import { NextResponse } from 'next/server';
import { listAuditEvents, listImageAssets, recordEvent } from '@/lib/auditDb';
import { loadSession } from '@/lib/storage';

export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';

function escapeHtml(input: string): string {
  return input
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

function formatTime(ts: number): string {
  return new Date(ts).toLocaleString('zh-CN', { hour12: false, timeZone: 'Asia/Shanghai' });
}

function compactMetadata(metadata: string | null): string {
  if (!metadata) return '';
  try {
    const parsed = JSON.parse(metadata) as unknown;
    const raw = JSON.stringify(parsed);
    return raw.length > 260 ? `${raw.slice(0, 260)}...` : raw;
  } catch {
    return metadata.length > 260 ? `${metadata.slice(0, 260)}...` : metadata;
  }
}

export async function GET(_req: Request, ctx: { params: Promise<{ sessionId: string }> }) {
  const { sessionId } = await ctx.params;
  if (!/^s_[a-z0-9_-]+$/i.test(sessionId)) {
    return NextResponse.json({ error: 'bad sessionId' }, { status: 400 });
  }

  const session = await loadSession(sessionId);
  if (!session) return NextResponse.json({ error: 'session not found' }, { status: 404 });

  recordEvent({ action: 'audit.view', sessionId, targetType: 'session', targetId: sessionId, status: 'ok' });
  const events = listAuditEvents(sessionId, 500);
  const assets = listImageAssets(sessionId, 1000);
  const imageRows = assets.map(asset => `
    <tr>
      <td><a href="${asset.url}" target="_blank" rel="noreferrer">${escapeHtml(asset.filename)}</a></td>
      <td>${escapeHtml(asset.bucket)}</td>
      <td>${escapeHtml(asset.kind ?? '')}</td>
      <td>${escapeHtml(asset.template_id ?? asset.target_id ?? '')}</td>
      <td>${asset.width && asset.height ? `${asset.width}×${asset.height}` : ''}</td>
      <td>${asset.current ? '当前' : '历史'}</td>
      <td>${escapeHtml(asset.status ?? '')}</td>
      <td>${formatTime(asset.updated_at)}</td>
    </tr>
  `).join('');

  const eventRows = events.map(event => `
    <tr>
      <td>${formatTime(event.ts)}</td>
      <td><span class="status ${escapeHtml(event.status)}">${escapeHtml(event.status)}</span></td>
      <td>${escapeHtml(event.action)}</td>
      <td>${escapeHtml(event.target_type ?? '')}</td>
      <td>${escapeHtml(event.target_id ?? '')}</td>
      <td>${escapeHtml(event.provider ?? '')}</td>
      <td>${escapeHtml(event.message ?? compactMetadata(event.metadata))}</td>
    </tr>
  `).join('');

  const html = `<!doctype html>
<html lang="zh">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>${escapeHtml(sessionId)} Audit</title>
  <style>
    :root { color-scheme: dark; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #0b0b0d; color: #f5f5f5; }
    body { margin: 0; padding: 28px; }
    header { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; margin-bottom: 24px; }
    h1 { margin: 0 0 8px; font-size: 24px; }
    h2 { margin: 30px 0 12px; font-size: 18px; }
    a { color: #c4b5fd; }
    .muted { color: #9ca3af; }
    .pillrow { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
    .pill { border: 1px solid #2d2f36; border-radius: 999px; padding: 6px 10px; background: #15161b; color: #d1d5db; font-size: 12px; }
    table { width: 100%; border-collapse: collapse; background: #15161b; border: 1px solid #2d2f36; border-radius: 12px; overflow: hidden; }
    th, td { padding: 9px 10px; border-bottom: 1px solid #252831; text-align: left; font-size: 12px; vertical-align: top; }
    th { color: #d1d5db; background: #1d1f27; font-weight: 600; position: sticky; top: 0; }
    td { color: #a7adbb; }
    tr:hover td { background: #191c23; }
    .status { display: inline-flex; border-radius: 999px; padding: 2px 7px; background: #2b2f38; color: #d1d5db; }
    .status.ok { background: rgba(16,185,129,.18); color: #86efac; }
    .status.error { background: rgba(239,68,68,.18); color: #fca5a5; }
    .status.blocked { background: rgba(251,191,36,.18); color: #fde68a; }
    .status.started, .status.running, .status.queued { background: rgba(59,130,246,.18); color: #93c5fd; }
    .empty { color: #9ca3af; }
  </style>
</head>
<body>
  <header>
    <div>
      <h1>操作记录 / 数据库</h1>
      <div class="muted">Session: ${escapeHtml(sessionId)}</div>
      <div class="muted">每次上传、生成、选择、锁定、重做和图库查看都会记录在 <code>data/app.db</code></div>
    </div>
    <div>
      <div class="pillrow">
        <span class="pill">事件 ${events.length}</span>
        <span class="pill">图片索引 ${assets.length}</span>
        <span class="pill">当前图 ${assets.filter(asset => asset.current).length}</span>
      </div>
      <div style="margin-top:10px;text-align:right"><a href="/api/gallery/${encodeURIComponent(sessionId)}">返回图库</a></div>
    </div>
  </header>

  <h2>图片索引</h2>
  ${assets.length ? `<table>
    <thead><tr><th>文件</th><th>桶</th><th>包</th><th>槽位/目标</th><th>真实尺寸</th><th>状态</th><th>资产状态</th><th>更新时间</th></tr></thead>
    <tbody>${imageRows}</tbody>
  </table>` : '<p class="empty">暂无图片索引。</p>'}

  <h2>操作事件</h2>
  ${events.length ? `<table>
    <thead><tr><th>时间</th><th>状态</th><th>动作</th><th>目标类型</th><th>目标 ID</th><th>Provider</th><th>信息</th></tr></thead>
    <tbody>${eventRows}</tbody>
  </table>` : '<p class="empty">暂无操作记录。</p>'}
</body>
</html>`;

  return new NextResponse(html, {
    headers: {
      'Content-Type': 'text/html; charset=utf-8',
      'Cache-Control': 'no-store',
    },
  });
}
