"use client";

import { useCallback, useEffect, useState } from "react";
import {
  exportReconciliationCSV,
  getReconciliation,
  type ReconciliationResponse,
  type ReconciliationSource,
} from "@/lib/api";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import { Separator } from "@/components/ui/separator";
import { Alert, AlertDescription } from "@/components/ui/alert";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";

/** Formatiert einen source_key zu einem lesbaren Label. */
function formatSourceLabel(source: ReconciliationSource): string {
  switch (source.source_type) {
    case "smtp":
      return "SMTP-Journal";
    case "import":
      return "Datei-Import";
    case "imap":
      return `IMAP-Konto #${source.source_id ?? "?"}`;
    case "pop3":
      return `POP3-Konto #${source.source_id ?? "?"}`;
    default:
      return source.source_key;
  }
}

function formatDayLabel(iso: string): string {
  const d = new Date(iso);
  return d.toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit" });
}

/** Zellinhalt für einen Tagespunkt: "—" bei fehlendem Datensatz, sonst Werte. */
function DayCell({
  archived,
  expected,
  delta,
  missing,
  isImap,
}: {
  archived: number | null;
  expected: number | null;
  delta: number | null;
  missing: boolean;
  isImap: boolean;
}) {
  if (missing) {
    return (
      <span
        className="text-muted-foreground"
        title="Kein Report-Datensatz für diesen Tag (Cron nicht gelaufen)"
      >
        —
      </span>
    );
  }
  return (
    <span className="inline-flex flex-col items-end leading-tight">
      <span className="font-medium tabular-nums">
        {(archived ?? 0).toLocaleString("de-DE")}
      </span>
      {isImap && expected != null && (
        <span className="text-[10px] text-muted-foreground tabular-nums">
          Soll {expected.toLocaleString("de-DE")}
          {delta != null && (
            <span
              className={
                delta < 0 ? "ml-1 text-destructive" : "ml-1 text-green-600"
              }
            >
              ({delta > 0 ? "+" : ""}
              {delta.toLocaleString("de-DE")})
            </span>
          )}
        </span>
      )}
    </span>
  );
}

export function ReconciliationCard() {
  const [data, setData] = useState<ReconciliationResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [exporting, setExporting] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await getReconciliation(7);
      setData(res);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : "Laden fehlgeschlagen");
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void load();
  }, [load]);

  const handleExport = async () => {
    setExporting(true);
    try {
      const { blob, filename } = await exportReconciliationCSV(30);
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      a.remove();
      URL.revokeObjectURL(url);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : "Export fehlgeschlagen");
    } finally {
      setExporting(false);
    }
  };

  // Tages-Header aus dem ersten Quell-Eintrag ableiten (alle Quellen haben
  // dieselben Tage in gleicher Reihenfolge).
  const dayHeaders = data?.sources[0]?.points.map((p) => p.date) ?? [];

  return (
    <Card>
      <CardContent className="pt-6 space-y-3">
        <div className="flex items-center justify-between gap-3">
          <div className="flex items-center gap-2">
            <span className="text-sm font-medium text-muted-foreground">
              Vollständigkeits-Check
            </span>
            {data && (
              <span className="text-xs text-muted-foreground">
                letzte {data.days} Tage · Schwelle {data.threshold_pct}%
              </span>
            )}
          </div>
          <div className="flex items-center gap-2">
            <Button
              variant="outline"
              size="sm"
              onClick={load}
              disabled={loading}
            >
              {loading ? "..." : "Aktualisieren"}
            </Button>
            <Button
              variant="outline"
              size="sm"
              onClick={handleExport}
              disabled={exporting}
            >
              {exporting ? "Export..." : "CSV-Export (30 Tage)"}
            </Button>
          </div>
        </div>
        <Separator />

        {loading ? (
          <div className="space-y-2">
            {Array.from({ length: 3 }).map((_, i) => (
              <Skeleton key={i} className="h-8 w-full" />
            ))}
          </div>
        ) : error ? (
          <Alert variant="destructive">
            <AlertDescription>
              Vollständigkeits-Report konnte nicht geladen werden: {error}
            </AlertDescription>
          </Alert>
        ) : !data || data.sources.length === 0 ? (
          <p className="text-sm text-muted-foreground">
            Noch keine Reconciliation-Daten vorhanden. Der tägliche Zähl-Job
            (<code className="font-mono">archivmail reconcile</code>) hat noch
            keine Datensätze erzeugt.
          </p>
        ) : (
          <div className="overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="whitespace-nowrap">Quelle</TableHead>
                  {dayHeaders.map((d) => (
                    <TableHead
                      key={d}
                      className="text-right whitespace-nowrap"
                    >
                      {formatDayLabel(d)}
                    </TableHead>
                  ))}
                  <TableHead className="text-right whitespace-nowrap">
                    Ø 7 Tage
                  </TableHead>
                  <TableHead className="text-right whitespace-nowrap">
                    Status
                  </TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {data.sources.map((s) => {
                  const isImap = s.source_type === "imap";
                  return (
                    <TableRow key={s.source_key}>
                      <TableCell className="font-medium whitespace-nowrap">
                        {formatSourceLabel(s)}
                      </TableCell>
                      {!s.enough_data ? (
                        <TableCell
                          colSpan={dayHeaders.length + 1}
                          className="text-center text-sm text-muted-foreground"
                        >
                          Noch nicht genug Daten
                        </TableCell>
                      ) : (
                        <>
                          {s.points.map((p) => (
                            <TableCell key={p.date} className="text-right">
                              <DayCell
                                archived={p.archived_count}
                                expected={p.expected_count}
                                delta={p.delta}
                                missing={p.missing}
                                isImap={isImap}
                              />
                            </TableCell>
                          ))}
                          <TableCell className="text-right tabular-nums text-muted-foreground">
                            {s.avg_7d != null
                              ? s.avg_7d.toLocaleString("de-DE", {
                                  maximumFractionDigits: 1,
                                })
                              : "—"}
                          </TableCell>
                        </>
                      )}
                      <TableCell className="text-right">
                        {s.alert ? (
                          <Badge variant="destructive">Auffällig</Badge>
                        ) : s.enough_data ? (
                          <Badge variant="secondary">OK</Badge>
                        ) : (
                          <Badge variant="outline">—</Badge>
                        )}
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          </div>
        )}
      </CardContent>
    </Card>
  );
}
