"use client";

import { useCallback, useEffect, useState } from "react";

interface ErrorRow {
  id: string;
  level: string;
  source: string;
  message: string;
  stack: string | null;
  url: string | null;
  digest: string | null;
  user_email: string | null;
  family_name: string | null;
  user_agent: string | null;
  created_at: string;
}
interface GroupRow { message: string; source: string; count: number; last_seen: string; first_seen: string }
interface Stats { last24h: number; last7d: number; client7d: number; server7d: number }
interface Data { events: ErrorRow[]; grouped: GroupRow[]; stats: Stats; error?: string }

const WINDOWS = [
  { label: "24h", hours: 24 },
  { label: "7d", hours: 168 },
  { label: "30d", hours: 720 },
];

export default function AdminErrors() {
  const [data, setData] = useState<Data | null>(null);
  const [loading, setLoading] = useState(true);
  const [tab, setTab] = useState<"recent" | "grouped">("recent");
  const [source, setSource] = useState<"" | "client" | "server">("");
  const [hours, setHours] = useState(168);
  const [q, setQ] = useState("");
  const [expanded, setExpanded] = useState<string | null>(null);

  const load = useCallback(() => {
    setLoading(true);
    const params = new URLSearchParams({ sinceHours: String(hours) });
    if (source) params.set("source", source);
    if (q.trim()) params.set("q", q.trim());
    fetch(`/api/admin/errors?${params}`, { credentials: "include" })
      .then(r => r.json())
      .then(d => {
        setData({
          events: Array.isArray(d?.events) ? d.events : [],
          grouped: Array.isArray(d?.grouped) ? d.grouped : [],
          stats: d?.stats || { last24h: 0, last7d: 0, client7d: 0, server7d: 0 },
          error: d?.error,
        });
        setLoading(false);
      })
      .catch(() => setLoading(false));
  }, [hours, source, q]);

  useEffect(() => { load(); }, [hours, source]); // eslint-disable-line react-hooks/exhaustive-deps

  const stats = data?.stats || { last24h: 0, last7d: 0, client7d: 0, server7d: 0 };

  return (
    <div className="p-6 space-y-6">
      <div className="flex justify-between items-start flex-wrap gap-3">
        <div>
          <h1 className="text-2xl font-bold">Errors &amp; Crashes</h1>
          <p className="text-gray-400">Client &amp; server errors captured automatically</p>
        </div>
        <button onClick={load} className="px-3 py-1.5 bg-gray-700 hover:bg-gray-600 rounded-lg text-sm">↻ Refresh</button>
      </div>

      <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
        <Card label="Last 24h" value={stats.last24h} color={stats.last24h > 0 ? "text-rose-400" : "text-emerald-400"} />
        <Card label="Last 7d" value={stats.last7d} color="text-amber-400" />
        <Card label="Client (7d)" value={stats.client7d} color="text-blue-400" />
        <Card label="Server (7d)" value={stats.server7d} color="text-purple-400" />
      </div>

      <div className="flex gap-2 flex-wrap items-center">
        <div className="flex gap-1 bg-gray-800 p-1 rounded-lg">
          {(["recent", "grouped"] as const).map(t => (
            <button key={t} onClick={() => setTab(t)} className={`px-3 py-1.5 rounded-md text-sm font-medium capitalize ${tab === t ? "bg-gray-600" : "text-gray-400 hover:text-white"}`}>{t}</button>
          ))}
        </div>
        <select value={source} onChange={e => setSource(e.target.value as "" | "client" | "server")} className="bg-gray-800 border border-gray-700 rounded-lg px-3 py-1.5 text-sm">
          <option value="">All sources</option>
          <option value="client">Client</option>
          <option value="server">Server</option>
        </select>
        <div className="flex gap-1 bg-gray-800 p-1 rounded-lg">
          {WINDOWS.map(w => (
            <button key={w.hours} onClick={() => setHours(w.hours)} className={`px-3 py-1.5 rounded-md text-sm ${hours === w.hours ? "bg-gray-600" : "text-gray-400 hover:text-white"}`}>{w.label}</button>
          ))}
        </div>
        <form onSubmit={e => { e.preventDefault(); load(); }} className="flex-1 min-w-[180px]">
          <input value={q} onChange={e => setQ(e.target.value)} placeholder="Search message…" className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-1.5 text-sm" />
        </form>
      </div>

      {data?.error && <div className="bg-rose-500/10 text-rose-400 text-sm p-3 rounded-lg">Feed error: {data.error}</div>}

      {loading ? (
        <div className="text-gray-400">Loading…</div>
      ) : tab === "recent" ? (
        <div className="bg-gray-800 rounded-xl overflow-hidden">
          {(data?.events.length ?? 0) === 0 ? (
            <div className="p-8 text-center text-gray-500">🎉 No errors in this window</div>
          ) : (
            <div className="divide-y divide-gray-700">
              {data!.events.map(e => (
                <div key={e.id} className="p-4 hover:bg-gray-750">
                  <div className="flex items-start gap-3 cursor-pointer" onClick={() => setExpanded(expanded === e.id ? null : e.id)}>
                    <LevelBadge level={e.level} />
                    <span className={`text-xs px-1.5 py-0.5 rounded ${e.source === "client" ? "bg-blue-500/20 text-blue-400" : "bg-purple-500/20 text-purple-400"}`}>{e.source}</span>
                    <div className="flex-1 min-w-0">
                      <div className="text-sm font-medium break-words">{e.message}</div>
                      <div className="text-xs text-gray-500 mt-0.5 flex gap-2 flex-wrap">
                        {e.url && <span>📍 {e.url}</span>}
                        {e.user_email && <span>👤 {e.user_email}</span>}
                        {e.family_name && <span>🏠 {e.family_name}</span>}
                        <span>🕒 {timeAgo(e.created_at)}</span>
                      </div>
                    </div>
                    <span className="text-gray-500 text-xs">{expanded === e.id ? "▲" : "▼"}</span>
                  </div>
                  {expanded === e.id && (
                    <pre className="mt-3 bg-gray-900 p-3 rounded-lg text-xs text-gray-400 overflow-x-auto whitespace-pre-wrap break-words max-h-72">
                      {e.stack || "(no stack trace)"}
                      {e.user_agent ? `\n\nUser-Agent: ${e.user_agent}` : ""}
                      {e.digest ? `\nDigest: ${e.digest}` : ""}
                    </pre>
                  )}
                </div>
              ))}
            </div>
          )}
        </div>
      ) : (
        <div className="bg-gray-800 rounded-xl overflow-hidden">
          {(data?.grouped.length ?? 0) === 0 ? (
            <div className="p-8 text-center text-gray-500">No errors to group</div>
          ) : (
            <table className="w-full">
              <thead className="bg-gray-700"><tr>
                <th className="px-4 py-3 text-left text-sm font-medium">Count</th>
                <th className="px-4 py-3 text-left text-sm font-medium">Source</th>
                <th className="px-4 py-3 text-left text-sm font-medium">Message</th>
                <th className="px-4 py-3 text-left text-sm font-medium">Last seen</th>
              </tr></thead>
              <tbody className="divide-y divide-gray-700">
                {data!.grouped.map((g, i) => (
                  <tr key={i} className="hover:bg-gray-750">
                    <td className="px-4 py-3"><span className="bg-rose-500/20 text-rose-400 px-2 py-0.5 rounded font-bold text-sm">{g.count}</span></td>
                    <td className="px-4 py-3 text-sm text-gray-400">{g.source}</td>
                    <td className="px-4 py-3 text-sm break-words">{g.message}</td>
                    <td className="px-4 py-3 text-sm text-gray-500 whitespace-nowrap">{timeAgo(g.last_seen)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>
      )}
    </div>
  );
}

function Card({ label, value, color }: { label: string; value: number; color: string }) {
  return (
    <div className="bg-gray-800 p-4 rounded-xl">
      <div className={`text-2xl font-bold ${color}`}>{value}</div>
      <div className="text-sm text-gray-300 mt-0.5">{label}</div>
    </div>
  );
}

function LevelBadge({ level }: { level: string }) {
  const map: Record<string, string> = {
    fatal: "bg-rose-600/30 text-rose-300",
    error: "bg-rose-500/20 text-rose-400",
    warn: "bg-amber-500/20 text-amber-400",
  };
  return <span className={`text-xs px-1.5 py-0.5 rounded font-medium ${map[level] || "bg-gray-700 text-gray-400"}`}>{level}</span>;
}

function timeAgo(iso: string) {
  const diff = Date.now() - new Date(iso).getTime();
  const m = Math.floor(diff / 60000);
  if (m < 1) return "just now";
  if (m < 60) return `${m}m ago`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h}h ago`;
  return `${Math.floor(h / 24)}d ago`;
}
