import { useCallback, useEffect, useRef, useState } from "react";
import { keyServerClient } from "../api/keyServerClient";

export interface ClientErrorItem {
  id: number;
  message: string;
  stack?: string;
  source: string;
  url: string;
  user_agent?: string;
  user_id?: number;
  count: number;
  first_seen: string;
  last_seen: string;
}

const STORAGE_KEY = "omniai:admin-monitor-open";
const POLL_INTERVAL = 30000;

function formatTime(iso: string) {
  const d = new Date(iso);
  return d.toLocaleString("zh-CN", { month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit" });
}

function AdminMonitor() {
  const [open, setOpen] = useState(() => {
    try { return sessionStorage.getItem(STORAGE_KEY) === "1"; } catch { return false; }
  });
  const [errors, setErrors] = useState<ClientErrorItem[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const intervalRef = useRef<ReturnType<typeof setInterval>>();

  const fetchErrors = useCallback(async (p = 1) => {
    setLoading(true);
    try {
      const data = await keyServerClient.getClientErrors(p);
      setErrors(data.items);
      setTotal(data.total);
      setPage(p);
    } catch { /* silent */ }
    setLoading(false);
  }, []);

  useEffect(() => {
    if (!open) return;
    void fetchErrors(1);
    intervalRef.current = setInterval(() => fetchErrors(1), POLL_INTERVAL);
    return () => clearInterval(intervalRef.current);
  }, [open, fetchErrors]);

  useEffect(() => {
    try { sessionStorage.setItem(STORAGE_KEY, open ? "1" : "0"); } catch { /* */ }
  }, [open]);

  const maxPage = Math.max(1, Math.ceil(total / 50));

  if (!open) {
    return (
      <button type="button" className="admin-monitor-trigger" onClick={() => setOpen(true)} title="错误监控">
        <span className="admin-monitor-trigger__dot" aria-hidden="true" />
      </button>
    );
  }

  return (
    <div className="admin-monitor" role="dialog" aria-label="客户端错误监控">
      <header className="admin-monitor__header">
        <strong>客户端错误 ({total})</strong>
        <div className="admin-monitor__actions">
          <button type="button" onClick={() => void fetchErrors(1)} disabled={loading}>
            {loading ? "刷新中..." : "刷新"}
          </button>
          <button type="button" onClick={() => setOpen(false)}>关闭</button>
        </div>
      </header>
      <section className="admin-monitor__list">
        {errors.length === 0 ? (
          <div className="admin-monitor__empty">暂无错误</div>
        ) : (
          errors.map((err) => (
            <details key={err.id} className="admin-monitor__item">
              <summary>
                <span className="admin-monitor__source">{err.source}</span>
                <span className="admin-monitor__msg">{err.message.slice(0, 120)}</span>
                <span className="admin-monitor__count">{err.count}</span>
                <time>{formatTime(err.last_seen)}</time>
              </summary>
              <div className="admin-monitor__detail">
                <div><b>URL:</b> {err.url}</div>
                <div><b>User:</b> {err.user_id || "匿名"}</div>
                {err.stack ? <pre>{err.stack.slice(0, 1000)}</pre> : null}
              </div>
            </details>
          ))
        )}
      </section>
      {maxPage > 1 ? (
        <footer className="admin-monitor__pager">
          <button type="button" disabled={page <= 1} onClick={() => fetchErrors(page - 1)}>上一页</button>
          <span>{page} / {maxPage}</span>
          <button type="button" disabled={page >= maxPage} onClick={() => fetchErrors(page + 1)}>下一页</button>
        </footer>
      ) : null}
    </div>
  );
}

export default AdminMonitor;
