"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { ChevronDown, Download, FileText, Plus, Save, ShieldCheck, UploadCloud, X } from "lucide-react";
import { useEffect, useMemo, useRef, useState } from "react";
import { Controller, useFieldArray, useForm, useWatch } from "react-hook-form";
import { z } from "zod";
import { ActionButton, ActionState } from "@/components/action-button";
import { useAuth } from "@/components/auth";
import { API_BASE, apiGet, apiSend, Contact, Customer, Device, Equipment, Location, normalizeValidationPayload, Paginated, ValidationItem } from "@/lib/api";
import { getValidationResultPresentation, normalizeValidationResult, validationResultValues } from "@/lib/validation-result";

const triState = ["yes", "no", "na"] as const;
const today = new Date().toISOString().slice(0, 10);

const attachmentCategories = [
  "Aufbereitungsraum",
  "reiner Bereich",
  "unreiner Bereich",
  "Sterilisator",
  "Beladung",
  "Sensorposition",
  "Chargenprotokoll",
  "Indikator",
  "Zertifikat",
  "Kalibrierschein",
  "Winlog-Auswertung"
];

const requiredLabels: Record<string, { label: string; section: string }> = {
  report_number: { label: "Berichtsnummer", section: "Allgemeine Angaben" },
  validation_type: { label: "Validierungsart", section: "Allgemeine Angaben" },
  performed_on: { label: "Pruefdatum", section: "Allgemeine Angaben" },
  customer_id: { label: "Kunde", section: "Kunde und Standort" },
  location_id: { label: "Standort", section: "Kunde und Standort" },
  device_id: { label: "Geraet", section: "Geraet" },
  examiner_name: { label: "Pruefer", section: "Allgemeine Angaben" }
};

const schema = z.object({
  report_number: z.string().min(3),
  validation_type: z.string().min(1),
  project: z.string().optional(),
  performed_on: z.string().min(1),
  next_validation_on: z.string().optional().nullable(),
  revalidation_interval_months: z.coerce.number().int().min(1),
  next_validation_manually_overridden: z.boolean(),
  test_location: z.string().optional(),
  examiner_name: z.string().min(1),
  participants: z.string().optional(),
  status: z.string().min(1),
  result: z.string().min(1),
  customer_id: z.string().min(1),
  location_id: z.string().min(1),
  contact_id: z.string().optional().nullable(),
  examiner_id: z.string().optional().nullable(),
  operator_name: z.string().optional(),
  device_id: z.string().min(1),
  equipment_ids: z.array(z.string()),
  environment_conditions: z.record(z.unknown()),
  documentation_checklist: z.array(z.record(z.unknown())),
  performance_checklist: z.array(z.record(z.unknown())),
  programs: z.array(z.record(z.unknown())),
  loading_patterns: z.array(z.record(z.unknown())),
  measurement_data: z.array(z.record(z.unknown())),
  drying: z.record(z.unknown()),
  recommendations: z.array(z.record(z.unknown())),
  attachments: z.array(z.record(z.unknown()))
});

type FormValues = z.infer<typeof schema>;
type ReviewIssue = { field: string; message: string; section: string };
type ReviewResult = { status: string; errors: ReviewIssue[]; warnings: ReviewIssue[]; complete_sections: string[] };
type ChecklistTemplate = { checklist_key: string; title: string; items: Record<string, unknown>[] };

function defaults(reportNumber = ""): FormValues {
  return {
    report_number: reportNumber,
    validation_type: "Erstvalidierung",
    project: "",
    performed_on: today,
    next_validation_on: "",
    revalidation_interval_months: 24,
    next_validation_manually_overridden: false,
    test_location: "",
    examiner_name: "",
    participants: "",
    status: "ENTWURF",
    result: "OFFEN",
    customer_id: "",
    location_id: "",
    contact_id: "",
    examiner_id: "",
    operator_name: "",
    device_id: "",
    equipment_ids: [],
    environment_conditions: {
      room_temperature: "",
      humidity: "",
      test_time: "",
      checks: [
        { text: "Raumbedingungen stabil", value: "na", comment: "" },
        { text: "Aufstellort frei zugaenglich", value: "na", comment: "" },
        { text: "Medienversorgung verfuegbar", value: "na", comment: "" }
      ]
    },
    documentation_checklist: [],
    performance_checklist: [],
    programs: [
      { name: "Vakuumtest", selected: false, custom: false },
      { name: "Bowie-Dick / Leerkammerprofil", selected: false, custom: false },
      { name: "134 C hohl verpackt", selected: false, custom: false }
    ],
    loading_patterns: [1, 2, 3].map((run) => ({ run, pattern: "", description: "", images: [] })),
    measurement_data: ["Vakuumtest", "Leerkammerprofil", "Testlauf 1", "Testlauf 2", "Testlauf 3"].map((name) => ({
      name,
      start_time: "",
      end_time: "",
      duration: "",
      leak_rate: "",
      min_temperature: "",
      max_temperature: "",
      temperature_band: "",
      equilibration_time: "",
      holding_time: "",
      pressure: "",
      result: "",
      imports: []
    })),
    drying: { start_weight: "", end_weight: "", difference: "", rating: "", comment: "" },
    recommendations: [],
    attachments: []
  };
}

function Accordion({ title, children, defaultOpen = false }: { title: string; children: React.ReactNode; defaultOpen?: boolean }) {
  const [open, setOpen] = useState(defaultOpen);
  return (
    <section className="rounded-lg border border-border bg-surface shadow-soft">
      <button type="button" onClick={() => setOpen((value) => !value)} className="flex w-full items-center justify-between px-5 py-4 text-left text-lg font-semibold hover:bg-background">
        {title}
        <ChevronDown className={`h-5 w-5 transition ${open ? "rotate-180" : ""}`} />
      </button>
      {open && <div className="border-t border-border p-5">{children}</div>}
    </section>
  );
}

function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return <label className="block"><span className="text-sm font-medium text-text">{label}</span><div className="mt-2">{children}</div></label>;
}

const inputClass = "h-12 w-full rounded-lg border border-border bg-white px-4 outline-none focus:border-primary";
const selectClass = inputClass;
const areaClass = "min-h-24 w-full rounded-lg border border-border bg-white px-4 py-3 outline-none focus:border-primary";

export function ValidationEditor({ validationId }: { validationId?: string }) {
  const { token } = useAuth();
  const client = useQueryClient();
  const [draftId, setDraftId] = useState<string | null>(validationId ?? null);
  const [lastSaved, setLastSaved] = useState<string>("");
  const [formMessage, setFormMessage] = useState("");
  const [reviewResult, setReviewResult] = useState<ReviewResult | null>(null);
  const [saveState, setSaveState] = useState<ActionState>("normal");
  const [reviewState, setReviewState] = useState<ActionState>("normal");
  const [pdfState, setPdfState] = useState<ActionState>("normal");
  const [uploadingCategory, setUploadingCategory] = useState<string | null>(null);
  const autosaveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  const nextNumber = useQuery({ queryKey: ["next-report-number", token], queryFn: () => apiGet<{ report_number: string }>("/validations/next-report-number", 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 locations = useQuery({ queryKey: ["locations-options", token], queryFn: () => apiGet<Paginated<Location>>("/locations?page=1&page_size=100", token ?? ""), enabled: Boolean(token) });
  const contacts = useQuery({ queryKey: ["contacts-options", token], queryFn: () => apiGet<Paginated<Contact>>("/contacts?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 equipment = useQuery({ queryKey: ["equipment-options", token], queryFn: () => apiGet<Paginated<Equipment>>("/equipment?page=1&page_size=100", token ?? ""), enabled: Boolean(token) });
  const checklistTemplates = useQuery({ queryKey: ["report-checklists", token], queryFn: () => apiGet<ChecklistTemplate[]>("/report-templates/default/checklists", token ?? ""), enabled: Boolean(token) });
  const existingValidation = useQuery({ queryKey: ["validation", validationId, token], queryFn: () => apiGet<ValidationItem>(`/validations/${validationId}`, token ?? ""), enabled: Boolean(token && validationId) });

  const form = useForm<FormValues>({ resolver: zodResolver(schema), defaultValues: defaults() });
  const watched = useWatch({ control: form.control });
  const selectedDevice = devices.data?.items.find((item) => item.id === form.watch("device_id"));
  const selectedEquipment = equipment.data?.items.filter((item) => form.watch("equipment_ids").includes(item.id)) ?? [];
  const selectedResult = getValidationResultPresentation(form.watch("result"));
  const recommendations = useFieldArray({ control: form.control, name: "recommendations" });
  const attachments = useFieldArray({ control: form.control, name: "attachments" });

  useEffect(() => {
    if (nextNumber.data?.report_number && !form.getValues("report_number")) {
      form.setValue("report_number", nextNumber.data.report_number);
    }
  }, [form, nextNumber.data]);

  useEffect(() => {
    if (!existingValidation.data) return;
    const data = existingValidation.data;
    form.reset({
      ...defaults(),
      ...data,
      result: normalizeValidationResult(data.result),
      project: data.project ?? "",
      test_location: data.test_location ?? "",
      examiner_name: data.examiner_name ?? "",
      participants: data.participants ?? "",
      operator_name: data.operator_name ?? "",
      performed_on: data.performed_on ?? "",
      next_validation_on: data.next_validation_on ?? "",
      contact_id: data.contact_id ?? "",
      examiner_id: "",
      location_id: data.location_id ?? "",
      device_id: data.device_id ?? ""
    });
    setDraftId(data.id);
  }, [existingValidation.data, form]);

  useEffect(() => {
    if (!checklistTemplates.data || existingValidation.data) return;
    if (form.getValues("documentation_checklist").length > 0) return;
    const items = checklistTemplates.data.flatMap((template) =>
      template.items.map((item) => ({ ...item, template_key: template.checklist_key, template_title: template.title }))
    );
    form.setValue("documentation_checklist", items);
  }, [checklistTemplates.data, existingValidation.data, form]);

  const readonly = existingValidation.data?.status === "FREIGEGEBEN" || existingValidation.data?.status === "ABGESCHLOSSEN";

  const saveMutation = useMutation({
    mutationFn: (values: FormValues) => apiSend<ValidationItem>(draftId ? `/validations/${draftId}` : "/validations", token ?? "", draftId ? "PUT" : "POST", normalizeValidationPayload(values)),
    onSuccess: (item) => {
      setDraftId(item.id);
      setLastSaved(new Date().toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" }));
      setFormMessage("");
      setSaveState("success");
      window.setTimeout(() => setSaveState("normal"), 1500);
      client.invalidateQueries({ queryKey: ["dashboard"] });
    },
    onError: (error) => {
      setSaveState("error");
      setFormMessage(error instanceof Error ? error.message : "Speichern fehlgeschlagen.");
    }
  });

  useEffect(() => {
    if (readonly || !token || !watched.report_number || !watched.validation_type || !watched.customer_id || !watched.location_id || !watched.device_id || !watched.examiner_name || !watched.performed_on) return;
    if (autosaveTimer.current) clearTimeout(autosaveTimer.current);
    autosaveTimer.current = setTimeout(() => {
      const values = form.getValues();
      saveMutation.mutate(values);
    }, 2500);
    return () => {
      if (autosaveTimer.current) clearTimeout(autosaveTimer.current);
    };
  }, [form, saveMutation, token, watched]);

  const customerOptions = customers.data?.items ?? [];
  const selectedCustomer = customerOptions.find((item) => item.id === form.watch("customer_id"));
  const filteredLocations = (locations.data?.items ?? []).filter((item) => !form.watch("customer_id") || item.customer_id === form.watch("customer_id"));
  const filteredContacts = (contacts.data?.items ?? []).filter((item) => !form.watch("customer_id") || item.customer_id === form.watch("customer_id"));
  const filteredDevices = (devices.data?.items ?? []).filter((item) => !form.watch("customer_id") || item.customer_id === form.watch("customer_id"));

  const calibrationWarnings = useMemo(() => selectedEquipment.filter((item) => item.calibration_due_on && item.calibration_due_on < today), [selectedEquipment]);

  function missingRequired(values = form.getValues()) {
    return Object.entries(requiredLabels).filter(([field]) => !values[field as keyof FormValues]);
  }

  function scrollToFirstMissing() {
    const first = missingRequired()[0];
    if (!first) return false;
    setFormMessage(`${first[1].label} fehlt in ${first[1].section}.`);
    document.querySelector(`[name="${first[0]}"]`)?.scrollIntoView({ behavior: "smooth", block: "center" });
    return true;
  }

  function submit(values: FormValues) {
    if (readonly) {
      setFormMessage("Diese Validierung ist schreibgeschuetzt.");
      return;
    }
    if (missingRequired(values).length) {
      setSaveState("error");
      scrollToFirstMissing();
      return;
    }
    setSaveState("loading");
    saveMutation.mutate(values);
  }

  async function reviewValidation() {
    if (readonly) {
      setFormMessage("Diese Validierung ist schreibgeschuetzt.");
      return;
    }
    if (missingRequired().length) {
      setReviewState("error");
      scrollToFirstMissing();
      return;
    }
    try {
      setReviewState("loading");
      const saved = draftId ? null : await saveMutation.mutateAsync(form.getValues());
      const id = draftId ?? saved?.id;
      if (!id || !token) return;
      const response = await fetch(`${API_BASE}/validations/${id}/review`, { method: "POST", headers: { Authorization: `Bearer ${token}` } });
      const result = (await response.json()) as ReviewResult;
      setReviewResult(result);
      setReviewState("success");
      window.setTimeout(() => setReviewState("normal"), 1500);
      setFormMessage(result.errors.length ? "Pruefung abgeschlossen: Fehler blockieren die Freigabe." : "Pruefung abgeschlossen: keine blockierenden Fehler.");
    } catch (error) {
      setReviewState("error");
      setFormMessage(error instanceof Error ? error.message : "Pruefung fehlgeschlagen.");
    }
  }

  async function addFiles(files: FileList | null, category: string) {
    if (!files || files.length === 0) return;
    if (!draftId || !token) {
      setFormMessage("Bitte den Entwurf speichern, bevor Bilder oder Anlagen hochgeladen werden.");
      return;
    }
    try {
      setUploadingCategory(category);
      for (const [index, file] of Array.from(files).entries()) {
        const order = attachments.fields.length + index + 1;
        const body = new FormData();
        body.append("category", category);
        body.append("description", "");
        body.append("order", String(order));
        body.append("file", file);
        const response = await fetch(`${API_BASE}/validations/${draftId}/attachments`, {
          method: "POST",
          headers: { Authorization: `Bearer ${token}` },
          body
        });
        if (!response.ok) {
          const errorBody = await response.json().catch(() => null);
          throw new Error(errorBody?.detail ?? "Upload fehlgeschlagen.");
        }
        const uploaded = await response.json();
        attachments.append(uploaded);
      }
      client.invalidateQueries({ queryKey: ["validation", draftId, token] });
      setFormMessage("Upload abgeschlossen.");
    } catch (error) {
      setFormMessage(error instanceof Error ? error.message : "Upload fehlgeschlagen.");
    } finally {
      setUploadingCategory(null);
    }
  }

  async function openReportPreview() {
    if (!draftId || !token) return;
    const response = await fetch(`${API_BASE}/validations/${draftId}/report.html`, {
      headers: { Authorization: `Bearer ${token}` }
    });
    const html = await response.text();
    const preview = window.open("", "_blank");
    if (preview) {
      preview.document.write(html);
      preview.document.close();
    }
  }

  async function downloadReport() {
    if (!draftId || !token) return;
    try {
      setPdfState("loading");
      const response = await fetch(`${API_BASE}/validations/${draftId}/report.pdf`, {
        headers: { Authorization: `Bearer ${token}` }
      });
      if (!response.ok) {
        const body = await response.json().catch(() => null);
        throw new Error(body?.detail ?? "PDF konnte nicht erzeugt werden.");
      }
      const blob = await response.blob();
      const url = URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = url;
      link.download = `${form.getValues("report_number")}.pdf`;
      link.click();
      URL.revokeObjectURL(url);
      setPdfState("success");
      window.setTimeout(() => setPdfState("normal"), 1500);
    } catch (error) {
      setPdfState("error");
      setFormMessage(error instanceof Error ? error.message : "PDF-Download fehlgeschlagen.");
    }
  }

  return (
    <form onSubmit={form.handleSubmit(submit)} className="space-y-5 pb-28">
      <header>
        <h1 className="text-3xl font-semibold text-text">Validierungsbericht</h1>
        <p className="mt-2 text-text-light">{readonly ? "Schreibgeschuetzte freigegebene oder abgeschlossene Validierung." : "Eine responsive Seite fuer Erfassung, Pruefung und Berichtserstellung."}</p>
      </header>

      <Accordion title="1. Allgemeine Angaben" defaultOpen>
        <div className="grid gap-4 md:grid-cols-2">
          <Field label="Berichtsnummer *"><input className={inputClass} {...form.register("report_number")} /></Field>
          <Field label="Validierungsart *"><select className={selectClass} {...form.register("validation_type")}><option>Erstvalidierung</option><option>Revalidierung</option><option>Leistungsbeurteilung</option><option>Sonderpruefung</option></select></Field>
          <Field label="Projekt"><input className={inputClass} {...form.register("project")} /></Field>
          <Field label="Pruefdatum *"><input type="date" className={inputClass} {...form.register("performed_on")} /></Field>
          <Field label="Revalidierungsintervall Monate"><input type="number" className={inputClass} {...form.register("revalidation_interval_months")} /></Field>
          <Field label="Naechste Validierung"><input type="date" className={inputClass} {...form.register("next_validation_on")} onChange={(event) => { form.setValue("next_validation_manually_overridden", true); form.setValue("next_validation_on", event.target.value); }} /></Field>
          <Field label="Pruefungsort"><input className={inputClass} {...form.register("test_location")} /></Field>
          <Field label="Pruefer *"><input className={inputClass} {...form.register("examiner_name")} /></Field>
          <Field label="Mitwirkende Personen"><textarea className={areaClass} {...form.register("participants")} /></Field>
          <Field label="Status"><select className={selectClass} {...form.register("status")}><option value="ENTWURF">Entwurf</option><option value="BEREIT_ZUR_PRUEFUNG">Bereit zur Pruefung</option><option value="IN_PRUEFUNG">In Pruefung</option><option value="FREIGEGEBEN">Freigegeben</option><option value="ABGESCHLOSSEN">Abgeschlossen</option><option value="STORNIERT">Storniert</option></select></Field>
          <Field label="Gesamtergebnis"><select className={selectClass} {...form.register("result")}>{validationResultValues.map((value) => <option key={value} value={value}>{getValidationResultPresentation(value).label}</option>)}</select><div className={`mt-3 flex min-h-12 items-center justify-center rounded-lg border px-4 text-sm font-semibold ${selectedResult.previewClass}`}>{selectedResult.label}</div></Field>
        </div>
      </Accordion>

      <Accordion title="2. Kunde und Standort">
        <div className="grid gap-4 md:grid-cols-2">
          <Field label="Kunde *"><select className={selectClass} {...form.register("customer_id")}><option value="">Bitte waehlen</option>{customerOptions.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}</select></Field>
          <Field label="Standort *"><select className={selectClass} {...form.register("location_id")}><option value="">Bitte waehlen</option>{filteredLocations.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}</select></Field>
          <Field label="Ansprechpartner"><select className={selectClass} {...form.register("contact_id")}><option value="">Bitte waehlen</option>{filteredContacts.map((item) => <option key={item.id} value={item.id}>{item.full_name}</option>)}</select></Field>
          <Field label="Betreiber"><input className={inputClass} {...form.register("operator_name")} /></Field>
          <Field label="QM-/Hygienebeauftragter"><input className={inputClass} value={[selectedCustomer?.quality_manager, selectedCustomer?.hygiene_officer].filter(Boolean).join(" / ")} readOnly /></Field>
        </div>
      </Accordion>

      <Accordion title="3. Geraet">
        <Field label="Geraet *"><select className={selectClass} {...form.register("device_id")}><option value="">Bitte waehlen</option>{filteredDevices.map((item) => <option key={item.id} value={item.id}>{item.manufacturer} {item.model} - {item.serial_number}</option>)}</select></Field>
        <div className="mt-4 grid gap-4 md:grid-cols-3">{[
          ["Hersteller", selectedDevice?.manufacturer],
          ["Modell", selectedDevice?.model],
          ["Seriennummer", selectedDevice?.serial_number],
          ["Baujahr", selectedDevice?.year_built],
          ["Inbetriebnahme", selectedDevice?.commissioned_on],
          ["Kammervolumen", selectedDevice?.chamber_volume_liters],
          ["Dampferzeugung", selectedDevice?.steam_generation],
          ["Wasseraufbereitung", selectedDevice?.water_treatment],
          ["Dokumentation", selectedDevice?.documentation],
          ["Lieferant", selectedDevice?.supplier]
        ].map(([label, value]) => <div key={label as string} className="rounded-lg border border-border bg-background p-4"><p className="text-xs text-text-light">{label}</p><p className="mt-1 font-medium">{String(value ?? "-")}</p></div>)}</div>
      </Accordion>

      <Accordion title="4. Pruefmittel">
        <Controller control={form.control} name="equipment_ids" render={({ field }) => (
          <div className="grid gap-3 md:grid-cols-2">
            {(equipment.data?.items ?? []).map((item) => {
              const expired = Boolean(item.calibration_due_on && item.calibration_due_on < today);
              return <label key={item.id} className="flex items-start gap-3 rounded-lg border border-border p-4"><input type="checkbox" className="mt-1 h-5 w-5" checked={field.value.includes(item.id)} onChange={(event) => field.onChange(event.target.checked ? [...field.value, item.id] : field.value.filter((id: string) => id !== item.id))} /><span><strong>{item.kind}</strong><br />{item.serial_number} · {item.calibrated_on ?? "-"} · {item.status}{expired && <span className="ml-2 text-danger">Kalibrierung abgelaufen</span>}</span></label>;
            })}
          </div>
        )} />
        {calibrationWarnings.length > 0 && <p className="mt-4 rounded-lg border border-danger/30 bg-danger/5 p-4 text-danger">Mindestens ein ausgewaehltes Pruefmittel hat eine abgelaufene Kalibrierung.</p>}
      </Accordion>

      <Accordion title="5. Umgebungsbedingungen">
        <div className="grid gap-4 md:grid-cols-3">
          <Field label="Raumtemperatur"><input className={inputClass} {...form.register("environment_conditions.room_temperature")} /></Field>
          <Field label="relative Luftfeuchtigkeit"><input className={inputClass} {...form.register("environment_conditions.humidity")} /></Field>
          <Field label="Pruefzeit"><input className={inputClass} {...form.register("environment_conditions.test_time")} /></Field>
        </div>
        {[0, 1, 2].map((index) => <ChecklistRow key={index} form={form} path={`environment_conditions.checks.${index}`} />)}
      </Accordion>

      <Accordion title="6. Dokumentations- und Leistungschecklisten">
        {form.watch("documentation_checklist").map((item, index) => <ChecklistRow key={`${String(item.template_key ?? "check")}-${index}`} form={form} path={`documentation_checklist.${index}`} />)}
        {form.watch("performance_checklist").map((_, index) => <ChecklistRow key={`performance-${index}`} form={form} path={`performance_checklist.${index}`} />)}
      </Accordion>

      <Accordion title="7. Programme">
        {[0, 1, 2].map((index) => <ProgramRow key={index} form={form} index={index} />)}
        <ActionButton type="button" icon={<Plus className="h-4 w-4" />} onClick={() => form.setValue("programs", [...form.getValues("programs"), { name: "", selected: true, custom: true }])} className="mt-4">Eigenes Programm</ActionButton>
      </Accordion>

      <Accordion title="8. Beladungsmuster">
        {[0, 1, 2].map((index) => <LoadingRun key={index} form={form} index={index} />)}
      </Accordion>

      <Accordion title="9. Messdaten">
        {[0, 1, 2, 3, 4].map((index) => <MeasurementBlock key={index} form={form} index={index} />)}
      </Accordion>

      <Accordion title="10. Trocknung">
        <div className="grid gap-4 md:grid-cols-2">
          {["start_weight", "end_weight", "difference", "rating"].map((name) => <Field key={name} label={name}><input className={inputClass} {...form.register(`drying.${name}`)} /></Field>)}
          <Field label="Bemerkung"><textarea className={areaClass} {...form.register("drying.comment")} /></Field>
        </div>
      </Accordion>

      <Accordion title="11. Empfehlungen und Auflagen">
        {recommendations.fields.map((field, index) => <div key={field.id} className="mb-3 grid gap-3 rounded-lg border border-border p-4 md:grid-cols-4"><input className={inputClass} placeholder="Nummer" {...form.register(`recommendations.${index}.number`)} /><input className={inputClass} placeholder="Text" {...form.register(`recommendations.${index}.text`)} /><input type="date" className={inputClass} {...form.register(`recommendations.${index}.deadline`)} /><input className={inputClass} placeholder="Status" {...form.register(`recommendations.${index}.status`)} /></div>)}
        <ActionButton type="button" icon={<Plus className="h-4 w-4" />} onClick={() => recommendations.append({ number: recommendations.fields.length + 1, text: "", deadline: "", status: "offen" })}>Zeile hinzufuegen</ActionButton>
      </Accordion>

      <Accordion title="12. Bilder und Anlagen">
        <div className="grid gap-3 md:grid-cols-2">{attachmentCategories.map((category) => <label key={category} className="rounded-lg border border-dashed border-primary/40 p-4 transition hover:border-primary hover:bg-background"><UploadCloud className="mb-2 h-5 w-5 text-primary" />{category}{uploadingCategory === category && <span className="ml-2 text-sm text-text-light">Upload...</span>}<input type="file" multiple className="mt-3 block w-full text-sm" onChange={(event) => addFiles(event.target.files, category)} /></label>)}</div>
        <div className="mt-5 grid gap-3 md:grid-cols-2">{attachments.fields.map((field, index) => {
          const fileUrl = String(form.watch(`attachments.${index}.url`) ?? "");
          const imageUrl = fileUrl && /\.(png|jpe?g|webp|svg)$/i.test(fileUrl) ? `${API_BASE.replace("/api/v1", "")}${fileUrl}` : "";
          return <div key={field.id} className="rounded-lg border border-border p-4">{imageUrl && <img src={imageUrl} alt={String(form.watch(`attachments.${index}.filename`) ?? "")} className="mb-3 max-h-56 w-full rounded-lg border border-border object-contain" />}<div className="flex justify-between gap-3"><strong>{String(form.watch(`attachments.${index}.filename`) ?? "")}</strong><button type="button" onClick={() => attachments.remove(index)}><X className="h-4 w-4 text-danger" /></button></div><input className={`${inputClass} mt-3`} placeholder="Beschreibung" {...form.register(`attachments.${index}.description`)} /><input className={`${inputClass} mt-3`} placeholder="Reihenfolge" {...form.register(`attachments.${index}.order`)} /></div>;
        })}</div>
      </Accordion>

      {reviewResult && <section className="rounded-lg border border-border bg-surface p-5 shadow-soft"><h2 className="text-xl font-semibold">Pruefergebnis</h2><div className="mt-4 grid gap-4 md:grid-cols-3"><IssueList title="Fehler" items={reviewResult.errors} tone="danger" /><IssueList title="Warnungen" items={reviewResult.warnings} tone="warning" /><div><h3 className="font-semibold text-success">Vollstaendige Bereiche</h3>{reviewResult.complete_sections.map((item) => <p key={item} className="mt-2 text-sm">{item}</p>)}</div></div></section>}
      {saveMutation.isError && formMessage && <div className="fixed right-4 top-4 z-50 max-w-md rounded-lg border border-danger/30 bg-white p-4 text-sm text-danger shadow-soft">{formMessage}</div>}
      <fieldset disabled={readonly} className={readonly ? "pointer-events-none contents opacity-80" : "contents"}></fieldset>
      <div className="fixed inset-x-0 bottom-0 z-40 border-t border-border bg-surface/95 px-4 py-3 shadow-soft backdrop-blur">
        <div className="mx-auto flex max-w-7xl flex-wrap items-center justify-between gap-3">
          <div className="text-sm text-text-light"><p>{lastSaved ? `Automatisch gespeichert um ${lastSaved}` : "Autosave startet nach Ausfuellen der Pflichtfelder."}</p>{missingRequired().length > 0 && <p className="text-danger">Fehlt: {missingRequired().map(([, value]) => value.label).join(", ")}</p>}{formMessage && <p className="text-primary-dark">{formMessage}</p>}</div>
          <div className="flex flex-wrap gap-2">
            <ActionButton type="submit" disabled={readonly} disabledReason="Freigegebene und abgeschlossene Validierungen sind schreibgeschuetzt" icon={<Save className="h-4 w-4" />} state={saveState} loadingText="Speichern..." successText="Gespeichert">Entwurf speichern</ActionButton>
            <ActionButton type="button" disabled={readonly} disabledReason="Freigegebene und abgeschlossene Validierungen sind schreibgeschuetzt" icon={<ShieldCheck className="h-4 w-4" />} state={reviewState} loadingText="Pruefung laeuft..." successText="Geprueft" onClick={reviewValidation}>Bericht pruefen</ActionButton>
            <ActionButton type="button" variant="primary" icon={<FileText className="h-4 w-4" />} onClick={() => draftId ? window.location.assign(`/validations/${draftId}/preview`) : scrollToFirstMissing()}>HTML-Vorschau</ActionButton>
            <ActionButton type="button" icon={<Download className="h-4 w-4" />} state={pdfState} loadingText="PDF wird erzeugt..." successText="PDF erzeugt" onClick={() => draftId ? downloadReport() : scrollToFirstMissing()}>PDF herunterladen</ActionButton>
          </div>
        </div>
      </div>
    </form>
  );
}

function ChecklistRow({ form, path }: { form: ReturnType<typeof useForm<FormValues>>; path: string }) {
  return <div className="mt-3 grid gap-3 rounded-lg border border-border p-4 md:grid-cols-[1fr_180px_1fr]"><input className={inputClass} readOnly {...form.register(`${path}.text` as never)} /><select className={selectClass} {...form.register(`${path}.value` as never)}>{triState.map((value) => <option key={value} value={value}>{value === "yes" ? "Ja" : value === "no" ? "Nein" : "Nicht zutreffend"}</option>)}</select><input className={inputClass} placeholder="Kommentar" {...form.register(`${path}.comment` as never)} /></div>;
}

function IssueList({ title, items, tone }: { title: string; items: ReviewIssue[]; tone: "danger" | "warning" }) {
  return <div><h3 className={`font-semibold ${tone === "danger" ? "text-danger" : "text-warning"}`}>{title}</h3>{items.length === 0 ? <p className="mt-2 text-sm text-text-light">Keine Eintraege.</p> : items.map((item) => <p key={`${item.field}-${item.message}`} className="mt-2 text-sm">{item.section}: {item.message}</p>)}</div>;
}

function ProgramRow({ form, index }: { form: ReturnType<typeof useForm<FormValues>>; index: number }) {
  return <div className="mb-3 grid gap-3 rounded-lg border border-border p-4 md:grid-cols-[80px_1fr]"><input type="checkbox" className="h-6 w-6" {...form.register(`programs.${index}.selected`)} /><input className={inputClass} {...form.register(`programs.${index}.name`)} /></div>;
}

function LoadingRun({ form, index }: { form: ReturnType<typeof useForm<FormValues>>; index: number }) {
  return <div className="mb-4 rounded-lg border border-border p-4"><h3 className="font-semibold">Testlauf {index + 1}</h3><div className="mt-3 grid gap-3 md:grid-cols-2"><input className={inputClass} placeholder="Beladungsmuster" {...form.register(`loading_patterns.${index}.pattern`)} /><input className={inputClass} placeholder="Beschreibung" {...form.register(`loading_patterns.${index}.description`)} /><input type="file" multiple className="rounded-lg border border-border p-3 md:col-span-2" /></div></div>;
}

function MeasurementBlock({ form, index }: { form: ReturnType<typeof useForm<FormValues>>; index: number }) {
  const fields = ["start_time", "end_time", "duration", "leak_rate", "min_temperature", "max_temperature", "temperature_band", "equilibration_time", "holding_time", "pressure", "result"];
  return <div className="mb-4 rounded-lg border border-border p-4"><h3 className="font-semibold">{String(form.watch(`measurement_data.${index}.name`) ?? "")}</h3><div className="mt-3 grid gap-3 md:grid-cols-3">{fields.map((field) => <input key={field} className={inputClass} placeholder={field} {...form.register(`measurement_data.${index}.${field}`)} />)}<input type="file" multiple accept=".csv,.pdf" className="rounded-lg border border-border p-3 md:col-span-3" /></div></div>;
}

export default ValidationEditor;
