<?php
// 短链接系统 - 前台
$cfg = require __DIR__ . '/config.php';

function db($cfg) {
    $dsn = "mysql:host={$cfg['host']};port={$cfg['port']};dbname={$cfg['dbname']};charset=utf8mb4";
    return new PDO($dsn, $cfg['user'], $cfg['pass'], [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]);
}

function genCode($pdo, $len = 6) {
    $alpha = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    do {
        $code = '';
        for ($i = 0; $i < $len; $i++) $code .= $alpha[random_int(0, strlen($alpha) - 1)];
    } while ($pdo->query("SELECT COUNT(*) c FROM short_link WHERE code=" . $pdo->quote($code))->fetch()['c'] > 0);
    return $code;
}

$pdo = null;
try { $pdo = db($cfg); } catch (Exception $e) { $dbError = '数据库连接失败，请检查 config.php 配置：' . $e->getMessage(); }

$shortened = null;
$error = null;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $url = trim($_POST['url'] ?? '');
    $alias = trim($_POST['alias'] ?? '');
    if ($url === '' || !preg_match('#^https?://#i', $url)) {
        $error = '请输入以 http(s):// 开头的链接';
    } else {
        try {
            $code = '';
            if ($alias !== '') {
                if (!preg_match('#^[a-zA-Z0-9]{3,16}$#', $alias)) {
                    $error = '别名需为 3-16 位字母数字';
                } else {
                    $exists = $pdo->query("SELECT COUNT(*) c FROM short_link WHERE code=" . $pdo->quote($alias))->fetch()['c'];
                    if ($exists > 0) $error = '该别名已被占用';
                    else $code = $alias;
                }
            } else {
                $code = genCode($pdo);
            }
            if ($error === null) {
                $st = $pdo->prepare("INSERT INTO short_link (code, url, alias) VALUES (?,?,?)");
                $st->execute([$code, $url, $alias === '' ? null : $alias]);
                $shortened = 'https://' . ($_SERVER['HTTP_HOST'] ?? 'dev.xjxbk.cn') . '/s/' . $code;
            }
        } catch (Exception $e) {
            $error = '生成失败：' . $e->getMessage();
        }
    }
}

$recent = [];
if ($pdo) {
    try {
        $recent = $pdo->query("SELECT code, url, clicks, DATE_FORMAT(created_at,'%m-%d %H:%i') t FROM short_link ORDER BY id DESC LIMIT 10")->fetchAll();
    } catch (Exception $e) {}
}

header('Content-Type: text/html; charset=utf-8');
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>URL 短链接系统</title>
<meta name="description" content="短链接生成与管理：自定义短码、点击统计、访问日志">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🔗</text></svg>">
<style>
:root{--bg:#070b14;--glass:rgba(255,255,255,.055);--glass2:rgba(255,255,255,.09);--border:rgba(255,255,255,.1);--pri:#22d3ee;--pri2:#6366f1;--text:#e6edf7;--dim:#9aa8bd;--faint:#64748b;--r:20px;--font:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif}
*{margin:0;padding:0;box-sizing:border-box}
body{background:radial-gradient(1000px 700px at 15% -10%,rgba(34,211,238,.16),transparent 60%),radial-gradient(900px 700px at 100% 0%,rgba(99,102,241,.18),transparent 55%),radial-gradient(800px 800px at 50% 120%,rgba(168,85,247,.12),transparent 60%),var(--bg);background-attachment:fixed;color:var(--text);font-family:var(--font);min-height:100vh;line-height:1.65;-webkit-font-smoothing:antialiased}
.wrap{max-width:760px;margin:0 auto;padding:40px 20px 60px}
header{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:10px;margin-bottom:32px}
.logo{font-size:20px;font-weight:800}
.logo span{background:linear-gradient(135deg,var(--pri),var(--pri2));-webkit-background-clip:text;background-clip:text;color:transparent}
.logo .sub{color:var(--faint);font-size:13px;font-weight:400;margin-left:8px}
a{color:var(--pri);text-decoration:none}
.card{background:var(--glass);border:1px solid var(--border);border-radius:var(--r);backdrop-filter:blur(22px);padding:32px;margin-bottom:20px}
h2{font-size:16px;margin-bottom:20px;font-weight:700}
h2 small{color:var(--faint);font-size:13px;font-weight:400;margin-left:8px}
.row{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:14px}
input{flex:1;min-width:220px;background:var(--glass);border:1px solid var(--border);color:var(--text);font-family:var(--font);font-size:15px;padding:14px 18px;border-radius:40px;outline:none;backdrop-filter:blur(22px);transition:border-color .2s}
input:focus{border-color:var(--pri)}
input::placeholder{color:var(--faint)}
.btn{background:linear-gradient(135deg,var(--pri),var(--pri2));color:#04121a;border:none;font-family:var(--font);font-size:15px;font-weight:700;padding:14px 28px;border-radius:40px;cursor:pointer;transition:filter .2s}
.btn:hover{filter:brightness(1.15)}
.result{background:var(--glass2);border:1px solid rgba(34,211,238,.4);border-radius:14px;padding:16px 20px;margin-top:4px;display:none;word-break:break-all}
.result.show{display:block}
.result .lbl{font-size:12px;color:var(--faint);margin-bottom:4px}
.result a{font-size:17px;font-weight:700}
.err{color:#f87171;font-size:13px;margin-bottom:10px;display:none}
.err.show{display:block}
ul.list{list-style:none;display:flex;flex-direction:column;gap:10px}
ul.list li{background:var(--glass);border:1px solid var(--border);border-radius:14px;padding:14px 18px;display:flex;justify-content:space-between;gap:12px;align-items:center;flex-wrap:wrap;font-size:14px}
ul.list .code{color:var(--pri);font-weight:700;flex-shrink:0}
ul.list .url{color:var(--faint);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:120px}
ul.list .clicks{color:var(--dim);font-size:12px;flex-shrink:0}
.hint{color:var(--faint);font-size:13px;margin-top:16px}
.hint a{color:var(--dim);font-weight:600}
footer{color:var(--faint);font-size:13px;margin-top:30px;padding-top:16px;border-top:1px solid var(--border);display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px}
footer a{color:var(--dim);font-weight:600}
</style>
</head>
<body>
<div class="wrap">
<header>
    <div class="logo">短链<span>.</span><span class="sub">dev.xjxbk.cn</span></div>
    <a href="admin.php">管理后台</a>
</header>

<div class="card">
    <h2>生成短链接<small>自定义别名 · 点击统计</small></h2>
    <div class="err" id="err"><?= htmlspecialchars($error ?? '') ?></div>
    <form method="post" id="form">
        <div class="row">
            <input type="url" name="url" placeholder="粘贴长链接，如 https://www.example.com/very/long/path" required>
        </div>
        <div class="row">
            <input type="text" name="alias" placeholder="自定义短码（可选，3-16位字母数字）" maxlength="16">
        </div>
        <button class="btn" type="submit">生成</button>
        <div class="result" id="result">
            <div class="lbl">短链接（点击复制）</div>
            <a href="#" id="resultLink" target="_blank" rel="noopener"></a>
        </div>
        <div class="hint">短链访问地址为 <b><?= htmlspecialchars(($_SERVER['HTTP_HOST'] ?? 'dev.xjxbk.cn') . '/s/') ?>短码</b>，点击自动跳转到原链接。</div>
    </form>
</div>

<div class="card">
    <h2>最近生成</h2>
    <?php if (empty($recent)): ?>
    <div class="hint">暂无记录</div>
    <?php else: ?>
    <ul class="list">
        <?php foreach ($recent as $r): ?>
        <li>
            <span class="code"><?= htmlspecialchars($r['code']) ?></span>
            <span class="url"><?= htmlspecialchars($r['url']) ?></span>
            <span class="clicks"><?= (int)$r['clicks'] ?> 次</span>
        </li>
        <?php endforeach; ?>
    </ul>
    <?php endif; ?>
</div>

<footer>
    <span>© <?= date('Y') ?> 别克 · 短链接系统</span>
    <span><a href="https://xjxbk.cn/projects">返回作品集</a></span>
</footer>
</div>
<script>
(function(){
    var form=document.getElementById('form');
    var err=document.getElementById('err');
    var result=document.getElementById('result');
    var link=document.getElementById('resultLink');
    form.addEventListener('submit',function(e){
        e.preventDefault();
        var fd=new FormData(form);
        fetch('index.php',{method:'POST',body:fd}).then(function(r){return r.text()}).then(function(html){
            // 简单判定：POST 返回整个页面时，若包含 resultLink 已填充则成功
            var temp=document.createElement('html');temp.innerHTML=html;
            var href=temp.querySelector('#resultLink');
            if(href&&href.getAttribute('href')&&href.getAttribute('href')!=='#'){
                err.classList.remove('show');
                link.setAttribute('href',href.getAttribute('href'));
                link.textContent=href.textContent;
                result.classList.add('show');
                // 刷新最近列表
                location.reload();
            }else{
                var msg=temp.querySelector('#err');
                err.textContent=msg?msg.textContent:'生成失败';
                err.classList.add('show');
                result.classList.remove('show');
            }
        });
    });
    link.addEventListener('click',function(){
        var t=link.textContent;
        if(navigator.clipboard)navigator.clipboard.writeText(t).then(function(){alert('已复制：'+t)});
    });
})();
</script>
</body>
</html>
