"use client";

import Link from "next/link";
import { useEffect, useState } from "react";

import { apiFetch } from "@/lib/api";
import { readToken } from "@/lib/auth";
import { useI18nText } from "@/lib/i18n";
import { Activity, AlertCircle, List, Play, RefreshCw, Server, Trash2, Zap } from "lucide-react";

type BackendLogItem = {
  id: number;
  problem_id: number;
  problem_title: string;
  status: string;
  progress: number;
  message: string;
  created_by: number;
  max_solutions: number;
  created_at: number;
  started_at: number | null;
  finished_at: number | null;
  updated_at: number;
  runner_pending: boolean;
};

type QueueJobItem = {
  id: number;
  problem_id: number;
  problem_title: string;
  status: string;
  progress: number;
  message: string;
  updated_at: number;
  started_at?: number | null;
};

type BackendLogsResp = {
  items: BackendLogItem[];
  running_jobs: QueueJobItem[];
  queued_jobs: QueueJobItem[];
  running_problem_ids: number[];
  queued_problem_ids: number[];
  running_count: number;
  queued_count_preview: number;
  pending_jobs: number;
  missing_problems: number;
  limit: number;
  running_limit: number;
  queued_limit: number;
};

type TriggerMissingResp = {
  started: boolean;
  missing_total: number;
  candidate_count: number;
  queued_count: number;
  pending_jobs: number;
  limit: number;
  max_solutions: number;
};

type AdminUser = {
  id: number;
  username: string;
  rating: number;
  created_at: number;
};

type AdminUsersResp = {
  items: AdminUser[];
  total_count: number;
  page: number;
  page_size: number;
};

function fmtTs(v: number | null | undefined): string {
  if (!v) return "-";
  return new Date(v * 1000).toLocaleString();
}

export default function BackendLogsPage() {
  const { tx } = useI18nText();
  const [token, setToken] = useState("");
  const [checkingAdmin, setCheckingAdmin] = useState(true);
  const [isAdmin, setIsAdmin] = useState(false);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  const [limit, setLimit] = useState(100);
  const [pendingJobs, setPendingJobs] = useState(0);
  const [missingProblems, setMissingProblems] = useState(0);
  const [items, setItems] = useState<BackendLogItem[]>([]);
  const [runningJobs, setRunningJobs] = useState<QueueJobItem[]>([]);
  const [queuedJobs, setQueuedJobs] = useState<QueueJobItem[]>([]);
  const [runningIds, setRunningIds] = useState<number[]>([]);
  const [queuedIds, setQueuedIds] = useState<number[]>([]);
  const [triggerLoading, setTriggerLoading] = useState(false);
  const [triggerMsg, setTriggerMsg] = useState("");
  const [users, setUsers] = useState<AdminUser[]>([]);
  const [deleteUserId, setDeleteUserId] = useState<number | null>(null);
  const [userMsg, setUserMsg] = useState("");

  const refresh = async () => {
    if (!isAdmin || !token) return;
    setLoading(true);
    setError("");
    try {
      const [data, usersData] = await Promise.all([
        apiFetch<BackendLogsResp>(
          `/api/v1/backend/logs?limit=${limit}&running_limit=20&queued_limit=100`,
          {},
          token
        ),
        apiFetch<AdminUsersResp>("/api/v1/admin/users?page=1&page_size=200", {}, token),
      ]);

      setPendingJobs(data.pending_jobs ?? 0);
      setMissingProblems(data.missing_problems ?? 0);
      setItems(data.items ?? []);
      setRunningJobs(data.running_jobs ?? []);
      setQueuedJobs(data.queued_jobs ?? []);
      setRunningIds(data.running_problem_ids ?? []);
      setQueuedIds(data.queued_problem_ids ?? []);
      setUsers(usersData.items ?? []);
    } catch (e: unknown) {
      setError(String(e));
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    let canceled = false;
    const checkAdmin = async () => {
      setCheckingAdmin(true);
      const tk = readToken();
      if (!canceled) setToken(tk);
      if (!tk) {
        if (!canceled) {
          setIsAdmin(false);
          setError(tx("请先登录管理员账号", "Please sign in with admin account first"));
          setCheckingAdmin(false);
        }
        return;
      }
      try {
        const me = await apiFetch<{ username?: string }>("/api/v1/me", {}, tk);
        const allowed = (me?.username ?? "") === "admin";
        if (!canceled) {
          setIsAdmin(allowed);
          if (!allowed) {
            setError(tx("仅管理员可查看后台日志", "Backend logs are visible to admin only"));
          } else {
            setError("");
          }
        }
      } catch (e: unknown) {
        if (!canceled) {
          setIsAdmin(false);
          setError(String(e));
        }
      } finally {
        if (!canceled) setCheckingAdmin(false);
      }
    };
    void checkAdmin();
    return () => {
      canceled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (!isAdmin || !token) return;
    void refresh();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isAdmin, token, limit]);

  const triggerMissingSolutions = async () => {
    if (!isAdmin || !token) {
      setError(tx("请先登录管理员账号", "Please sign in with admin account first"));
      return;
    }
    setTriggerLoading(true);
    setTriggerMsg("");
    setError("");
    try {
      const data = await apiFetch<TriggerMissingResp>(
        "/api/v1/backend/solutions/generate-missing",
        {
          method: "POST",
          body: JSON.stringify({ limit: 50000, max_solutions: 3 }),
        },
        token
      );
      setPendingJobs(data.pending_jobs ?? 0);
      setTriggerMsg(
        tx(
          `已触发异步任务：候选 ${data.candidate_count} 题，入队 ${data.queued_count} 题（当前待处理 ${data.pending_jobs}）。`,
          `Async trigger submitted: candidate ${data.candidate_count}, queued ${data.queued_count} (pending ${data.pending_jobs}).`
        )
      );
      await refresh();
    } catch (e: unknown) {
      setError(String(e));
    } finally {
      setTriggerLoading(false);
    }
  };

  const deleteUser = async (user: AdminUser) => {
    if (!isAdmin || !token) return;
    if (user.username === "admin") {
      setError(tx("保留管理员账号不可删除", "Reserved admin account cannot be deleted"));
      return;
    }
    const ok = window.confirm(
      tx(
        `确认删除用户 ${user.username}(#${user.id})？该用户提交记录、错题本、草稿、积分记录会被级联删除。`,
        `Delete user ${user.username}(#${user.id})? Submissions, wrong-book, drafts, and points records will be removed by cascade.`
      )
    );
    if (!ok) return;

    setDeleteUserId(user.id);
    setError("");
    setUserMsg("");
    try {
      await apiFetch(
        `/api/v1/admin/users/${user.id}`,
        {
          method: "DELETE",
        },
        token
      );
      setUserMsg(
        tx(
          `已删除用户 ${user.username}(#${user.id})`,
          `Deleted user ${user.username}(#${user.id}).`
        )
      );
      await refresh();
    } catch (e: unknown) {
      setError(String(e));
    } finally {
      setDeleteUserId(null);
    }
  };

  useEffect(() => {
    if (!isAdmin || !token) return;
    const timer = setInterval(() => {
      void refresh();
    }, 5000);
    return () => clearInterval(timer);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isAdmin, token, limit]);

  if (checkingAdmin) {
    return (
      <main className="mx-auto max-w-7xl px-3 py-8 text-sm text-zinc-600">
        {tx("正在校验管理员权限...", "Checking admin access...")}
      </main>
    );
  }

  if (!isAdmin) {
    return (
      <main className="mx-auto max-w-5xl px-3 py-8">
        <h1 className="text-xl font-semibold">{tx("后台日志（题解异步队列）", "Backend Logs (Async Solution Queue)")}</h1>
        <p className="mt-3 text-sm text-red-600">
          {error || tx("仅管理员可查看此页面", "This page is available for admin only")}
        </p>
      </main>
    );
  }

  return (
    <main className="mx-auto max-w-7xl px-3 py-6 max-[390px]:px-2 sm:px-4 md:px-6 md:py-8">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <h1 className="text-xl font-semibold max-[390px]:text-lg sm:text-2xl flex items-center gap-2">
          <Server size={24} />
          {tx("后台日志（题解异步队列）", "Backend Logs (Async Solution Queue)")}
        </h1>
        <div className="flex w-full flex-wrap items-center gap-2 text-sm sm:w-auto sm:justify-end">
          <span className={pendingJobs > 0 ? "text-emerald-700" : "text-zinc-600"}>
            {tx("待处理任务", "Pending jobs")} {pendingJobs}
          </span>
          <span className={missingProblems > 0 ? "text-amber-700" : "text-zinc-600"}>
            {tx("缺失答案题目", "Problems missing answers")} {missingProblems}
          </span>
          <button
            className="rounded border px-3 py-1 disabled:opacity-50 flex items-center gap-1"
            onClick={() => void triggerMissingSolutions()}
            disabled={triggerLoading}
          >
            <Zap size={14} />
            {triggerLoading ? tx("手动补全中...", "Triggering...") : tx("手动补全（可选）", "Manual fill (optional)")}
          </button>
          <select
            className="rounded border px-2 py-1"
            value={limit}
            onChange={(e) => setLimit(Number(e.target.value))}
          >
            <option value={50}>{tx("最近 50 条", "Latest 50")}</option>
            <option value={100}>{tx("最近 100 条", "Latest 100")}</option>
            <option value={200}>{tx("最近 200 条", "Latest 200")}</option>
          </select>
          <button className="rounded border px-3 py-1 sm:ml-auto flex items-center gap-1" onClick={() => void refresh()} disabled={loading}>
            <RefreshCw size={14} className={loading ? "animate-spin" : ""} />
            {tx("刷新", "Refresh")}
          </button>
        </div>
      </div>

      {error && <p className="mt-3 text-sm text-red-600">{error}</p>}
      {triggerMsg && <p className="mt-3 text-sm text-emerald-700">{triggerMsg}</p>}
      {userMsg && <p className="mt-3 text-sm text-emerald-700">{userMsg}</p>}
      <p className="mt-3 text-xs text-zinc-500">
        {tx(
          "系统已自动单线程异步处理待队列任务，无需手工点击；上方按钮仅用于立即手动补全。",
          "System auto-processes queued jobs in single-thread async mode; the button above is only for manual trigger."
        )}
      </p>

      <section className="mt-4 rounded-xl border bg-white p-3">
        <div className="flex flex-wrap items-center justify-between gap-2">
          <h2 className="text-sm font-medium">{tx("用户管理（可删除）", "User Management (Delete Supported)")}</h2>
          <p className="text-xs text-zinc-600">
            {tx("总用户", "Total users")} {users.length}
          </p>
        </div>

        <div className="mt-3 divide-y md:hidden">
          {users.map((user) => (
            <article key={user.id} className="space-y-1 py-2 text-xs">
              <p className="font-medium">
                #{user.id} · {user.username}
              </p>
              <p className="text-zinc-600">
                Rating {user.rating} · {tx("创建", "Created")} {fmtTs(user.created_at)}
              </p>
              <button
                className="rounded border px-2 py-1 text-xs text-red-700 hover:bg-red-50 disabled:opacity-60"
                disabled={deleteUserId === user.id || user.username === "admin"}
                onClick={() => void deleteUser(user)}
              >
                {user.username === "admin"
                  ? tx("保留账号", "Reserved")
                  : deleteUserId === user.id
                    ? tx("删除中...", "Deleting...")
                    : tx("删除用户", "Delete User")}
              </button>
            </article>
          ))}
          {!loading && users.length === 0 && (
            <p className="py-4 text-center text-sm text-zinc-500">{tx("暂无用户数据", "No users found")}</p>
          )}
        </div>

        <div className="mt-2 hidden overflow-x-auto md:block">
          <table className="min-w-full text-xs">
            <thead className="bg-zinc-100 text-left">
              <tr>
                <th className="px-2 py-2">ID</th>
                <th className="px-2 py-2">{tx("用户名", "Username")}</th>
                <th className="px-2 py-2">Rating</th>
                <th className="px-2 py-2">{tx("创建时间", "Created At")}</th>
                <th className="px-2 py-2">{tx("操作", "Action")}</th>
              </tr>
            </thead>
            <tbody>
              {users.map((user) => (
                <tr key={user.id} className="border-t">
                  <td className="px-2 py-2">{user.id}</td>
                  <td className="px-2 py-2">{user.username}</td>
                  <td className="px-2 py-2">{user.rating}</td>
                  <td className="px-2 py-2 text-zinc-600">{fmtTs(user.created_at)}</td>
                  <td className="px-2 py-2">
                    <button
                      className="rounded border px-2 py-1 text-xs text-red-700 hover:bg-red-50 disabled:opacity-60"
                      disabled={deleteUserId === user.id || user.username === "admin"}
                      onClick={() => void deleteUser(user)}
                    >
                      {user.username === "admin"
                        ? tx("保留账号", "Reserved")
                        : deleteUserId === user.id
                          ? tx("删除中...", "Deleting...")
                          : tx("删除用户", "Delete User")}
                    </button>
                  </td>
                </tr>
              ))}
              {!loading && users.length === 0 && (
                <tr>
                  <td className="px-2 py-4 text-center text-zinc-500" colSpan={5}>
                    {tx("暂无用户数据", "No users found")}
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </section>

      <section className="mt-4 grid gap-3 md:grid-cols-2">
        <article className="rounded-xl border bg-white p-3">
          <h2 className="text-sm font-medium flex items-center gap-2">
            <Activity size={16} className="text-emerald-600" />
            {tx("正在处理（Running）", "Running Jobs")}
          </h2>
          <p className="mt-1 text-xs text-zinc-600">
            {tx("当前题目 ID：", "Current problem IDs:")}
            {runningIds.length ? runningIds.join(", ") : tx("无", "None")}
          </p>
          <ul className="mt-2 space-y-2 text-xs">
            {runningJobs.map((job) => (
              <li key={job.id} className="rounded border border-zinc-200 p-2">
                <p>
                  {tx("任务", "Job")} #{job.id} · {tx("题目", "Problem")} #{job.problem_id} {job.problem_title || tx("(未命名题目)", "(Untitled)")}
                </p>
                <p className="text-zinc-600">
                  {tx("状态", "Status")} {job.status} · {tx("进度", "Progress")} {job.progress}% · {tx("开始", "Start")} {fmtTs(job.started_at ?? null)}
                </p>
                <p className="whitespace-pre-wrap break-words text-zinc-600">{job.message || "-"}</p>
              </li>
            ))}
            {!runningJobs.length && <li className="text-zinc-500">{tx("当前无运行中的任务", "No running jobs")}</li>}
          </ul>
        </article>

        <article className="rounded-xl border bg-white p-3">
          <h2 className="text-sm font-medium flex items-center gap-2">
            <List size={16} className="text-amber-600" />
            {tx("待处理队列（Queued）", "Queued Jobs")}
          </h2>
          <p className="mt-1 text-xs text-zinc-600">
            {tx("待处理题目 ID（预览）：", "Queued problem IDs (preview):")}
            {queuedIds.length ? queuedIds.join(", ") : tx("无", "None")}
          </p>
          <ul className="mt-2 max-h-56 space-y-2 overflow-auto text-xs">
            {queuedJobs.map((job) => (
              <li key={job.id} className="rounded border border-zinc-200 p-2">
                <p>
                  {tx("任务", "Job")} #{job.id} · {tx("题目", "Problem")} #{job.problem_id} {job.problem_title || tx("(未命名题目)", "(Untitled)")}
                </p>
                <p className="text-zinc-600">
                  {tx("状态", "Status")} {job.status} · {tx("进度", "Progress")} {job.progress}% · {tx("更新", "Updated")} {fmtTs(job.updated_at)}
                </p>
                <p className="whitespace-pre-wrap break-words text-zinc-600">{job.message || "-"}</p>
              </li>
            ))}
            {!queuedJobs.length && <li className="text-zinc-500">{tx("当前无待处理任务", "No queued jobs")}</li>}
          </ul>
        </article>
      </section>

      <section className="mt-4 rounded-xl border bg-white">
        <div className="divide-y md:hidden">
          {items.map((item) => (
            <article key={item.id} className="space-y-2 p-3 text-xs">
              <div className="flex items-center justify-between gap-2">
                <p className="font-medium">
                  {tx("任务", "Job")} #{item.id}
                </p>
                <span className={item.runner_pending ? "text-emerald-700" : "text-zinc-700"}>
                  {item.status} · {item.progress}%
                </span>
              </div>
              <Link className="text-blue-600 hover:underline" href={`/problems/${item.problem_id}`}>
                #{item.problem_id} {item.problem_title || tx("(未命名题目)", "(Untitled)")}
              </Link>
              <p className="whitespace-pre-wrap break-words text-zinc-600">{item.message || "-"}</p>
              <p className="text-zinc-500">
                {tx("创建", "Created")} {fmtTs(item.created_at)} · {tx("开始", "Start")} {fmtTs(item.started_at)} · {tx("结束", "End")} {fmtTs(item.finished_at)}
              </p>
            </article>
          ))}
          {!loading && items.length === 0 && (
            <p className="px-3 py-6 text-center text-sm text-zinc-500">{tx("暂无后台任务日志", "No backend logs yet")}</p>
          )}
        </div>

        <div className="hidden overflow-x-auto md:block">
          <table className="min-w-full text-xs">
            <thead className="bg-zinc-100 text-left">
              <tr>
                <th className="px-2 py-2">{tx("任务ID", "Job ID")}</th>
                <th className="px-2 py-2">{tx("题目", "Problem")}</th>
                <th className="px-2 py-2">{tx("状态", "Status")}</th>
                <th className="px-2 py-2">{tx("进度", "Progress")}</th>
                <th className="px-2 py-2">{tx("消息", "Message")}</th>
                <th className="px-2 py-2">{tx("时间", "Time")}</th>
              </tr>
            </thead>
            <tbody>
              {items.map((item) => (
                <tr key={item.id} className="border-t align-top">
                  <td className="px-2 py-2 font-medium">{item.id}</td>
                  <td className="max-w-[260px] px-2 py-2">
                    <Link className="text-blue-600 hover:underline" href={`/problems/${item.problem_id}`}>
                      #{item.problem_id} {item.problem_title || tx("(未命名题目)", "(Untitled)")}
                    </Link>
                  </td>
                  <td className="px-2 py-2">
                    <span className={item.runner_pending ? "text-emerald-700" : "text-zinc-700"}>
                      {item.status}
                    </span>
                  </td>
                  <td className="px-2 py-2">{item.progress}%</td>
                  <td className="max-w-[420px] px-2 py-2">
                    <div className="whitespace-pre-wrap break-words">{item.message || "-"}</div>
                  </td>
                  <td className="px-2 py-2 text-zinc-600">
                    {tx("创建", "Created")} {fmtTs(item.created_at)}
                    <br />
                    {tx("开始", "Start")} {fmtTs(item.started_at)}
                    <br />
                    {tx("结束", "End")} {fmtTs(item.finished_at)}
                  </td>
                </tr>
              ))}
              {!loading && items.length === 0 && (
                <tr>
                  <td className="px-2 py-6 text-center text-zinc-500" colSpan={6}>
                    {tx("暂无后台任务日志", "No backend logs yet")}
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </section>
    </main>
  );
}
