"use client";

import { useState, useEffect, useCallback } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";

interface ExpiredMail {
  id: string;
  from: string;
  subject: string;
  received_at: string;
  retain_until: string;
  marked: boolean;
  marked_by?: string;
}

async function fetchExpiredMails(): Promise<ExpiredMail[]> {
  const res = await fetch("/api/admin/retention/expired", { credentials: "include" });
  if (!res.ok) throw new Error("Fehler beim Laden");
  const data = await res.json();
  return data.mails ?? [];
}

async function setMarkedForDeletion(id: string, marked: boolean): Promise<void> {
  const res = await fetch(`/api/admin/mails/${id}/mark-deletion`, {
    method: "PUT",
    credentials: "include",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ marked }),
  });
  if (!res.ok) throw new Error("Markierung fehlgeschlagen");
}

function formatDateTime(iso: string): string {
  try {
    return new Date(iso).toLocaleString("de-DE", {
      day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit",
    });
  } catch {
    return iso;
  }
}

interface TenantRetention {
  id: number;
  name: string;
  slug: string;
  retention_days: number;
}

interface RetentionData {
  global_retention_days: number;
  tenants: TenantRetention[];
}

async function fetchRetention(): Promise<RetentionData> {
  const res = await fetch("/api/admin/retention", { credentials: "include" });
  if (!res.ok) throw new Error("Fehler beim Laden");
  return res.json();
}

async function setTenantRetention(tenantID: number, days: number): Promise<void> {
  const res = await fetch(`/api/admin/tenant/${tenantID}/retention`, {
    method: "PUT",
    credentials: "include",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ retention_days: days }),
  });
  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error((err as { error?: string }).error ?? "Fehler beim Speichern");
  }
}

async function triggerPurge(): Promise<number> {
  const res = await fetch("/api/admin/purge", {
    method: "POST",
    credentials: "include",
  });
  if (!res.ok) throw new Error("Purge fehlgeschlagen");
  const data = await res.json();
  return data.deleted ?? 0;
}

function retentionLabel(days: number): React.ReactNode {
  if (days === 0) {
    return <Badge variant="secondary">Kein Lock (manuell setzen)</Badge>;
  }
  return <Badge>{days} Tage ({(days / 365).toFixed(1)} Jahre)</Badge>;
}

export function RetentionTab() {
  const [data, setData] = useState<RetentionData | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  // edit state
  const [editTenant, setEditTenant] = useState<TenantRetention | null>(null);
  const [editDays, setEditDays] = useState("");
  const [saving, setSaving] = useState(false);

  // purge state
  const [purgeOpen, setPurgeOpen] = useState(false);
  const [purging, setPurging] = useState(false);
  const [purgeResult, setPurgeResult] = useState<number | null>(null);

  // PROJ-56c: expired-mails review + mark-for-deletion state
  const [expired, setExpired] = useState<ExpiredMail[]>([]);
  const [expiredLoading, setExpiredLoading] = useState(true);
  const [markingID, setMarkingID] = useState<string | null>(null);

  const load = useCallback(() => {
    setLoading(true);
    fetchRetention()
      .then(setData)
      .catch(() => setError("Retention-Daten konnten nicht geladen werden"))
      .finally(() => setLoading(false));
  }, []);

  const loadExpired = useCallback(() => {
    setExpiredLoading(true);
    fetchExpiredMails()
      .then(setExpired)
      .catch(() => setError("Abgelaufene Mails konnten nicht geladen werden"))
      .finally(() => setExpiredLoading(false));
  }, []);

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

  const handleToggleMark = async (mail: ExpiredMail) => {
    setMarkingID(mail.id);
    try {
      await setMarkedForDeletion(mail.id, !mail.marked);
      setExpired((prev) =>
        prev.map((m) => (m.id === mail.id ? { ...m, marked: !mail.marked } : m))
      );
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : "Markierung fehlgeschlagen");
    } finally {
      setMarkingID(null);
    }
  };

  const handleEditOpen = (t: TenantRetention) => {
    setEditTenant(t);
    setEditDays(t.retention_days > 0 ? String(t.retention_days) : "");
    setSaving(false);
  };

  const handleEditSave = async () => {
    if (!editTenant) return;
    const days = editDays.trim() === "" ? 0 : parseInt(editDays, 10);
    if (isNaN(days) || days < 0) return;
    setSaving(true);
    try {
      await setTenantRetention(editTenant.id, days);
      setEditTenant(null);
      load();
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : "Fehler");
    } finally {
      setSaving(false);
    }
  };

  const handlePurge = async () => {
    setPurging(true);
    setPurgeResult(null);
    try {
      const deleted = await triggerPurge();
      setPurgeResult(deleted);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : "Purge fehlgeschlagen");
      setPurgeOpen(false);
    } finally {
      setPurging(false);
    }
  };

  return (
    <div className="mt-4 space-y-4">
      {/* Global Policy */}
      <Card>
        <CardHeader>
          <CardTitle>Globale Retention-Policy</CardTitle>
        </CardHeader>
        <CardContent className="space-y-3">
          <div className="flex items-center gap-3">
            <span className="text-sm font-medium">Globale Aufbewahrungsfrist:</span>
            {(data?.global_retention_days ?? 0) > 0 ? (
              <Badge>{data!.global_retention_days} Tage ({Math.round(data!.global_retention_days / 365)} Jahre)</Badge>
            ) : (
              <Badge variant="secondary">Kein globaler Lock (config.yml)</Badge>
            )}
          </div>
          <p className="text-sm text-muted-foreground">
            Die globale Frist gilt nur für Mails ohne Mandant-Zuordnung (Systemkonten).
            <strong className="text-foreground"> Für Mandanten greift ausschließlich die individuelle Einstellung</strong> —
            solange ein Mandant keine eigene Frist gesetzt hat (0 Tage), werden seine Mails nie automatisch gelöscht.
          </p>
          <Button
            variant="destructive"
            size="sm"
            onClick={() => { setPurgeOpen(true); setPurgeResult(null); }}
          >
            Abgelaufene Mails jetzt löschen (Purge)
          </Button>
          {error && <p className="text-sm text-destructive">{error}</p>}
        </CardContent>
      </Card>

      {/* PROJ-56c: expired mails — review + mark for deletion */}
      <Card>
        <CardHeader>
          <CardTitle>Abgelaufene Mails — zur Löschung markieren</CardTitle>
        </CardHeader>
        <CardContent className="space-y-3">
          <p className="text-sm text-muted-foreground">
            Diese Mails haben ihre Aufbewahrungsfrist überschritten. Der automatische
            nächtliche Purge-Job löscht <strong className="text-foreground">ausschließlich</strong> Mails,
            die hier explizit markiert wurden — ein abgelaufenes Datum allein reicht nicht.
            Der Button &quot;Jetzt löschen&quot; oben löscht dagegen sofort alle abgelaufenen Mails, unabhängig von der Markierung.
          </p>
          {expiredLoading ? (
            <p className="text-sm text-muted-foreground">Lädt...</p>
          ) : expired.length === 0 ? (
            <p className="text-sm text-muted-foreground">Keine abgelaufenen Mails.</p>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-10"></TableHead>
                  <TableHead>Von</TableHead>
                  <TableHead>Betreff</TableHead>
                  <TableHead>Abgelaufen seit</TableHead>
                  <TableHead>Markiert von</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {expired.map((m) => (
                  <TableRow key={m.id}>
                    <TableCell>
                      <Checkbox
                        checked={m.marked}
                        disabled={markingID === m.id}
                        onCheckedChange={() => handleToggleMark(m)}
                      />
                    </TableCell>
                    <TableCell className="max-w-[16rem] truncate">{m.from || "–"}</TableCell>
                    <TableCell className="max-w-[20rem] truncate">{m.subject || "(kein Betreff)"}</TableCell>
                    <TableCell>{formatDateTime(m.retain_until)}</TableCell>
                    <TableCell>{m.marked ? (m.marked_by || "–") : "–"}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>

      {/* Per-tenant table */}
      <Card>
        <CardHeader>
          <CardTitle>Retention pro Mandant</CardTitle>
        </CardHeader>
        <CardContent>
          {loading ? (
            <p className="text-sm text-muted-foreground">Lädt...</p>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Mandant</TableHead>
                  <TableHead>Aufbewahrungsfrist</TableHead>
                  <TableHead className="w-24"></TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {(data?.tenants ?? []).map((t) => (
                  <TableRow key={t.id}>
                    <TableCell className="font-medium">{t.name}</TableCell>
                    <TableCell>{retentionLabel(t.retention_days)}</TableCell>
                    <TableCell>
                      <Button size="sm" variant="outline" onClick={() => handleEditOpen(t)}>
                        Bearbeiten
                      </Button>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>

      {/* Edit Dialog */}
      <Dialog open={!!editTenant} onOpenChange={(o) => { if (!o) setEditTenant(null); }}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Retention für &quot;{editTenant?.name}&quot;</DialogTitle>
            <DialogDescription>
              Aufbewahrungsfrist in Tagen. <strong>0</strong> = globale Einstellung verwenden.
              GoBD: mind. 10 Jahre = 3650 Tage.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-2 py-2">
            <label className="text-sm font-medium">Aufbewahrung (Tage)</label>
            <Input
              type="number"
              min={0}
              placeholder="0 = globale Einstellung"
              value={editDays}
              onChange={(e) => setEditDays(e.target.value)}
            />
            {editDays && parseInt(editDays) > 0 && (
              <p className="text-xs text-muted-foreground">
                ≈ {(parseInt(editDays) / 365).toFixed(1)} Jahre
              </p>
            )}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setEditTenant(null)}>
              Abbrechen
            </Button>
            <Button disabled={saving} onClick={handleEditSave}>
              {saving ? "Speichern..." : "Speichern"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Purge Dialog */}
      <Dialog open={purgeOpen} onOpenChange={setPurgeOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Abgelaufene Mails löschen</DialogTitle>
            <DialogDescription>
              Alle Mails, deren Aufbewahrungsfrist abgelaufen ist, werden unwiderruflich gelöscht.
              Mails innerhalb der Frist bleiben erhalten.
            </DialogDescription>
          </DialogHeader>
          {purgeResult !== null ? (
            <p className="text-sm font-medium py-2">
              {purgeResult === 0
                ? "Keine abgelaufenen Mails gefunden."
                : `${purgeResult} Mail(s) erfolgreich gelöscht.`}
            </p>
          ) : (
            <p className="text-sm text-muted-foreground py-2">
              Dieser Vorgang kann nicht rückgängig gemacht werden.
            </p>
          )}
          <DialogFooter>
            <Button variant="outline" onClick={() => setPurgeOpen(false)}>
              {purgeResult !== null ? "Schließen" : "Abbrechen"}
            </Button>
            {purgeResult === null && (
              <Button variant="destructive" disabled={purging} onClick={handlePurge}>
                {purging ? "Lösche..." : "Jetzt löschen"}
              </Button>
            )}
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
