import { useEffect, useState } from "react";

import "./admin-generations.css";

interface AdminSession {
  acknowledged_private_content_notice_version: string | null;
  current_private_content_notice_version: string | null;
  csrf_token: string;
  notice_acknowledged: boolean;
}

interface GenerationRecord {
  generation_id: string;
  owner_ref: string;
  project_id: string;
  model_id: string;
  ratio: string;
  status: "queued" | "running" | "succeeded" | "failed" | "rejected";
  created_at: string;
  completed_at: string | null;
  duration_ms: number | null;
  confirmed_credit_cost: number;
  reserved_credits: number;
  final_credit_state: "committed" | "released" | null;
  error_category: string | null;
}

interface GenerationResponse { generated_at: string; items: GenerationRecord[] }
interface OpenedPrompt { generation_id: string; prompt: string }

function idempotencyKey() {
  return `${crypto.randomUUID().replaceAll("-", "")}${crypto.randomUUID().replaceAll("-", "")}`;
}

function compactId(value: string) { return `${value.slice(0, 8)}...${value.slice(-4)}`; }
function formatTime(value: string | null) { return value ? new Intl.DateTimeFormat("zh-CN", { dateStyle: "short", timeStyle: "medium" }).format(new Date(value)) : "未完成"; }
function statusLabel(value: GenerationRecord["status"]) { return { queued: "排队", running: "运行中", succeeded: "成功", failed: "失败", rejected: "已拒绝" }[value]; }

export function AdminGenerationsPage() {
  const [session, setSession] = useState<AdminSession>();
  const [records, setRecords] = useState<GenerationRecord[]>([]);
  const [loading, setLoading] = useState(true);
  const [failed, setFailed] = useState(false);
  const [acknowledging, setAcknowledging] = useState(false);
  const [notice, setNotice] = useState("");
  const [openedPrompt, setOpenedPrompt] = useState<OpenedPrompt>();
  const [openedImage, setOpenedImage] = useState<{ generationId: string; url: string }>();

  async function load() {
    setLoading(true);
    setFailed(false);
    try {
      const sessionResponse = await fetch("/api/v1/admin-auth/session", { credentials: "same-origin" });
      if (sessionResponse.status === 401) throw new Error("session_invalid");
      if (!sessionResponse.ok) throw new Error("session_unavailable");
      const current = await sessionResponse.json() as AdminSession;
      setSession(current);
      setNotice("");
      if (!current.notice_acknowledged) {
        setRecords([]);
        return;
      }
      const listResponse = await fetch("/api/v1/admin/generations", { credentials: "same-origin" });
      if (!listResponse.ok) throw new Error("generation_list_unavailable");
      setRecords((await listResponse.json() as GenerationResponse).items);
    } catch {
      setFailed(true);
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => { void load(); }, []);
  useEffect(() => () => { if (openedImage) URL.revokeObjectURL(openedImage.url); }, [openedImage]);

  async function acknowledge() {
    if (!session?.current_private_content_notice_version || acknowledging) return;
    setAcknowledging(true);
    setNotice("");
    try {
      const response = await fetch("/api/v1/admin/private-content-notice/ack", {
        body: JSON.stringify({ expected_notice_version: session.current_private_content_notice_version }),
        credentials: "same-origin",
        headers: { "Content-Type": "application/json", "Idempotency-Key": idempotencyKey(), "X-CSRF-Token": session.csrf_token },
        method: "POST",
      });
      if (!response.ok) throw new Error("notice_ack_failed");
      await load();
    } catch {
      setNotice("告知版本已变化或确认未完成，请重新读取。 ");
    } finally {
      setAcknowledging(false);
    }
  }

  async function openPrompt(generationId: string) {
    setNotice("");
    try {
      const response = await fetch(`/api/v1/admin/private-content/generations/${generationId}/prompt`, { credentials: "same-origin" });
      if (!response.ok) throw new Error("prompt_unavailable");
      setOpenedPrompt(await response.json() as OpenedPrompt);
    } catch {
      setNotice("内容读取未完成，访问审计未成功时不会返回内容。 ");
    }
  }

  async function openImage(generationId: string) {
    setNotice("");
    try {
      const response = await fetch(`/api/v1/admin/private-content/generations/${generationId}/image`, { credentials: "same-origin" });
      if (!response.ok) throw new Error("image_unavailable");
      const url = URL.createObjectURL(await response.blob());
      setOpenedImage((previous) => {
        if (previous) URL.revokeObjectURL(previous.url);
        return { generationId, url };
      });
    } catch {
      setNotice("内容读取未完成，访问审计未成功时不会返回内容。 ");
    }
  }

  return (
    <main className="admin-generations" id="admin-main">
      <header className="admin-page-heading"><div><p>OPERATIONS / GENERATION RECORDS</p><h2>生成记录</h2></div><button className="admin-generations-refresh" onClick={() => void load()} type="button">重新读取</button></header>
      {loading ? <p aria-live="polite">正在读取生成记录</p> : null}
      {failed ? <div className="admin-generations-error" role="alert">后台生成记录暂时无法读取。<button onClick={() => void load()} type="button">重试</button></div> : null}
      {notice ? <p className="admin-generations-notice" role="alert">{notice}</p> : null}
      {session && !session.notice_acknowledged ? (
        <section aria-labelledby="private-content-notice-title" className="admin-generations-notice-panel">
          <p>PRIVATE CONTENT ACCESS</p>
          <h3 id="private-content-notice-title">查看私有内容前，请确认当前规则告知</h3>
          <p>生成记录默认只显示安全元数据。打开图片或完整提示词时，系统会自动记录本次管理员、目标和内容类型访问审计。</p>
          <button disabled={acknowledging} onClick={() => void acknowledge()} type="button">{acknowledging ? "确认中" : "确认并进入记录"}</button>
        </section>
      ) : null}
      {session?.notice_acknowledged ? (
        <section aria-label="生成记录元数据" className="admin-generations-table-wrap">
          <table><thead><tr><th>任务</th><th>用户标识</th><th>模型 / 比例</th><th>状态</th><th>创建 / 完成</th><th>点数</th><th>私有内容</th></tr></thead><tbody>
            {records.map((record) => <tr key={record.generation_id}>
              <td><code>{compactId(record.generation_id)}</code></td>
              <td><code>{compactId(record.owner_ref)}</code></td>
              <td>{record.model_id}<br /><small>{record.ratio}</small></td>
              <td><span className={`admin-generations-status is-${record.status}`}>{statusLabel(record.status)}</span>{record.error_category ? <small>{record.error_category}</small> : null}</td>
              <td><time dateTime={record.created_at}>{formatTime(record.created_at)}</time><br /><small>{formatTime(record.completed_at)}</small></td>
              <td>{record.confirmed_credit_cost} / {record.final_credit_state ?? "冻结"}</td>
              <td className="admin-generations-actions"><button onClick={() => void openPrompt(record.generation_id)} type="button">打开提示词并记录审计</button><button disabled={record.status !== "succeeded"} onClick={() => void openImage(record.generation_id)} type="button">打开图片并记录审计</button></td>
            </tr>)}
          </tbody></table>
          {!records.length && !loading ? <p className="admin-generations-empty">当前无生成记录</p> : null}
        </section>
      ) : null}
      {openedPrompt ? <section aria-label="已审计的完整提示词" className="admin-generations-opened"><header><h3>已记录审计的完整提示词</h3><button onClick={() => setOpenedPrompt(undefined)} type="button">关闭</button></header><p><code>{compactId(openedPrompt.generation_id)}</code></p><pre>{openedPrompt.prompt}</pre></section> : null}
      {openedImage ? <section aria-label="已审计的生成图片" className="admin-generations-opened"><header><h3>已记录审计的生成图片</h3><button onClick={() => { URL.revokeObjectURL(openedImage.url); setOpenedImage(undefined); }} type="button">关闭</button></header><img alt="已记录审计的生成图片" src={openedImage.url} /></section> : null}
    </main>
  );
}
