<?php
require dirname(__DIR__) . '/app/bootstrap.php';
$requestPath = rawurldecode((string)(parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/'));
if ($_SERVER['REQUEST_METHOD'] === 'GET' && preg_match('#^/([^/]+)/index\.html$#', $requestPath, $match)) {
    $requestedVersion = $match[1];
    $staticTarget = staticReleaseRoot() . '/' . staticReleaseSegment($requestedVersion) . '/index.html';
    if (is_file($staticTarget)) redirect(staticReleaseUrl($requestedVersion));
}
$hasAdmin = (bool)$db->query("SELECT COUNT(*) FROM users WHERE role = 'admin'")->fetchColumn();
$error = '';
$view = get('view');
$form = ['title'=>'', 'version'=>'', 'entry_date'=>date('Y-m-d'), 'type'=>'feature', 'status'=>'released', 'milestone_id'=>'', 'content'=>''];
$milestoneForm = ['name'=>'', 'target_version'=>'', 'description'=>'', 'target_date'=>date('Y-m-d'), 'status'=>'active'];
$editId = max(0, (int)get('edit'));
$milestoneEditId = max(0, (int)get('milestone_edit'));
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!hash_equals($_SESSION['csrf'], input('csrf'))) { http_response_code(403); exit('请求已失效，请刷新页面后重试。'); }
    $action = input('action');
    if ($action === 'setup' && !$hasAdmin) {
        $username = input('username'); $password = input('password');
        if (!preg_match('/^[a-zA-Z0-9_]{3,32}$/', $username) || !validPassword($password)) {
            $error = '用户名需为 3–32 位字母、数字或下划线；密码需为 6–72 位数字或字母。'; $view = 'setup';
        } else {
            $s = $db->prepare("INSERT OR IGNORE INTO users (username, password, role, created_at) VALUES (?, ?, 'admin', ?)");
            $s->execute([$username, password_hash($password, PASSWORD_DEFAULT), date('c')]);
            if ($s->rowCount() === 1) { session_regenerate_id(true); $_SESSION['user_id'] = (int)$db->lastInsertId(); $_SESSION['username'] = $username; $_SESSION['role'] = 'admin'; flash('管理员已创建，开始记录第一次更新吧。'); redirect('/?view=new'); }
            redirect('/?view=login');
        }
    } elseif ($action === 'login') {
        $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
        $db->prepare('DELETE FROM login_attempts WHERE attempted_at < ?')->execute([time()-900]);
        $s = $db->prepare('SELECT COUNT(*) FROM login_attempts WHERE ip = ?'); $s->execute([$ip]);
        if ((int)$s->fetchColumn() >= 10) { $error = '尝试次数过多，请 15 分钟后重试。'; http_response_code(429); }
        else {
            $s = $db->prepare('SELECT * FROM users WHERE username = ? COLLATE NOCASE'); $s->execute([input('username')]); $user = $s->fetch();
            if ($user && password_verify(input('password'), $user['password'])) {
                session_regenerate_id(true); $_SESSION['user_id'] = (int)$user['id']; $_SESSION['username'] = $user['username']; $_SESSION['role'] = $user['role'];
                $db->prepare('DELETE FROM login_attempts WHERE ip = ?')->execute([$ip]); flash('登录成功，欢迎回来。'); redirect();
            }
            $db->prepare('INSERT INTO login_attempts VALUES (?, ?)')->execute([$ip, time()]); $error = '用户名或密码不正确。';
        }
        $view = 'login';
    } else {
        if (!loggedIn()) { http_response_code(403); exit('请先登录管理员账号。'); }
        if ($action === 'logout') { $_SESSION = []; session_regenerate_id(true); redirect(); }
        if ($action === 'change_password') {
            $currentPassword=input('current_password'); $newPassword=input('new_password'); $confirmPassword=input('confirm_password');
            $s=$db->prepare('SELECT password FROM users WHERE id=?'); $s->execute([(int)$_SESSION['user_id']]); $currentHash=$s->fetchColumn();
            if (!$currentHash || !password_verify($currentPassword,(string)$currentHash)) $error='当前密码不正确。';
            elseif (!validPassword($newPassword)) $error='新密码需为 6–72 位数字或字母。';
            elseif ($newPassword !== $confirmPassword) $error='两次输入的新密码不一致。';
            elseif ($newPassword === $currentPassword) $error='新密码不能与当前密码相同。';
            else {
                $db->prepare('UPDATE users SET password=? WHERE id=?')->execute([password_hash($newPassword,PASSWORD_DEFAULT),(int)$_SESSION['user_id']]);
                session_regenerate_id(true); flash('个人密码已修改。');
                redirect(in_array($view,['logs','milestones','users'],true)?'/?view='.$view:'/');
            }
        }
        if ($action === 'save') {
            if (!canEdit()) { http_response_code(403); exit('当前账号没有编辑权限。'); }
            $editId = max(0, (int)input('id'));
            foreach ($form as $key => $value) $form[$key] = input($key);
            $milestoneId = max(0, (int)$form['milestone_id']);
            $s = $db->prepare('SELECT COUNT(*) FROM milestones WHERE id=?'); $s->execute([$milestoneId]); $milestoneExists = (bool)$s->fetchColumn();
            if ($form['title'] === '' || mb_strlen($form['title']) > 120 || $form['version'] === '' || mb_strlen($form['version']) > 40 || $form['content'] === '' || mb_strlen($form['content']) > 10000 || !validDate($form['entry_date']) || !isset(TYPES[$form['type']]) || !isset(STATUSES[$form['status']]) || !$milestoneExists) {
                $error = '请完整填写标题、版本、里程碑和内容，并检查日期与字段长度。'; $view = 'new';
            } else {
                $now = date('c');
                $values = [$form['title'],$form['version'],$form['entry_date'],$form['type'],$form['status'],$milestoneId,$form['content']];
                $previousVersion = null;
                if ($editId) {
                    $s = $db->prepare('SELECT version FROM entries WHERE id=?'); $s->execute([$editId]); $previousVersion = $s->fetchColumn();
                    if ($previousVersion === false) { http_response_code(404); exit('该更新记录不存在。'); }
                    $s = $db->prepare('UPDATE entries SET title=?, version=?, entry_date=?, type=?, status=?, milestone_id=?, milestone=1, content=?, updated_at=? WHERE id=?'); $s->execute([...$values, $now, $editId]);
                } else { $db->prepare('INSERT INTO entries (title,version,entry_date,type,status,milestone_id,milestone,content,created_at,updated_at) VALUES (?,?,?,?,?,?,1,?,?,?)')->execute([...$values, $now, $now]); }
                if ($previousVersion !== null && $previousVersion !== $form['version']) rebuildStaticRelease($db, $previousVersion);
                rebuildStaticRelease($db, $form['version']);
                rebuildStaticAll($db);
                rebuildStaticLatest($db);
                flash(($editId ? '更新记录已保存' : '新的更新记录已添加') . '，公开静态页已生成。'); redirect('/?date=' . $form['entry_date']);
            }
        } elseif ($action === 'delete') {
            if (!canEdit()) { http_response_code(403); exit('当前账号没有编辑权限。'); }
            $id = (int)input('id'); $s = $db->prepare('SELECT version FROM entries WHERE id=?'); $s->execute([$id]); $deletedVersion = $s->fetchColumn();
            $db->prepare('DELETE FROM entries WHERE id=?')->execute([$id]);
            if ($deletedVersion !== false) rebuildStaticRelease($db, (string)$deletedVersion);
            rebuildStaticAll($db);
            rebuildStaticLatest($db);
            flash('更新记录已删除，公开静态页已同步。'); redirect();
        } elseif ($action === 'create_user') {
            if (!isAdmin()) { http_response_code(403); exit('只有管理员可以管理账号。'); }
            $username = input('username'); $password = input('password'); $role = input('role');
            if (!preg_match('/^[a-zA-Z0-9_]{3,32}$/', $username) || !validPassword($password) || !in_array($role, ['editor', 'viewer'], true)) {
                $error = '用户名需为 3–32 位字母、数字或下划线；密码需为 6–72 位数字或字母。'; $view = 'users';
            } else {
                try {
                    $s = $db->prepare('INSERT INTO users (username,password,role,created_at) VALUES (?,?,?,?)');
                    $s->execute([$username, password_hash($password, PASSWORD_DEFAULT), $role, date('c')]); flash('账号已创建。'); redirect('/?view=users');
                } catch (PDOException $exception) {
                    if ((string)$exception->getCode() !== '23000') throw $exception;
                    $error = '该用户名已经存在。'; $view = 'users';
                }
            }
        } elseif ($action === 'delete_user') {
            if (!isAdmin()) { http_response_code(403); exit('只有管理员可以管理账号。'); }
            $id = max(0, (int)input('id'));
            if ($id === (int)$_SESSION['user_id']) { $error = '不能删除当前登录的管理员账号。'; $view = 'users'; }
            else { $db->prepare("DELETE FROM users WHERE id=? AND role <> 'admin'")->execute([$id]); flash('账号已删除。'); redirect('/?view=users'); }
        } elseif ($action === 'update_user') {
            if (!isAdmin()) { http_response_code(403); exit('只有管理员可以管理账号。'); }
            $id = max(0, (int)input('id')); $role = input('role'); $password=input('password');
            $s=$db->prepare('SELECT username,role FROM users WHERE id=?'); $s->execute([$id]); $target=$s->fetch();
            if (!$target) { http_response_code(404); exit('该账号不存在。'); }
            if (($target['role'] !== 'admin' && !in_array($role, ['editor','viewer'], true)) || ($password !== '' && !validPassword($password))) {
                $error='请选择有效权限；新密码需为 6–72 位数字或字母。'; $view='users';
            } elseif ($target['role'] === 'admin' && $password === '') {
                $error='管理员权限固定；如需修改，请填写新密码。'; $view='users';
            } else {
                $nextRole=$target['role']==='admin'?'admin':$role;
                if ($password !== '') $db->prepare('UPDATE users SET role=?,password=? WHERE id=?')->execute([$nextRole,password_hash($password,PASSWORD_DEFAULT),$id]);
                else $db->prepare('UPDATE users SET role=? WHERE id=?')->execute([$nextRole,$id]);
                flash('账号权限与密码设置已更新。'); redirect('/?view=users');
            }
        } elseif ($action === 'save_milestone') {
            if (!canEdit()) { http_response_code(403); exit('当前账号没有编辑权限。'); }
            $milestoneEditId = max(0, (int)input('id'));
            foreach ($milestoneForm as $key => $value) $milestoneForm[$key] = input($key);
            if ($milestoneForm['name']==='' || mb_strlen($milestoneForm['name'])>100 || $milestoneForm['target_version']==='' || mb_strlen($milestoneForm['target_version'])>40 || mb_strlen($milestoneForm['description'])>2000 || !validDate($milestoneForm['target_date']) || !isset(MILESTONE_STATUSES[$milestoneForm['status']])) {
                $error = '请完整填写里程碑名称、目标版本和日期。'; $view = 'milestone_form';
            } else {
                $values = array_values($milestoneForm); $now = date('c');
                if ($milestoneEditId) {
                    $s=$db->prepare('UPDATE milestones SET name=?,target_version=?,description=?,target_date=?,status=?,updated_at=? WHERE id=?'); $s->execute([...$values,$now,$milestoneEditId]);
                    if (!$s->rowCount()) { http_response_code(404); exit('该里程碑不存在。'); }
                } else { $db->prepare('INSERT INTO milestones (name,target_version,description,target_date,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?)')->execute([...$values,$now,$now]); }
                flash($milestoneEditId ? '里程碑已保存。' : '里程碑已创建，现在可以关联更新内容。'); redirect('/?view=milestones');
            }
        } elseif ($action === 'delete_milestone') {
            if (!canEdit()) { http_response_code(403); exit('当前账号没有编辑权限。'); }
            $id=max(0,(int)input('id')); $s=$db->prepare('SELECT COUNT(*) FROM entries WHERE milestone_id=?'); $s->execute([$id]);
            if ((int)$s->fetchColumn()>0) { $error='该里程碑已有更新内容，不能删除。'; $view='milestones'; }
            else { $db->prepare('DELETE FROM milestones WHERE id=?')->execute([$id]); flash('里程碑已删除。'); redirect('/?view=milestones'); }
        }
    }
}
if (($view === 'new' || $editId || $view === 'milestone_form' || $milestoneEditId) && !canEdit()) redirect(loggedIn() ? '/' : '/?view=login');
if ($view === 'users' && !isAdmin()) redirect(loggedIn() ? '/' : '/?view=login');
if ($view === 'setup' && $hasAdmin) redirect('/?view=login');
if ($editId && $_SERVER['REQUEST_METHOD'] !== 'POST') {
    $s = $db->prepare('SELECT * FROM entries WHERE id=?'); $s->execute([$editId]); $record = $s->fetch();
    if (!$record) { http_response_code(404); exit('该更新记录不存在。'); } $form = $record; $view = 'new';
}
if ($milestoneEditId && $_SERVER['REQUEST_METHOD'] !== 'POST') {
    $s=$db->prepare('SELECT * FROM milestones WHERE id=?'); $s->execute([$milestoneEditId]); $record=$s->fetch();
    if (!$record) { http_response_code(404); exit('该里程碑不存在。'); } $milestoneForm=$record; $view='milestone_form';
}
$date = get('date'); if (!validDate($date)) $date = '';
$period = get('period', $view === 'logs' ? '7' : 'all');
if (!in_array($period, ['7','30','90','all'], true)) $period = '7';
$periodLabels = ['7'=>'近 7 天','30'=>'近 30 天','90'=>'近 90 天','all'=>'全部日期'];
$type = get('type'); if (!isset(TYPES[$type])) $type = '';
$status = get('status'); if (!isset(STATUSES[$status])) $status = '';
$q = mb_substr(get('q'), 0, 200); $milestoneId = max(0,(int)get('milestone_id'));
$isOverview = $view === '' && !$date && $q === '' && !$type && !$status && !$milestoneId;
$where = []; $params = [];
if ($date) { $where[] = 'entry_date = ?'; $params[] = $date; }
elseif ($view === 'logs' && $period !== 'all') {
    $where[] = 'entry_date BETWEEN ? AND ?';
    $params[] = (new DateTimeImmutable('today'))->modify('-'.((int)$period-1).' days')->format('Y-m-d');
    $params[] = date('Y-m-d');
}
if ($q !== '') { $where[] = "(title LIKE ? ESCAPE '\' OR content LIKE ? ESCAPE '\' OR version LIKE ? ESCAPE '\')"; $pattern = '%'.str_replace(['\\','%','_'], ['\\\\','\\%','\\_'], $q).'%'; array_push($params, $pattern, $pattern, $pattern); }
if ($type) { $where[]='type=?'; $params[]=$type; }
if ($status) { $where[]='status=?'; $params[]=$status; }
if ($milestoneId) { $where[] = 'milestone_id=?'; $params[]=$milestoneId; }
$sqlWhere = $where ? ' WHERE '.implode(' AND ', $where) : '';
$s=$db->prepare('SELECT COUNT(*) FROM entries'.$sqlWhere); $s->execute($params); $total=(int)$s->fetchColumn();
$pageSize=$isOverview?5:20; $pages=$isOverview?1:max(1,(int)ceil($total/$pageSize)); $page=min($pages,max(1,(int)get('page','1')));
$s=$db->prepare('SELECT entries.*, (SELECT name FROM milestones WHERE id=entries.milestone_id) milestone_name FROM entries'.$sqlWhere.' ORDER BY entry_date DESC, id DESC LIMIT '.$pageSize.' OFFSET '.(($page-1)*$pageSize)); $s->execute($params); $entries=$s->fetchAll();
$stats=$db->query("SELECT COUNT(*) total, COUNT(DISTINCT version) versions, 0 milestones, COALESCE(SUM(substr(entry_date,1,7)='".date('Y-m')."'),0) monthly FROM entries")->fetch();
$stats['milestones']=(int)$db->query('SELECT COUNT(*) FROM milestones')->fetchColumn();
$flash=$_SESSION['flash']??''; unset($_SESSION['flash']);
$userQ=mb_substr(get('user_q'),0,100); $users=[]; $userTotal=0;
if ($view === 'users' && isAdmin()) {
    $userTotal=(int)$db->query('SELECT COUNT(*) FROM users')->fetchColumn();
    if ($userQ !== '') { $s=$db->prepare("SELECT id,username,role,created_at FROM users WHERE username LIKE ? ESCAPE '\\' ORDER BY role,id"); $s->execute(['%'.str_replace(['\\','%','_'],['\\\\','\\%','\\_'],$userQ).'%']); $users=$s->fetchAll(); }
    else $users=$db->query('SELECT id,username,role,created_at FROM users ORDER BY role,id')->fetchAll();
}
$milestones=$db->query('SELECT milestones.*, COUNT(entries.id) entry_count, COUNT(DISTINCT entries.version) version_count FROM milestones LEFT JOIN entries ON entries.milestone_id=milestones.id GROUP BY milestones.id ORDER BY target_date DESC,id DESC')->fetchAll();
$selectedMilestone=null;
if ($milestoneId) { $s=$db->prepare('SELECT * FROM milestones WHERE id=?'); $s->execute([$milestoneId]); $selectedMilestone=$s->fetch(); if(!$selectedMilestone){http_response_code(404);exit('该里程碑不存在。');} }
$viewEntry=null; $entryViewId=max(0,(int)get('entry'));
if ($view==='entry') {
    if (!$entryViewId) { http_response_code(404); exit('该更新记录不存在。'); }
    $s=$db->prepare('SELECT entries.*, milestones.name milestone_name FROM entries LEFT JOIN milestones ON milestones.id=entries.milestone_id WHERE entries.id=?');
    $s->execute([$entryViewId]); $viewEntry=$s->fetch();
    if(!$viewEntry){http_response_code(404);exit('该更新记录不存在。');}
}
?>
<!doctype html>
<html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>更新日志 · 迭代之间</title><link rel="stylesheet" href="/assets/style.css"><script src="/assets/app.js" defer></script></head>
<body>
<aside class="sidebar"><a class="brand" href="/"><span class="brand-icon"><?=icon('activity')?></span><span>迭代之间<small>CHANGELOG WORKSPACE</small></span></a><div class="workspace"><span class="workspace-icon">迭</span><div>产品更新空间<small>每一步进展，都值得记录</small></div><span class="online"></span></div><div class="nav-label">工作空间</div><nav><a class="<?=$isOverview?'active':''?>" href="/"><?=icon('grid')?>更新总览</a><a class="<?=($view==='logs'||$view==='entry'||$date||$q!==''||$type||$status)&&!$milestoneId?'active':''?>" href="/?view=logs"><?=icon('activity')?>更新日志<span><?=$stats['total']?></span></a><a class="<?=$view==='milestones'||$milestoneId?'active':''?>" href="/?view=milestones"><?=icon('flag')?>里程碑<span><?=$stats['milestones']?></span></a><a class="<?=$view==='help'?'active':''?>" href="/?view=help"><?=icon('help')?>帮助文档</a><?php if(isAdmin()):?><a class="<?=$view==='users'?'active':''?>" href="/?view=users"><?=icon('box')?>账号管理</a><?php endif;?></nav>
<div class="sidebar-bottom"><?php if(loggedIn()):?><button class="profile-trigger" type="button" data-modal-open="self-password" aria-label="修改个人密码"><span class="avatar"><?=e(mb_substr($_SESSION['username'],0,1))?></span><span><?=e($_SESSION['username'])?><small><?=roleLabel($_SESSION['role'])?> · 修改密码</small></span></button><form method="post"><input type="hidden" name="csrf" value="<?=e($_SESSION['csrf'])?>"><button class="logout" name="action" value="logout">退出</button></form><?php else:?><span class="avatar">访</span><div>访客模式<small>仅查看公开内容</small></div><a href="/?view=<?=$hasAdmin?'login':'setup'?>">登录 ↗</a><?php endif;?></div></aside>
<div class="main-shell"><header class="topbar"><div>工作空间 <span>/</span> <b>更新日志</b></div><div class="topbar-right"><span class="live-dot"></span> 持续迭代中 <span class="top-date"><?=date('Y年m月d日')?></span></div></header><main>
<?php if($flash):?><div class="notice" role="status"><?=icon('check')?><?=e($flash)?></div><?php endif;?>
<?php if($error):?><div class="notice error" role="alert"><?=e($error)?></div><?php endif;?>
<?php if(in_array($view,['login','setup'],true)):?>
<section class="auth-card"><span class="eyebrow">YOUR NEXT CHAPTER</span><h1><?=$view==='setup'?'创建你的更新空间':'欢迎回到迭代之间'?></h1><p><?=$view==='setup'?'设置管理员账号，开始记录产品的每一步成长。':'登录账号，按分配的权限使用更新日志。'?></p><form method="post" class="entry-form"><input type="hidden" name="csrf" value="<?=e($_SESSION['csrf'])?>"><input type="hidden" name="action" value="<?=$view==='setup'?'setup':'login'?>"><label>用户名<input name="username" required maxlength="32" autocomplete="username" value="<?=e(input('username'))?>" placeholder="输入用户名"></label><label>密码<input type="password" name="password" required <?=$view==='setup'?'minlength="6" pattern="[A-Za-z0-9]+"':''?> maxlength="72" autocomplete="<?=$view==='setup'?'new-password':'current-password'?>" placeholder="<?=$view==='setup'?'至少 6 位数字或字母':'输入密码'?>"></label><?php if($view==='setup'):?><small>用户名使用 3–32 位字母、数字或下划线；密码使用 6–72 位数字或字母，可为纯数字。</small><?php endif;?><button class="button primary" type="submit"><?=$view==='setup'?'创建空间':'登录工作空间'?> <?=icon('arrow')?></button></form><a class="back-link" href="/">← 返回更新日志</a></section>
<?php elseif($view==='entry'):?>
<div class="page-heading"><div><span class="eyebrow">UPDATE DETAIL</span><h1>更新详情</h1><p>查看这条更新的完整内容和关联信息。</p></div><div class="heading-actions"><a class="button" href="/?view=logs">返回更新日志</a><?php if(canEdit()):?><a class="button primary" href="/?edit=<?=$viewEntry['id']?>">编辑记录</a><?php endif;?></div></div>
<article class="entry-detail"><div class="entry-detail-meta"><time datetime="<?=e($viewEntry['entry_date'])?>"><?=e($viewEntry['entry_date'])?></time><a class="version" href="<?=e(staticReleaseUrl($viewEntry['version']))?>" target="_blank" rel="noopener"><?=icon('box')?><?=e($viewEntry['version'])?> · 公开页</a><span class="tag <?=$viewEntry['type']?>"><?=TYPES[$viewEntry['type']]?></span><span class="status <?=$viewEntry['status']?>"><i></i><?=STATUSES[$viewEntry['status']]?></span></div><h2><?=e($viewEntry['title'])?></h2><?php if($viewEntry['milestone_id']):?><a class="detail-milestone" href="/?milestone_id=<?=$viewEntry['milestone_id']?>"><?=icon('flag')?><?=e($viewEntry['milestone_name'])?></a><?php endif;?><ul class="detail-content"><?php foreach(preg_split('/\R/u',$viewEntry['content']) as $line): if(trim($line)==='') continue;?><li><?=e($line)?></li><?php endforeach;?></ul></article>
<?php elseif($view==='help'):?>
<div class="page-heading"><div><span class="eyebrow">HELP CENTER</span><h1>帮助文档</h1><p><span class="sync-dot"></span>在线文档 · 内容自动同步</p></div></div>
<section class="help-document live-doc"><iframe src="https://docs.google.com/document/d/1hsuMuYZucCBbo-EE14tzr8bro-85JG-UlG3hl9WlkK4/edit?usp=sharing&amp;embedded=true" title="后台文档使用说明" referrerpolicy="strict-origin-when-cross-origin"></iframe><div class="help-fallback">无法显示在线文档时，可<a href="https://docs.google.com/document/d/1hsuMuYZucCBbo-EE14tzr8bro-85JG-UlG3hl9WlkK4/edit?usp=sharing" target="_blank" rel="noopener">在 Google Docs 中打开</a>。</div></section>
<?php elseif($view==='milestones'):?>
<div class="page-heading"><div><span class="eyebrow">MILESTONE JOURNEY</span><h1>里程碑</h1><p>从阶段目标进入，查看每个里程碑关联的版本和更新内容。</p></div><?php if(canEdit()):?><a class="button primary" href="/?view=milestone_form"><?=icon('plus')?>建立里程碑</a><?php endif;?></div>
<?php if(!$milestones):?><div class="empty-state"><div class="empty-icon"><?=icon('flag')?></div><h3>建立第一个里程碑</h3><p>为阶段目标设定名称、目标版本和日期，再把每日更新关联进来。</p><?php if(canEdit()):?><a class="button primary" href="/?view=milestone_form">＋ 建立里程碑</a><?php endif;?></div><?php else:?><section class="milestone-grid"><?php foreach($milestones as $item):?><article class="milestone-card"><div class="milestone-card-top"><span class="tag <?=$item['status']==='completed'?'feature':'improvement'?>"><?=MILESTONE_STATUSES[$item['status']]?></span><span class="milestone-date"><?=e($item['target_date'])?></span></div><h2><?=e($item['name'])?></h2><div class="milestone-version"><?=icon('box')?>目标版本 <?=e($item['target_version'])?></div><p><?=e($item['description'] ?: '尚未填写里程碑说明。')?></p><div class="milestone-count"><strong><?=$item['entry_count']?></strong> 条更新 · <strong><?=$item['version_count']?></strong> 个关联版本</div><div class="milestone-actions"><a class="button primary" href="/?milestone_id=<?=$item['id']?>">查看更新 <?=icon('arrow')?></a><?php if(canEdit()):?><a class="button" href="/?milestone_edit=<?=$item['id']?>">编辑</a><?php if((int)$item['entry_count']===0):?><form method="post" data-confirm="确定删除这个空里程碑吗？"><input type="hidden" name="csrf" value="<?=e($_SESSION['csrf'])?>"><input type="hidden" name="id" value="<?=$item['id']?>"><button class="danger-link" name="action" value="delete_milestone">删除</button></form><?php endif;?><?php endif;?></div></article><?php endforeach;?></section><?php endif;?>
<?php elseif($view==='milestone_form'):?>
<div class="page-heading"><div><span class="eyebrow">DEFINE THE NEXT STEP</span><h1><?=$milestoneEditId?'编辑里程碑':'建立里程碑'?></h1><p>设定阶段目标，后续更新内容将与它建立关联。</p></div><a class="button" href="/?view=milestones">返回里程碑</a></div><section class="editor-card"><form method="post" class="entry-form"><input type="hidden" name="csrf" value="<?=e($_SESSION['csrf'])?>"><input type="hidden" name="action" value="save_milestone"><input type="hidden" name="id" value="<?=$milestoneEditId?>"><label>里程碑名称 <span>*</span><input name="name" value="<?=e($milestoneForm['name'])?>" maxlength="100" required placeholder="例如：移动端 2.0 正式发布"></label><div class="form-grid"><label>目标版本 <span>*</span><input name="target_version" value="<?=e($milestoneForm['target_version'])?>" maxlength="40" required placeholder="例如：v2.0.0"></label><label>目标日期 <span>*</span><input type="date" name="target_date" value="<?=e($milestoneForm['target_date'])?>" min="1900-01-01" max="2100-12-31" required></label></div><label>状态<select name="status"><?php foreach(MILESTONE_STATUSES as $key=>$label):?><option value="<?=$key?>" <?=$milestoneForm['status']===$key?'selected':''?>><?=$label?></option><?php endforeach;?></select></label><label>里程碑说明<textarea name="description" rows="6" maxlength="2000" placeholder="说明这个阶段要完成的目标和价值。"><?=e($milestoneForm['description'])?></textarea></label><div class="form-actions"><a class="button" href="/?view=milestones">取消</a><button class="button primary" type="submit"><?=icon('check')?>保存里程碑</button></div></form></section>
<?php elseif($view==='users'):?>
<div class="page-heading"><div><span class="eyebrow">ACCOUNT & ACCESS</span><h1>账号管理</h1><p>搜索账号、调整权限，并管理可访问更新日志的成员。</p></div><button class="button primary" type="button" data-modal-open="create-user"><?=icon('plus')?>新增账号</button></div>
<section class="user-list"><div class="user-toolbar"><form method="get" class="user-search"><input type="hidden" name="view" value="users"><label class="search-field"><?=icon('search')?><input type="search" name="user_q" value="<?=e($userQ)?>" placeholder="搜索账号名称…" aria-label="搜索账号"></label><button class="filter-button" type="submit">搜索</button><?php if($userQ!==''):?><a href="/?view=users">清除</a><?php endif;?></form><span>共 <?=$userTotal?> 个账号<?=$userQ!==''?' · 找到 '.count($users).' 个':''?></span></div><div class="user-table"><div class="user-table-head"><span>账号</span><span>权限</span><span>创建日期</span><span>操作</span></div><?php if(!$users):?><div class="user-empty">没有找到匹配的账号</div><?php endif;?><?php foreach($users as $user):?><article class="user-row"><div class="user-identity"><span class="avatar"><?=e(mb_substr($user['username'],0,1))?></span><div><strong><?=e($user['username'])?></strong><small><?=roleLabel($user['role'])?></small></div></div><span class="tag <?=$user['role']==='admin'?'milestone':($user['role']==='editor'?'feature':'improvement')?>"><?=roleLabel($user['role'])?></span><time datetime="<?=e(substr($user['created_at'],0,10))?>"><?=e(substr($user['created_at'],0,10))?></time><div class="user-actions"><button class="edit-user" type="button" data-edit-user data-user-id="<?=$user['id']?>" data-user-name="<?=e($user['username'])?>" data-user-role="<?=e($user['role'])?>">编辑</button><?php if($user['role']!=='admin'):?><form method="post" data-confirm="确定删除账号 <?=e($user['username'])?> 吗？"><input type="hidden" name="csrf" value="<?=e($_SESSION['csrf'])?>"><input type="hidden" name="id" value="<?=$user['id']?>"><button class="danger-link" name="action" value="delete_user">删除</button></form><?php endif;?></div></article><?php endforeach;?></div></section>
<div class="modal" id="create-user" hidden role="dialog" aria-modal="true" aria-labelledby="create-user-title" <?=$error&&input('action')==='create_user'?'data-open="true"':''?>><button class="modal-backdrop" type="button" data-modal-close aria-label="关闭"></button><section class="modal-card"><div class="modal-heading"><div><span class="eyebrow">NEW ACCOUNT</span><h2 id="create-user-title">新增账号</h2></div><button class="modal-close" type="button" data-modal-close aria-label="关闭">×</button></div><form method="post" class="entry-form account-form"><input type="hidden" name="csrf" value="<?=e($_SESSION['csrf'])?>"><input type="hidden" name="action" value="create_user"><label>用户名 <span>*</span><input name="username" required minlength="3" maxlength="32" pattern="[A-Za-z0-9_]+" autocomplete="off" value="<?=e(input('username'))?>" placeholder="3–32 位字母、数字或下划线"></label><label>初始密码 <span>*</span><input type="password" name="password" required minlength="6" maxlength="72" pattern="[A-Za-z0-9]+" autocomplete="new-password" placeholder="6–72 位数字或字母"></label><label>账号权限<select name="role"><option value="editor" <?=input('role')==='editor'?'selected':''?>>编辑账号：可查看并维护更新日志</option><option value="viewer" <?=input('role')==='viewer'?'selected':''?>>查看账号：只能查看更新日志</option></select></label><small>密码可以是纯数字，也可以是数字与字母组合，不支持空格和符号。</small><div class="form-actions"><button class="button" type="button" data-modal-close>取消</button><button class="button primary" type="submit"><?=icon('plus')?>创建账号</button></div></form></section></div>
<div class="modal" id="edit-user" hidden role="dialog" aria-modal="true" aria-labelledby="edit-user-title" <?=$error&&input('action')==='update_user'?'data-open="true"':''?>><button class="modal-backdrop" type="button" data-modal-close aria-label="关闭"></button><section class="modal-card"><div class="modal-heading"><div><span class="eyebrow">EDIT ACCOUNT</span><h2 id="edit-user-title">修改账号</h2><p id="edit-user-name"><?=e(input('account_name'))?></p></div><button class="modal-close" type="button" data-modal-close aria-label="关闭">×</button></div><form method="post" class="entry-form account-form"><input type="hidden" name="csrf" value="<?=e($_SESSION['csrf'])?>"><input type="hidden" name="action" value="update_user"><input type="hidden" name="id" value="<?=e(input('id'))?>"><input type="hidden" name="account_name" value="<?=e(input('account_name'))?>"><label>账号权限<select name="role"><option value="admin" <?=input('role')==='admin'?'selected':''?>>管理员（权限固定）</option><option value="editor" <?=input('role')==='editor'?'selected':''?>>编辑账号：可查看并维护更新日志</option><option value="viewer" <?=input('role')==='viewer'?'selected':''?>>查看账号：只能查看更新日志</option></select></label><label>设置新密码<input type="password" name="password" minlength="6" maxlength="72" pattern="[A-Za-z0-9]+" autocomplete="new-password" placeholder="不修改密码请留空"></label><small>新密码使用 6–72 位数字或字母。管理员账号只能修改密码，权限不可调整。</small><div class="form-actions"><button class="button" type="button" data-modal-close>取消</button><button class="button primary" type="submit"><?=icon('check')?>保存修改</button></div></form></section></div>
<?php elseif($view==='new'):?>
<div class="page-heading"><div><span class="eyebrow">DOCUMENT THE PROGRESS</span><h1><?=$editId?'编辑更新记录':'记录一次新的进展'?></h1><p>用清晰的记录，让每一天的努力被看见。</p></div><a class="button" href="/">返回总览</a></div>
<section class="editor-card"><?php if(!$milestones):?><div class="notice">请先建立里程碑，再记录更新内容。</div><a class="button primary" href="/?view=milestone_form"><?=icon('plus')?>建立里程碑</a><?php else:?><form method="post" class="entry-form"><input type="hidden" name="csrf" value="<?=e($_SESSION['csrf'])?>"><input type="hidden" name="action" value="save"><input type="hidden" name="id" value="<?=$editId?>"><label>更新标题 <span>*</span><input name="title" value="<?=e($form['title'])?>" maxlength="120" required placeholder="例如：全新工作台上线，让协作更简单"></label><div class="form-grid"><label>关联里程碑 <span>*</span><select name="milestone_id" required><option value="">请选择里程碑</option><?php foreach($milestones as $item):?><option value="<?=$item['id']?>" <?=(string)$form['milestone_id']===(string)$item['id']?'selected':''?>><?=e($item['name'])?> · <?=e($item['target_version'])?></option><?php endforeach;?></select></label><label>本次更新版本号 <span>*</span><input name="version" value="<?=e($form['version'])?>" maxlength="40" required placeholder="例如：v1.2.0"></label><label>更新日期 <span>*</span><input type="date" name="entry_date" value="<?=e($form['entry_date'])?>" min="1900-01-01" max="2100-12-31" required></label><label>更新类型<select name="type"><?php foreach(TYPES as $key=>$label):?><option value="<?=$key?>" <?=$form['type']===$key?'selected':''?>><?=$label?></option><?php endforeach;?></select></label><label>发布状态<select name="status"><?php foreach(STATUSES as $key=>$label):?><option value="<?=$key?>" <?=$form['status']===$key?'selected':''?>><?=$label?></option><?php endforeach;?></select></label></div><label>更新内容 <span>*</span><textarea name="content" rows="9" required maxlength="10000" placeholder="记录本次更新的具体内容，每行一项。&#10;例如：&#10;新增按日期筛选，快速回溯每天的更新&#10;优化移动端阅读体验"><?=e($form['content'])?></textarea><small>每条更新必须关联一个里程碑和版本号；正文每行显示为一项。</small></label><div class="form-actions"><a class="button" href="/">取消</a><button class="button primary" type="submit"><?=icon('check')?><?=$editId?'保存修改':'保存更新'?></button></div></form><?php endif;?></section>
<?php else:?>
<div class="page-heading"><div><span class="eyebrow">EVERY UPDATE, A STEP FORWARD</span><h1><?=$selectedMilestone?e($selectedMilestone['name']):($view==='logs'||$date?'更新日志':'每一次更新，都在向前。')?></h1><p><?=$selectedMilestone?'目标版本 '.e($selectedMilestone['target_version']).' · '.e(MILESTONE_STATUSES[$selectedMilestone['status']]).' · 查看该里程碑的全部更新。':($view==='logs'||$date?'按日期和版本查看完整更新记录，快速定位每一次变化。':'追踪版本演进，记录每日进展，让成长清晰可见。')?></p></div><div class="heading-actions"><a class="button" href="<?=e(staticLatestUrl())?>" target="_blank" rel="noopener">当前最新版本 ↗</a><a class="button" href="<?=e(staticAllUrl())?>" target="_blank" rel="noopener">公开全部版本 ↗</a><?php if($selectedMilestone):?><a class="button" href="/?view=milestones">返回里程碑</a><?php endif;?><?php if(canEdit()):?><a class="button primary" href="/?view=new"><?=icon('plus')?>记录更新</a><?php elseif(!loggedIn()):?><a class="button primary" href="/?view=<?=$hasAdmin?'login':'setup'?>">登录账号</a><?php endif;?></div></div>
<?php if($isOverview):?><section class="stats-grid" aria-label="更新统计"><?php foreach([['total','更新记录','box','所有值得记录的进展','/?view=logs'],['versions','迭代版本','activity','见证产品的持续演进','/?view=logs'],['milestones','重要里程碑','flag','每一个关键的突破','/?view=milestones'],['monthly','本月更新','calendar',date('Y 年 n 月').'的成长足迹','/?view=logs']] as [$key,$label,$symbol,$desc,$href]):?><a class="stat-card" href="<?=$href?>"><div class="stat-label"><?=$label?><span class="stat-icon <?=$key?>"><?=icon($symbol)?></span></div><div class="stat-value"><?=$stats[$key]?><span><?=in_array($key,['versions','milestones'],true)?'个':'条'?></span></div><small><?=$desc?></small></a><?php endforeach;?></section><?php endif;?>
<div class="content-grid"><section class="feed"><div class="section-heading"><h2><?=$date?e($date).' 的更新':($selectedMilestone?'里程碑更新':($isOverview?'最近更新':'更新日志'))?><span><?=$total?></span></h2><?php if($isOverview):?><a class="section-link" href="/?view=logs">查看全部更新日志 →</a><?php else:?><span class="muted">按更新日期倒序</span><?php endif;?></div><?php if(!$isOverview):?><form class="filters" method="get"><input type="hidden" name="view" value="logs"><label class="search-field"><?=icon('search')?><input type="search" name="q" value="<?=e($q)?>" placeholder="搜索更新内容、版本号…" aria-label="搜索更新"></label><select class="period-filter" name="period" aria-label="日期范围"><?php foreach($periodLabels as $key=>$label):?><option value="<?=$key?>" <?=$period===(string)$key?'selected':''?>><?=$label?></option><?php endforeach;?></select><select class="milestone-filter" name="milestone_id" aria-label="里程碑"><option value="">全部里程碑</option><?php foreach($milestones as $item):?><option value="<?=$item['id']?>" <?=$milestoneId===(int)$item['id']?'selected':''?>><?=e($item['name'])?></option><?php endforeach;?></select><select name="type" aria-label="更新类型"><option value="">全部类型</option><?php foreach(TYPES as $key=>$label):?><option value="<?=$key?>" <?=$type===$key?'selected':''?>><?=$label?></option><?php endforeach;?></select><select name="status" aria-label="发布状态"><option value="">全部状态</option><?php foreach(STATUSES as $key=>$label):?><option value="<?=$key?>" <?=$status===$key?'selected':''?>><?=$label?></option><?php endforeach;?></select><button class="filter-button" type="submit">筛选</button></form><?php endif;?>
<?php if($where):?><div class="filter-summary"><span>当前筛选：<?=e(implode(' · ',array_filter([$date,$view==='logs'&&!$date?$periodLabels[$period]:'',$q?'“'.$q.'”':'',TYPES[$type]??'',STATUSES[$status]??'',$selectedMilestone?$selectedMilestone['name'].' 里程碑':''])))?></span><a href="<?=$view==='logs'?'/?view=logs':($selectedMilestone?'/?view=milestones':'/?view=logs')?>">清除筛选 ×</a></div><?php endif;?>
<?php if(!$entries):?><div class="empty-state"><div class="empty-icon"><?=icon($where?'search':'calendar')?></div><h3><?=$where?'还没有匹配的更新':'故事，从第一次更新开始'?></h3><p><?=$where?'试试其他关键词或日期，发现更多产品进展。':'记录新功能、小优化和重要里程碑，建立你的产品时间线。'?></p><?php if($where):?><a class="button" href="/?view=logs">查看全部更新</a><?php elseif(canEdit()):?><a class="button primary" href="/?view=new">＋ 记录第一条更新</a><?php endif;?></div>
<?php elseif($view==='logs'):?><div class="log-list"><div class="log-list-head"><span>日期 / 版本</span><span>更新内容</span><span>状态</span><span>操作</span></div><?php foreach($entries as $entry):?><article class="log-row"><div class="log-identity"><time datetime="<?=e($entry['entry_date'])?>"><?=e($entry['entry_date'])?></time><a class="release-version" href="<?=e(staticReleaseUrl($entry['version']))?>"><?=icon('box')?><?=e($entry['version'])?></a></div><div class="log-main"><div class="log-tags"><span class="tag <?=$entry['type']?>"><?=TYPES[$entry['type']]?></span><?php if($entry['milestone_id']):?><a class="tag milestone" href="/?view=logs&amp;period=all&amp;milestone_id=<?=$entry['milestone_id']?>"><?=icon('flag')?><?=e($entry['milestone_name'])?></a><?php endif;?></div><h3><?=e($entry['title'])?></h3><p><?=e($entry['content'])?></p></div><span class="status <?=$entry['status']?>"><i></i><?=STATUSES[$entry['status']]?></span><div class="log-actions"><a href="/?view=entry&amp;entry=<?=$entry['id']?>">查看</a><?php if(canEdit()):?><a href="/?edit=<?=$entry['id']?>">编辑</a><form method="post" data-confirm="确定删除这条更新记录吗？删除后无法恢复。"><input type="hidden" name="csrf" value="<?=e($_SESSION['csrf'])?>"><input type="hidden" name="id" value="<?=$entry['id']?>"><button name="action" value="delete">删除</button></form><?php endif;?></div></article><?php endforeach;?></div>
<?php else:?><div class="timeline"><?php $lastDate=''; foreach($entries as $entry): $d=new DateTimeImmutable($entry['entry_date']); if($lastDate!==$entry['entry_date']): $lastDate=$entry['entry_date'];?><div class="timeline-date"><span class="timeline-dot"></span><strong><?=$d->format('m月d日')?></strong><span><?=$d->format('Y')?> · 星期<?=['日','一','二','三','四','五','六'][(int)$d->format('w')]?></span><?php if($entry['entry_date']===date('Y-m-d')):?><b class="today-tag">今天</b><?php endif;?></div><?php endif;?><article class="update-card <?=$entry['milestone_id']?'is-milestone':''?>"><div class="card-meta"><a class="version" href="<?=e(staticReleaseUrl($entry['version']))?>"><?=icon('box')?><?=e($entry['version'])?></a><span class="tag <?=$entry['type']?>"><?=TYPES[$entry['type']]?></span><?php if($entry['milestone_id']):?><a class="tag milestone" href="/?milestone_id=<?=$entry['milestone_id']?>"><?=icon('flag')?><?=e($entry['milestone_name'])?></a><?php endif;?><span class="status <?=$entry['status']?>"><i></i><?=STATUSES[$entry['status']]?></span></div><h3><?=e($entry['title'])?></h3><ul class="update-content"><?php foreach(preg_split('/\R/u',$entry['content']) as $line): if(trim($line)==='') continue;?><li><?=e($line)?></li><?php endforeach;?></ul><?php if(canEdit()):?><div class="card-actions"><a href="/?edit=<?=$entry['id']?>">编辑记录</a><form method="post" data-confirm="确定删除这条更新记录吗？删除后无法恢复。"><input type="hidden" name="csrf" value="<?=e($_SESSION['csrf'])?>"><input type="hidden" name="id" value="<?=$entry['id']?>"><button name="action" value="delete">删除</button></form></div><?php endif;?></article><?php endforeach;?></div><?php endif;?>
<?php if($pages>1):?><div class="pagination"><?php if($page>1):?><a class="button" href="<?=e(query(['page'=>$page-1]))?>">← 上一页</a><?php endif;?><span>第 <?=$page?> / <?=$pages?> 页</span><?php if($page<$pages):?><a class="button" href="<?=e(query(['page'=>$page+1]))?>">下一页 →</a><?php endif;?></div><?php endif;?></section>
</div>
<?php endif;?>
<?php if(loggedIn()):?><div class="modal" id="self-password" hidden role="dialog" aria-modal="true" aria-labelledby="self-password-title" <?=$error&&input('action')==='change_password'?'data-open="true"':''?>><button class="modal-backdrop" type="button" data-modal-close aria-label="关闭"></button><section class="modal-card"><div class="modal-heading"><div><span class="eyebrow">ACCOUNT SECURITY</span><h2 id="self-password-title">修改个人密码</h2><p><?=e($_SESSION['username'])?> · <?=roleLabel($_SESSION['role'])?></p></div><button class="modal-close" type="button" data-modal-close aria-label="关闭">×</button></div><?php if($error&&input('action')==='change_password'):?><div class="notice error"><?=e($error)?></div><?php endif;?><form method="post" class="entry-form account-form"><input type="hidden" name="csrf" value="<?=e($_SESSION['csrf'])?>"><input type="hidden" name="action" value="change_password"><label>当前密码 <span>*</span><input type="password" name="current_password" required maxlength="72" autocomplete="current-password" placeholder="输入当前密码"></label><label>新密码 <span>*</span><input type="password" name="new_password" required minlength="6" maxlength="72" pattern="[A-Za-z0-9]+" autocomplete="new-password" placeholder="6–72 位数字或字母"></label><label>确认新密码 <span>*</span><input type="password" name="confirm_password" required minlength="6" maxlength="72" pattern="[A-Za-z0-9]+" autocomplete="new-password" placeholder="再次输入新密码"></label><div class="form-actions"><button class="button" type="button" data-modal-close>取消</button><button class="button primary" type="submit"><?=icon('check')?>确认修改</button></div></form></section></div><?php endif;?>
<footer>迭代之间 <span>·</span> 记录产品成长的每一刻 <span class="footer-right">Built with care, shipped with purpose.</span></footer></main></div></body></html>
