"use client";

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { ColumnDef, flexRender, getCoreRowModel, getSortedRowModel, SortingState, useReactTable } from "@tanstack/react-table";
import { Copy, Download, Edit2, Eye, FilePlus2, GitBranchPlus, Search, Trash2, XCircle } from "lucide-react";
import Link from "next/link";
import { useEffect, useMemo, useState } from "react";
import { useAuth } from "@/components/auth";
import { API_BASE, apiDelete, apiGet, apiSend, Customer, Device, Paginated, ValidationItem } from "@/lib/api";

const statusLabels: Record<string, string> = {
  ENTWURF: "Entwurf",
  BEREIT_ZUR_PRUEFUNG: "Bereit zur Pruefung",
  IN_PRUEFUNG: "In Pruefung",
  FREIGEGEBEN: "Freigegeben",
  ABGESCHLOSSEN: "Abgeschlossen",
  STORNIERT: "Storniert"
};

const statusClass: Record<string, string> = {
  ENTWURF: "bg-border text-text-light",
  BEREIT_ZUR_PRUEFUNG: "bg-accent/35 text-primary-dark",
  IN_PRUEFUNG: "bg-warning/15 text-warning",
  FREIGEGEBEN: "bg-success/15 text-success",
  ABGESCHLOSSEN: "bg-primary-dark/15 text-primary-dark",
  STORNIERT: "bg-danger/15 text-danger"
};

export default function ValidationsPage() {
  const { token } = useAuth();
  const client = useQueryClient();
  const [page, setPage] = useState(1);
  const [search, setSearch] = useState("");
  const [status, setStatus] = useState("");
  const [customerId, setCustomerId] = useState("");
  const [deviceId, setDeviceId] = useState("");
  const [validationType, setValidationType] = useState("");
  const [result, setResult] = useState("");
  const [dateFrom, setDateFrom] = useState("");
  const [dateTo, setDateTo] = useState("");
  const [overdueOnly, setOverdueOnly] = useState(false);
  const [sorting, setSorting] = useState<SortingState>([{ id: "updated_at", desc: true }]);
  const pageSize = 10;
  const sort = sorting[0] ?? { id: "updated_at", desc: true };

  useEffect(() => {
    const initial = new URLSearchParams(window.location.search);
    setStatus(initial.get("status") ?? "");
    setOverdueOnly(initial.get("overdue_only") === "true");
  }, []);
  const params = new URLSearchParams({
    page: String(page),
    page_size: String(pageSize),
    sort_by: sort.id,
    sort_order: sort.desc ? "desc" : "asc"
  });
  if (search) params.set("search", search);
  if (status) params.set("status", status);
  if (customerId) params.set("customer_id", customerId);
  if (deviceId) params.set("device_id", deviceId);
  if (validationType) params.set("validation_type", validationType);
  if (result) params.set("result", result);
  if (dateFrom) params.set("date_from", dateFrom);
  if (dateTo) params.set("date_to", dateTo);
  if (overdueOnly) params.set("overdue_only", "true");

  const validations = useQuery({
    queryKey: ["validations", params.toString(), token],
    queryFn: () => apiGet<Paginated<ValidationItem>>(`/validations?${params.toString()}`, token ?? ""),
    enabled: Boolean(token)
  });
  const customers = useQuery({ queryKey: ["customers-options", token], queryFn: () => apiGet<Paginated<Customer>>("/customers?page=1&page_size=100", token ?? ""), enabled: Boolean(token) });
  const devices = useQuery({ queryKey: ["devices-options", token], queryFn: () => apiGet<Paginated<Device>>("/devices?page=1&page_size=100", token ?? ""), enabled: Boolean(token) });

  const duplicateMutation = useMutation({ mutationFn: (id: string) => apiSend<ValidationItem>(`/validations/${id}/duplicate`, token ?? "", "POST", {}), onSuccess: () => client.invalidateQueries({ queryKey: ["validations"] }) });
  const versionMutation = useMutation({ mutationFn: (id: string) => apiSend<ValidationItem>(`/validations/${id}/new-version`, token ?? "", "POST", {}), onSuccess: () => client.invalidateQueries({ queryKey: ["validations"] }) });
  const cancelMutation = useMutation({ mutationFn: (id: string) => apiSend<ValidationItem>(`/validations/${id}/cancel`, token ?? "", "POST", {}), onSuccess: () => client.invalidateQueries({ queryKey: ["validations"] }) });
  const deleteMutation = useMutation({ mutationFn: (id: string) => apiDelete(`/validations/${id}`, token ?? ""), onSuccess: () => client.invalidateQueries({ queryKey: ["validations"] }) });

  async function downloadPdf(id: string, reportNumber: string) {
    const response = await fetch(`${API_BASE}/validations/${id}/report.pdf`, { headers: { Authorization: `Bearer ${token}` } });
    const blob = await response.blob();
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = url;
    link.download = `${reportNumber}.pdf`;
    link.click();
    URL.revokeObjectURL(url);
  }

  const columns = useMemo<ColumnDef<ValidationItem>[]>(() => [
    { accessorKey: "report_number", header: "Berichtsnummer" },
    { accessorKey: "validation_type", header: "Art" },
    { accessorKey: "performed_on", header: "Pruefdatum" },
    { accessorKey: "next_validation_on", header: "Naechste Validierung" },
    { accessorKey: "examiner_name", header: "Pruefer" },
    { accessorKey: "result", header: "Ergebnis" },
    { accessorKey: "updated_at", header: "Zuletzt geaendert" },
    { accessorKey: "status", header: "Status", cell: ({ row }) => <span className={`rounded-full px-3 py-1 text-xs font-semibold ${statusClass[row.original.status] ?? statusClass.ENTWURF}`}>{statusLabels[row.original.status] ?? row.original.status}</span> },
    { id: "actions", header: "Aktionen", enableSorting: false, cell: ({ row }) => {
      const editable = ["ENTWURF", "BEREIT_ZUR_PRUEFUNG", "IN_PRUEFUNG"].includes(row.original.status);
      const versionable = ["FREIGEGEBEN", "ABGESCHLOSSEN"].includes(row.original.status);
      return <div className="flex justify-end gap-2">{editable && <Link className="btn btn-secondary h-10 px-3" title="Weiterbearbeiten" href={`/validations/${row.original.id}/edit`}><Edit2 className="h-4 w-4" /> Weiterbearbeiten</Link>}{versionable && <button className="btn btn-secondary h-10 px-3" title="Neue Version erstellen" onClick={() => versionMutation.mutate(row.original.id)}><GitBranchPlus className="h-4 w-4" /> Neue Version</button>}<Link className="icon-btn" title="HTML-Vorschau" href={`/validations/${row.original.id}/preview`}><Eye className="h-4 w-4" /></Link><button className="icon-btn" title="PDF herunterladen" onClick={() => downloadPdf(row.original.id, row.original.report_number)}><Download className="h-4 w-4" /></button><button className="icon-btn" title={duplicateMutation.isPending ? "Duplizieren laeuft..." : "Duplizieren"} disabled={duplicateMutation.isPending} onClick={() => duplicateMutation.mutate(row.original.id)}>{duplicateMutation.isPending ? <span className="spinner" /> : <Copy className="h-4 w-4" />}</button><button className="icon-btn text-danger" title={cancelMutation.isPending ? "Stornieren laeuft..." : "Stornieren"} disabled={cancelMutation.isPending} onClick={() => cancelMutation.mutate(row.original.id)}>{cancelMutation.isPending ? <span className="spinner" /> : <XCircle className="h-4 w-4" />}</button>{row.original.status === "ENTWURF" && <button className="icon-btn text-danger" title={deleteMutation.isPending ? "Loeschen laeuft..." : "Loeschen"} disabled={deleteMutation.isPending} onClick={() => deleteMutation.mutate(row.original.id)}>{deleteMutation.isPending ? <span className="spinner" /> : <Trash2 className="h-4 w-4" />}</button>}</div>;
    } }
  ], [cancelMutation, deleteMutation, duplicateMutation, token]);

  const table = useReactTable({
    data: validations.data?.items ?? [],
    columns,
    state: { sorting },
    manualSorting: true,
    onSortingChange: setSorting,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel()
  });
  const totalPages = Math.max(1, Math.ceil((validations.data?.total ?? 0) / pageSize));

  return (
    <div className="space-y-6">
      <header className="flex flex-col justify-between gap-4 md:flex-row md:items-center">
        <div><h1 className="text-3xl font-semibold">Validierungen</h1><p className="mt-2 text-text-light">Verwaltung, Vorschau, Export und Workflow.</p></div>
        <Link href="/validations/new" className="btn btn-primary h-12"><FilePlus2 className="h-5 w-5" /> Neue Validierung</Link>
      </header>
      <section className="rounded-lg border border-border bg-surface p-4 shadow-soft">
        <div className="grid gap-3 md:grid-cols-4">
          <label className="flex h-12 items-center gap-2 rounded-lg border border-border px-3 md:col-span-2"><Search className="h-4 w-4 text-primary" /><input value={search} onChange={(event) => { setPage(1); setSearch(event.target.value); }} className="flex-1 outline-none" placeholder="Volltextsuche" /></label>
          <select value={status} onChange={(event) => setStatus(event.target.value)} className="h-12 rounded-lg border border-border px-3"><option value="">Alle Status</option>{Object.entries(statusLabels).map(([value, label]) => <option key={value} value={value}>{label}</option>)}</select>
          <select value={validationType} onChange={(event) => setValidationType(event.target.value)} className="h-12 rounded-lg border border-border px-3"><option value="">Alle Arten</option><option>Erstvalidierung</option><option>Revalidierung</option><option>Leistungsbeurteilung</option><option>Sonderpruefung</option></select>
          <select value={customerId} onChange={(event) => setCustomerId(event.target.value)} className="h-12 rounded-lg border border-border px-3"><option value="">Alle Kunden</option>{(customers.data?.items ?? []).map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}</select>
          <select value={deviceId} onChange={(event) => setDeviceId(event.target.value)} className="h-12 rounded-lg border border-border px-3"><option value="">Alle Geraete</option>{(devices.data?.items ?? []).map((item) => <option key={item.id} value={item.id}>{item.manufacturer} {item.model}</option>)}</select>
          <select value={result} onChange={(event) => setResult(event.target.value)} className="h-12 rounded-lg border border-border px-3"><option value="">Alle Ergebnisse</option><option value="offen">Offen</option><option value="bestanden">Bestanden</option><option value="nicht_bestanden">Nicht bestanden</option><option value="mit_auflagen">Mit Auflagen</option></select>
          <input type="date" value={dateFrom} onChange={(event) => setDateFrom(event.target.value)} className="h-12 rounded-lg border border-border px-3" />
          <input type="date" value={dateTo} onChange={(event) => setDateTo(event.target.value)} className="h-12 rounded-lg border border-border px-3" />
          <label className="flex h-12 items-center gap-3 rounded-lg border border-border px-3"><input type="checkbox" checked={overdueOnly} onChange={(event) => setOverdueOnly(event.target.checked)} /> ueberfaellige Revalidierungen</label>
        </div>
      </section>
      <ImportPanel />
      <section className="overflow-hidden rounded-lg border border-border bg-surface shadow-soft">
        <div className="overflow-x-auto">
          <table className="min-w-full text-left text-sm">
            <thead className="bg-background text-xs uppercase text-text-light">{table.getHeaderGroups().map((group) => <tr key={group.id}>{group.headers.map((header) => <th key={header.id} onClick={header.column.getToggleSortingHandler()} className="cursor-pointer px-5 py-4 hover:text-primary-dark">{flexRender(header.column.columnDef.header, header.getContext())}</th>)}</tr>)}</thead>
            <tbody className="divide-y divide-border">{table.getRowModel().rows.map((row) => <tr key={row.id} className="hover:bg-accent/10">{row.getVisibleCells().map((cell) => <td key={cell.id} className="whitespace-nowrap px-5 py-4">{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>)}</tr>)}</tbody>
          </table>
        </div>
      </section>
      <footer className="flex items-center justify-between text-sm text-text-light"><span>{validations.data?.total ?? 0} Datensaetze</span><div className="flex items-center gap-3"><button disabled={page <= 1} title={page <= 1 ? "Erste Seite erreicht" : undefined} onClick={() => setPage((value) => value - 1)} className="btn btn-secondary">Zurueck</button><span>Seite {page} von {totalPages}</span><button disabled={page >= totalPages} title={page >= totalPages ? "Letzte Seite erreicht" : undefined} onClick={() => setPage((value) => value + 1)} className="btn btn-secondary">Weiter</button></div></footer>
    </div>
  );
}

type ImportPreview = {
  rows: { row_number: number; data: Record<string, string>; errors: string[]; duplicate: boolean }[];
  valid_rows: number;
  invalid_rows: number;
  duplicates: number;
};

function ImportPanel() {
  const { token } = useAuth();
  const client = useQueryClient();
  const [preview, setPreview] = useState<ImportPreview | null>(null);
  const [summary, setSummary] = useState("");
  const [strategy, setStrategy] = useState("skip");

  async function previewCsv(file: File | null) {
    if (!file || !token) return;
    const formData = new FormData();
    formData.append("file", file);
    const response = await fetch(`${API_BASE}/validations/import/csv-preview`, {
      method: "POST",
      headers: { Authorization: `Bearer ${token}` },
      body: formData
    });
    setPreview(await response.json());
  }

  async function importJson(file: File | null) {
    if (!file || !token) return;
    const parsed = JSON.parse(await file.text());
    const rows = Array.isArray(parsed) ? parsed : [parsed];
    const response = await fetch(`${API_BASE}/validations/import/json`, {
      method: "POST",
      headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
      body: JSON.stringify({ rows, duplicate_strategy: strategy })
    });
    const result = await response.json();
    setSummary(`Erfolgreich: ${result.successful}, uebersprungen: ${result.skipped}, fehlerhaft: ${result.failed}`);
    client.invalidateQueries({ queryKey: ["validations"] });
  }

  return (
    <section className="rounded-lg border border-border bg-surface p-4 shadow-soft">
      <div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
        <div><h2 className="font-semibold">Import</h2><p className="mt-1 text-sm text-text-light">CSV-Vorschau und JSON-Import mit Duplikatstrategie.</p></div>
        <select value={strategy} onChange={(event) => setStrategy(event.target.value)} className="h-11 rounded-lg border border-border px-3"><option value="skip">Duplikate ueberspringen</option><option value="update">Duplikate aktualisieren</option><option value="copy">Als Kopie importieren</option></select>
      </div>
      <div className="mt-4 grid gap-3 md:grid-cols-2">
        <label className="rounded-lg border border-dashed border-primary/40 p-4 transition hover:border-primary hover:bg-accent/10 hover:shadow-soft">CSV-Vorschau<input type="file" accept=".csv" className="mt-3 block w-full cursor-pointer" onChange={(event) => previewCsv(event.target.files?.[0] ?? null)} /></label>
        <label className="rounded-lg border border-dashed border-primary/40 p-4 transition hover:border-primary hover:bg-accent/10 hover:shadow-soft">JSON importieren<input type="file" accept=".json" className="mt-3 block w-full cursor-pointer" onChange={(event) => importJson(event.target.files?.[0] ?? null)} /></label>
      </div>
      {summary && <p className="mt-3 text-sm text-primary-dark">{summary}</p>}
      {preview && <div className="mt-4 overflow-x-auto"><p className="mb-2 text-sm text-text-light">Gueltig: {preview.valid_rows}, fehlerhaft: {preview.invalid_rows}, Duplikate: {preview.duplicates}</p><table className="min-w-full text-left text-sm"><thead className="bg-background text-xs uppercase text-text-light"><tr><th className="px-3 py-2">Zeile</th><th className="px-3 py-2">Berichtsnummer</th><th className="px-3 py-2">Status</th><th className="px-3 py-2">Fehler</th></tr></thead><tbody>{preview.rows.map((row) => <tr key={row.row_number} className="border-t border-border"><td className="px-3 py-2">{row.row_number}</td><td className="px-3 py-2">{row.data.report_number}</td><td className="px-3 py-2">{row.duplicate ? "Duplikat" : "Neu"}</td><td className="px-3 py-2 text-danger">{row.errors.join(", ")}</td></tr>)}</tbody></table></div>}
    </section>
  );
}
