"use client";

import { useState, useEffect, useCallback } from "react";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Skeleton } from "@/components/ui/skeleton";
import {
  getArchivingRules,
  createArchivingRule,
  updateArchivingRule,
  deleteArchivingRule,
  getTenants,
  type ArchivingRule,
  type ArchivingRuleInput,
  type RuleConditionType,
  type Tenant,
} from "@/lib/api";

const COND_LABELS: Record<RuleConditionType, string> = {
  sender_domain: "Absender-Domain",
  recipient_domain: "Empfänger-Domain",
  sender_address: "Absender-Adresse",
  recipient_address: "Empfänger-Adresse",
};

// PROJ-51 retention suggestion values.
const RETENTION_PRESETS = [
  { days: 2190, label: "6 Jahre (Handels-/Geschäftsbriefe)" },
  { days: 3650, label: "10 Jahre (Rechnungen, Belege)" },
  { days: 36500, label: "Dauerhaft (100 Jahre)" },
];

function retentionLabel(days: number | null): React.ReactNode {
  if (days === null) {
    return <Badge variant="secondary">kein Regel-Wert</Badge>;
  }
  if (days >= 36500) {
    return <Badge>Dauerhaft</Badge>;
  }
  return <Badge>{days} Tage ({(days / 365).toFixed(1)} Jahre)</Badge>;
}

interface EditState {
  id: number | null; // null = create
  tenant_id: string; // "" = alle Mandanten
  condition_type: RuleConditionType;
  pattern: string;
  priority: string;
  retention_days: string; // "" = kein Regel-Wert
}

const EMPTY_EDIT: EditState = {
  id: null,
  tenant_id: "",
  condition_type: "sender_domain",
  pattern: "",
  priority: "0",
  retention_days: "",
};

export function ArchivingRulesTab() {
  const [rules, setRules] = useState<ArchivingRule[]>([]);
  const [minRetentionDays, setMinRetentionDays] = useState(0);
  const [tenants, setTenants] = useState<Tenant[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const [edit, setEdit] = useState<EditState | null>(null);
  const [saving, setSaving] = useState(false);
  const [formError, setFormError] = useState("");

  const [deleteRule, setDeleteRule] = useState<ArchivingRule | null>(null);
  const [deleting, setDeleting] = useState(false);

  const load = useCallback(() => {
    setLoading(true);
    setError("");
    Promise.all([getArchivingRules(), getTenants()])
      .then(([data, ts]) => {
        setRules(data.rules);
        setMinRetentionDays(data.min_retention_days);
        setTenants(ts);
      })
      .catch(() => setError("Archivierungsregeln konnten nicht geladen werden"))
      .finally(() => setLoading(false));
  }, []);

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

  const tenantName = (id: number | null): React.ReactNode => {
    if (id === null) return <span className="text-muted-foreground">Alle Mandanten</span>;
    const t = tenants.find((x) => x.id === id);
    return t ? t.name : `#${id}`;
  };

  const openCreate = () => {
    setEdit({ ...EMPTY_EDIT });
    setFormError("");
  };

  const openEdit = (r: ArchivingRule) => {
    setEdit({
      id: r.id,
      tenant_id: r.tenant_id === null ? "" : String(r.tenant_id),
      condition_type: r.condition_type,
      pattern: r.pattern,
      priority: String(r.priority),
      retention_days: r.retention_days === null ? "" : String(r.retention_days),
    });
    setFormError("");
  };

  const handleSave = async () => {
    if (!edit) return;
    const pattern = edit.pattern.trim();
    if (!pattern) {
      setFormError("Muster darf nicht leer sein");
      return;
    }
    const priority = parseInt(edit.priority, 10);
    if (isNaN(priority)) {
      setFormError("Priorität muss eine Zahl sein");
      return;
    }
    let retention_days: number | null = null;
    if (edit.retention_days.trim() !== "") {
      retention_days = parseInt(edit.retention_days, 10);
      if (isNaN(retention_days) || retention_days < 0) {
        setFormError("Aufbewahrung muss eine positive Zahl sein");
        return;
      }
    }
    const input: ArchivingRuleInput = {
      tenant_id: edit.tenant_id === "" ? null : parseInt(edit.tenant_id, 10),
      condition_type: edit.condition_type,
      pattern,
      priority,
      retention_days,
    };
    setSaving(true);
    setFormError("");
    try {
      if (edit.id === null) {
        await createArchivingRule(input);
      } else {
        await updateArchivingRule(edit.id, input);
      }
      setEdit(null);
      load();
    } catch (e: unknown) {
      setFormError(e instanceof Error ? e.message : "Speichern fehlgeschlagen");
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async () => {
    if (!deleteRule) return;
    setDeleting(true);
    try {
      await deleteArchivingRule(deleteRule.id);
      setDeleteRule(null);
      load();
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : "Löschen fehlgeschlagen");
      setDeleteRule(null);
    } finally {
      setDeleting(false);
    }
  };

  return (
    <div className="mt-4 space-y-4">
      <Card>
        <CardHeader>
          <CardTitle>Globale Mindest-Aufbewahrungsfrist</CardTitle>
          <CardDescription>
            Gilt systemweit als unterste Grenze. Regeln und Mandanten-Einstellungen dürfen die
            Frist nur verlängern, nie verkürzen. Konfiguration über{" "}
            <code className="text-xs">storage.min_retention_days</code> in der{" "}
            <code className="text-xs">config.yml</code>.
          </CardDescription>
        </CardHeader>
        <CardContent>
          {loading ? (
            <Skeleton className="h-6 w-48" />
          ) : minRetentionDays > 0 ? (
            <Badge>
              {minRetentionDays} Tage ({(minRetentionDays / 365).toFixed(1)} Jahre)
            </Badge>
          ) : (
            <Badge variant="secondary">Keine Mindestfrist (0)</Badge>
          )}
        </CardContent>
      </Card>

      <Card>
        <CardHeader className="flex flex-row items-center justify-between gap-2">
          <div>
            <CardTitle>Archivierungsregeln</CardTitle>
            <CardDescription>
              Regeln mit Aufbewahrungsfrist bestimmen bei Treffer die Mindestaufbewahrung einer
              Mail (höchste Priorität gewinnt).
            </CardDescription>
          </div>
          <Button size="sm" onClick={openCreate}>
            Regel hinzufügen
          </Button>
        </CardHeader>
        <CardContent>
          {error && <p className="mb-3 text-sm text-destructive">{error}</p>}
          {loading ? (
            <div className="space-y-2">
              <Skeleton className="h-10 w-full" />
              <Skeleton className="h-10 w-full" />
            </div>
          ) : rules.length === 0 ? (
            <p className="py-6 text-center text-sm text-muted-foreground">
              Noch keine Archivierungsregeln definiert.
            </p>
          ) : (
            <div className="overflow-x-auto">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead className="w-16">Prio</TableHead>
                    <TableHead>Bedingung</TableHead>
                    <TableHead>Muster</TableHead>
                    <TableHead>Mandant</TableHead>
                    <TableHead>Aufbewahrung</TableHead>
                    <TableHead className="w-32"></TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {rules.map((r) => (
                    <TableRow key={r.id}>
                      <TableCell>{r.priority}</TableCell>
                      <TableCell>{COND_LABELS[r.condition_type] ?? r.condition_type}</TableCell>
                      <TableCell className="font-mono text-xs break-all">{r.pattern}</TableCell>
                      <TableCell>{tenantName(r.tenant_id)}</TableCell>
                      <TableCell>{retentionLabel(r.retention_days)}</TableCell>
                      <TableCell>
                        <div className="flex gap-1">
                          <Button size="sm" variant="outline" onClick={() => openEdit(r)}>
                            Bearbeiten
                          </Button>
                          <Button
                            size="sm"
                            variant="ghost"
                            className="text-destructive"
                            onClick={() => setDeleteRule(r)}
                          >
                            Löschen
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          )}
        </CardContent>
      </Card>

      {/* Create / Edit Dialog */}
      <Dialog open={!!edit} onOpenChange={(o) => { if (!o) setEdit(null); }}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              {edit?.id === null ? "Regel hinzufügen" : "Regel bearbeiten"}
            </DialogTitle>
            <DialogDescription>
              Legt fest, welche Mails von dieser Regel erfasst werden und – optional – wie lange
              sie aufbewahrt werden.
            </DialogDescription>
          </DialogHeader>

          {edit && (
            <div className="space-y-4 py-2">
              <div className="space-y-2">
                <Label>Bedingungstyp</Label>
                <Select
                  value={edit.condition_type}
                  onValueChange={(v) =>
                    setEdit({ ...edit, condition_type: v as RuleConditionType })
                  }
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {(Object.keys(COND_LABELS) as RuleConditionType[]).map((k) => (
                      <SelectItem key={k} value={k}>
                        {COND_LABELS[k]}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-2">
                <Label htmlFor="rule-pattern">Muster</Label>
                <Input
                  id="rule-pattern"
                  placeholder="z.B. firma.de oder rechnung@firma.de"
                  value={edit.pattern}
                  onChange={(e) => setEdit({ ...edit, pattern: e.target.value })}
                />
              </div>

              <div className="space-y-2">
                <Label>Mandant</Label>
                <Select
                  value={edit.tenant_id === "" ? "__all__" : edit.tenant_id}
                  onValueChange={(v) =>
                    setEdit({ ...edit, tenant_id: v === "__all__" ? "" : v })
                  }
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="__all__">Alle Mandanten</SelectItem>
                    {tenants.map((t) => (
                      <SelectItem key={t.id} value={String(t.id)}>
                        {t.name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-2">
                <Label htmlFor="rule-priority">Priorität</Label>
                <Input
                  id="rule-priority"
                  type="number"
                  value={edit.priority}
                  onChange={(e) => setEdit({ ...edit, priority: e.target.value })}
                />
                <p className="text-xs text-muted-foreground">
                  Höher = wird zuerst geprüft. Bei mehreren Treffern gewinnt die höchste Priorität.
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="rule-retention">Aufbewahrung (Tage)</Label>
                <Input
                  id="rule-retention"
                  type="number"
                  min={0}
                  placeholder="leer = kein Regel-spezifischer Wert"
                  value={edit.retention_days}
                  onChange={(e) => setEdit({ ...edit, retention_days: e.target.value })}
                />
                <div className="flex flex-wrap gap-1">
                  {RETENTION_PRESETS.map((p) => (
                    <Button
                      key={p.days}
                      type="button"
                      size="sm"
                      variant="outline"
                      onClick={() => setEdit({ ...edit, retention_days: String(p.days) })}
                    >
                      {p.label}
                    </Button>
                  ))}
                </div>
                {edit.retention_days.trim() !== "" &&
                  parseInt(edit.retention_days, 10) > 0 && (
                    <p className="text-xs text-muted-foreground">
                      ≈ {(parseInt(edit.retention_days, 10) / 365).toFixed(1)} Jahre
                      {minRetentionDays > 0 &&
                        parseInt(edit.retention_days, 10) < minRetentionDays && (
                          <span className="text-amber-600">
                            {" "}
                            – wird durch globale Mindestfrist ({minRetentionDays} Tage) angehoben
                          </span>
                        )}
                    </p>
                  )}
                <p className="text-xs text-muted-foreground">
                  Leer = diese Regel setzt keine eigene Frist (Mandanten-/globaler Standard gilt).
                </p>
              </div>

              {formError && <p className="text-sm text-destructive">{formError}</p>}
            </div>
          )}

          <DialogFooter>
            <Button variant="outline" onClick={() => setEdit(null)}>
              Abbrechen
            </Button>
            <Button disabled={saving} onClick={handleSave}>
              {saving ? "Speichern..." : "Speichern"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete Dialog */}
      <Dialog open={!!deleteRule} onOpenChange={(o) => { if (!o) setDeleteRule(null); }}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Regel löschen</DialogTitle>
            <DialogDescription>
              Die Regel wird gelöscht. Bereits gesetzte Aufbewahrungsfristen bestehender Mails
              bleiben unverändert.
            </DialogDescription>
          </DialogHeader>
          {deleteRule && (
            <p className="py-2 text-sm">
              <span className="font-mono">{deleteRule.pattern}</span> (
              {COND_LABELS[deleteRule.condition_type]})
            </p>
          )}
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleteRule(null)}>
              Abbrechen
            </Button>
            <Button variant="destructive" disabled={deleting} onClick={handleDelete}>
              {deleting ? "Lösche..." : "Löschen"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
