import { Fragment, useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import toast from 'react-hot-toast';
import { ChevronDown, ChevronRight, Trash2, Search } from 'lucide-react';
import { api } from '../../lib/api-client';
import { AppShell, PageHeader, PageBody } from '../../layout/AppShell';
import { Badge, Button, Card, Input, Select } from '../../components/ui/primitives';
import { Table, THead, TBody, TR, TH, TD } from '../../components/ui/table';

interface ErrorEntry {
  id: number;
  source: string;
  severity: string;
  message: string;
  stack: string | null;
  context: unknown;
  actor_email: string | null;
  request_path: string | null;
  created_at: string;
}

const SEVERITY_VARIANTS: Record<string, 'danger' | 'warn' | 'info'> = {
  fatal: 'danger',
  error: 'danger',
  warn: 'warn',
  warning: 'warn',
  info: 'info',
};

export function ErrorLog() {
  const qc = useQueryClient();
  const [filters, setFilters] = useState({ source: '', severity: '', q: '' });
  const [expanded, setExpanded] = useState<Set<number>>(new Set());

  const { data } = useQuery({
    queryKey: ['errors', filters],
    queryFn: () =>
      api.get<{ entries: ErrorEntry[]; sources: string[] }>('/errors', {
        source: filters.source || undefined,
        severity: filters.severity || undefined,
        q: filters.q || undefined,
        limit: 200,
      }),
    refetchInterval: 30000,
  });

  const purgeMut = useMutation({
    mutationFn: () => api.delete<{ purged: number }>('/errors'),
    onSuccess: (res) => {
      toast.success(`${res.purged} oude entries verwijderd`);
      qc.invalidateQueries({ queryKey: ['errors'] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const entries = data?.entries ?? [];
  const sources = data?.sources ?? [];

  const toggle = (id: number) => {
    const next = new Set(expanded);
    if (next.has(id)) next.delete(id);
    else next.add(id);
    setExpanded(next);
  };

  return (
    <AppShell>
      <PageHeader
        title="Error log"
        description="Runtime errors uit CMS API's en achtergrondjobs."
        actions={
          <Button
            size="sm"
            variant="ghost"
            onClick={() => {
              if (confirm('Alle entries ouder dan 30 dagen verwijderen?')) purgeMut.mutate();
            }}
          >
            <Trash2 className="h-4 w-4" />
            Oude entries wissen
          </Button>
        }
      />
      <PageBody>
        <Card className="mb-4">
          <div className="px-5 py-3 grid grid-cols-4 gap-3">
            <div className="relative">
              <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-[#666]" />
              <Input
                className="pl-9"
                placeholder="Zoek in message/stack..."
                value={filters.q}
                onChange={(e) => setFilters({ ...filters, q: e.target.value })}
              />
            </div>
            <Select value={filters.source} onChange={(e) => setFilters({ ...filters, source: e.target.value })}>
              <option value="">Alle bronnen</option>
              {sources.map((s) => (
                <option key={s} value={s}>
                  {s}
                </option>
              ))}
            </Select>
            <Select value={filters.severity} onChange={(e) => setFilters({ ...filters, severity: e.target.value })}>
              <option value="">Alle severity</option>
              <option value="fatal">Fatal</option>
              <option value="error">Error</option>
              <option value="warn">Warn</option>
              <option value="info">Info</option>
            </Select>
            <div className="text-xs text-[#666] self-center">Auto-refresh 30s</div>
          </div>
        </Card>

        <Card>
          <Table>
            <THead>
              <TR className="hover:bg-transparent">
                <TH className="w-8"></TH>
                <TH>Tijd</TH>
                <TH>Source</TH>
                <TH>Severity</TH>
                <TH>Bericht</TH>
                <TH>Path</TH>
              </TR>
            </THead>
            <TBody>
              {entries.map((e) => {
                const isOpen = expanded.has(e.id);
                return (
                  <Fragment key={e.id}>
                    <TR onClick={() => toggle(e.id)} className="cursor-pointer">
                      <TD>
                        {isOpen ? (
                          <ChevronDown className="h-4 w-4 text-[#666]" />
                        ) : (
                          <ChevronRight className="h-4 w-4 text-[#666]" />
                        )}
                      </TD>
                      <TD className="text-xs text-[#999] font-mono whitespace-nowrap">
                        {new Date(e.created_at).toLocaleString('nl-NL')}
                      </TD>
                      <TD className="text-xs font-mono">{e.source}</TD>
                      <TD>
                        <Badge variant={SEVERITY_VARIANTS[e.severity] ?? 'muted'}>{e.severity}</Badge>
                      </TD>
                      <TD className="text-xs truncate max-w-md">{e.message}</TD>
                      <TD className="font-mono text-xs text-[#666]">{e.request_path ?? '—'}</TD>
                    </TR>
                    {isOpen && (
                      <TR className="hover:bg-transparent">
                        <TD colSpan={6} className="bg-[#0A0A0A]">
                          <div className="p-4 space-y-3">
                            <div>
                              <h4 className="text-xs text-[#999] mb-1">Bericht</h4>
                              <p className="text-sm font-mono text-[#F5F5F5] whitespace-pre-wrap">{e.message}</p>
                            </div>
                            {e.stack && (
                              <div>
                                <h4 className="text-xs text-[#999] mb-1">Stack</h4>
                                <pre className="text-xs font-mono text-[#999] bg-[#141414] border border-[#333] rounded p-3 overflow-x-auto max-h-80">
                                  {e.stack}
                                </pre>
                              </div>
                            )}
                            {e.context != null && (
                              <div>
                                <h4 className="text-xs text-[#999] mb-1">Context</h4>
                                <pre className="text-xs font-mono text-[#999] bg-[#141414] border border-[#333] rounded p-3 overflow-x-auto">
                                  {JSON.stringify(e.context, null, 2)}
                                </pre>
                              </div>
                            )}
                          </div>
                        </TD>
                      </TR>
                    )}
                  </Fragment>
                );
              })}
            </TBody>
          </Table>
          {entries.length === 0 && (
            <div className="p-10 text-center text-sm text-[#666]">Geen errors — lekker rustig.</div>
          )}
        </Card>
      </PageBody>
    </AppShell>
  );
}
