"use client";

import { useEffect, useState } from "react";

import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import type {
  DevicePayload,
  DocumentPayload,
  DocumentType,
  KnowledgeDevice,
  KnowledgeDocument,
  KnowledgeManufacturer,
  KnowledgeNote,
  ManufacturerPayload,
  NotePayload,
  NoteType,
} from "@/types/knowledge";

const documentTypes: Array<[DocumentType, string]> = [
  ["manual", "Bedienungsanleitung"],
  ["service_manual", "Service Manual"],
  ["schematic", "Schaltplan"],
  ["alignment", "Abgleichanleitung"],
  ["parts_list", "Ersatzteilliste"],
  ["firmware", "Firmware"],
  ["datasheet", "Datenblatt"],
  ["service_bulletin", "Service Bulletin"],
  ["other", "Sonstiges"],
];

const noteTypes: Array<[NoteType, string]> = [
  ["repair", "Reparaturhinweis"],
  ["known_fault", "Bekannter Fehler"],
  ["alignment", "Abgleichhinweis"],
  ["spare_part", "Ersatzteilhinweis"],
  ["general", "Allgemein"],
];

function tagsToText(tags: string[]) {
  return tags.join(", ");
}

function textToTags(value: string) {
  return value.split(",").map((tag) => tag.trim()).filter(Boolean);
}

function fieldClass() {
  return "grid gap-2";
}

export function ManufacturerFormDialog({
  open,
  manufacturer,
  pending,
  error,
  onOpenChange,
  onSubmit,
}: {
  open: boolean;
  manufacturer: KnowledgeManufacturer | null;
  pending: boolean;
  error: string;
  onOpenChange: (open: boolean) => void;
  onSubmit: (payload: ManufacturerPayload) => void;
}) {
  const [name, setName] = useState("");
  const [website, setWebsite] = useState("");
  const [notes, setNotes] = useState("");

  useEffect(() => {
    queueMicrotask(() => {
      setName(manufacturer?.name ?? "");
      setWebsite(manufacturer?.website ?? "");
      setNotes(manufacturer?.notes ?? "");
    });
  }, [manufacturer, open]);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader><DialogTitle>{manufacturer ? "Hersteller bearbeiten" : "Hersteller erstellen"}</DialogTitle></DialogHeader>
        <div className="grid gap-4">
          <div className={fieldClass()}><Label>Name</Label><Input value={name} onChange={(event) => setName(event.target.value)} /></div>
          <div className={fieldClass()}><Label>Website</Label><Input value={website} onChange={(event) => setWebsite(event.target.value)} /></div>
          <div className={fieldClass()}><Label>Notizen</Label><textarea className="min-h-24 rounded-lg border border-input p-2 text-sm" value={notes} onChange={(event) => setNotes(event.target.value)} /></div>
          {error && <p className="text-sm text-red-600">{error}</p>}
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={pending}>Abbrechen</Button>
          <Button onClick={() => onSubmit({ name, website: website || null, notes })} disabled={pending}>Speichern</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

export function DeviceFormDialog({
  open,
  device,
  manufacturers,
  initialManufacturerId,
  pending,
  error,
  onOpenChange,
  onSubmit,
}: {
  open: boolean;
  device: KnowledgeDevice | null;
  manufacturers: KnowledgeManufacturer[];
  initialManufacturerId?: number | null;
  pending: boolean;
  error: string;
  onOpenChange: (open: boolean) => void;
  onSubmit: (payload: DevicePayload) => void;
}) {
  const [payload, setPayload] = useState<DevicePayload>({
    manufacturer_id: 0,
    name: "",
    model_number: "",
    device_type: "",
    frequency_range: "",
    production_year_from: null,
    production_year_to: null,
    notes: "",
  });

  useEffect(() => {
    queueMicrotask(() => {
      setPayload(device ? {
        manufacturer_id: device.manufacturer_id,
        name: device.name,
        model_number: device.model_number,
        device_type: device.device_type,
        frequency_range: device.frequency_range,
        production_year_from: device.production_year_from,
        production_year_to: device.production_year_to,
        notes: device.notes,
      } : {
        manufacturer_id: initialManufacturerId ?? manufacturers[0]?.id ?? 0,
        name: "",
        model_number: "",
        device_type: "",
        frequency_range: "",
        production_year_from: null,
        production_year_to: null,
        notes: "",
      });
    });
  }, [device, initialManufacturerId, manufacturers, open]);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-2xl">
        <DialogHeader><DialogTitle>{device ? "Gerät bearbeiten" : "Gerät erstellen"}</DialogTitle></DialogHeader>
        <div className="grid gap-4 sm:grid-cols-2">
          <div className={fieldClass()}><Label>Hersteller</Label><select className="h-9 rounded-lg border px-2 text-sm" value={payload.manufacturer_id} onChange={(event) => setPayload({ ...payload, manufacturer_id: Number(event.target.value) })}>{manufacturers.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}</select></div>
          <div className={fieldClass()}><Label>Name</Label><Input value={payload.name} onChange={(event) => setPayload({ ...payload, name: event.target.value })} /></div>
          <div className={fieldClass()}><Label>Modellnummer</Label><Input value={payload.model_number} onChange={(event) => setPayload({ ...payload, model_number: event.target.value })} /></div>
          <div className={fieldClass()}><Label>Gerätetyp</Label><Input value={payload.device_type} onChange={(event) => setPayload({ ...payload, device_type: event.target.value })} /></div>
          <div className={fieldClass()}><Label>Frequenzbereich</Label><Input value={payload.frequency_range} onChange={(event) => setPayload({ ...payload, frequency_range: event.target.value })} /></div>
          <div className={fieldClass()}><Label>Baujahr von</Label><Input type="number" value={payload.production_year_from ?? ""} onChange={(event) => setPayload({ ...payload, production_year_from: event.target.value ? Number(event.target.value) : null })} /></div>
          <div className={fieldClass()}><Label>Baujahr bis</Label><Input type="number" value={payload.production_year_to ?? ""} onChange={(event) => setPayload({ ...payload, production_year_to: event.target.value ? Number(event.target.value) : null })} /></div>
          <div className="grid gap-2 sm:col-span-2"><Label>Notizen</Label><textarea className="min-h-24 rounded-lg border border-input p-2 text-sm" value={payload.notes} onChange={(event) => setPayload({ ...payload, notes: event.target.value })} /></div>
          {error && <p className="text-sm text-red-600 sm:col-span-2">{error}</p>}
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={pending}>Abbrechen</Button>
          <Button onClick={() => onSubmit(payload)} disabled={pending || !payload.manufacturer_id}>Speichern</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

export function DocumentUploadDialog({
  open,
  document,
  manufacturers,
  devices,
  initialManufacturerId,
  pending,
  error,
  onOpenChange,
  onSubmit,
  onValidationError,
}: {
  open: boolean;
  document: KnowledgeDocument | null;
  manufacturers: KnowledgeManufacturer[];
  devices: KnowledgeDevice[];
  initialManufacturerId?: number | null;
  pending: boolean;
  error: string;
  onOpenChange: (open: boolean) => void;
  onSubmit: (payload: DocumentPayload, file: File | null) => void;
  onValidationError?: (message: string) => void;
}) {
  const [payload, setPayload] = useState<DocumentPayload>({
    manufacturer_id: 0,
    device_id: null,
    title: "",
    document_type: "service_manual",
    language: "de",
    external_url: null,
    paperless_document_id: "",
    description: "",
    tags: [],
  });
  const [tags, setTags] = useState("");
  const [file, setFile] = useState<File | null>(null);
  const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});

  useEffect(() => {
    queueMicrotask(() => {
      setPayload(document ? {
        manufacturer_id: document.manufacturer_id,
        device_id: document.device_id,
        title: document.title,
        document_type: document.document_type,
        language: document.language,
        external_url: document.external_url || null,
        paperless_document_id: document.paperless_document_id,
        description: document.description,
        tags: document.tags,
      } : {
        manufacturer_id: initialManufacturerId ?? manufacturers[0]?.id ?? 0,
        device_id: null,
        title: "",
        document_type: "service_manual",
        language: "de",
        external_url: null,
        paperless_document_id: "",
        description: "",
        tags: [],
      });
      setTags(document ? tagsToText(document.tags) : "");
      setFile(null);
      setFieldErrors({});
    });
  }, [document, initialManufacturerId, manufacturers, open]);

  const filteredDevices = devices.filter((device) => device.manufacturer_id === payload.manufacturer_id);
  const selectedManufacturer = manufacturers.find((manufacturer) => manufacturer.id === payload.manufacturer_id);

  function validate() {
    const errors: Record<string, string> = {};
    if (!payload.manufacturer_id) {
      errors.manufacturer_id = "Bitte wählen Sie einen Hersteller aus.";
    }
    if (!payload.device_id) {
      errors.device_id = "Bitte wählen Sie ein Gerät aus.";
    }
    if (!payload.document_type) {
      errors.document_type = "Bitte wählen Sie einen Dokumenttyp aus.";
    }
    if (!payload.title.trim()) {
      errors.title = "Bitte geben Sie einen Titel ein.";
    }
    if (!document && !file) {
      errors.file = "Bitte wählen Sie eine Datei aus.";
    }

    setFieldErrors(errors);
    const firstMessage = Object.values(errors)[0];
    if (firstMessage) {
      onValidationError?.(firstMessage);
      return false;
    }
    return true;
  }

  function submit() {
    if (!validate()) {
      return;
    }
    onSubmit({ ...payload, tags: textToTags(tags) }, file);
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-3xl">
        <DialogHeader><DialogTitle>{document ? "Dokument bearbeiten" : "Dokument hochladen"}</DialogTitle></DialogHeader>
        <p className="text-sm text-slate-500">
          Dokumente werden immer einem Gerät zugeordnet. Lege daher zuerst Hersteller und Gerät an.
        </p>
        <div className="grid gap-4 sm:grid-cols-2">
          <div className={fieldClass()}>
            <Label>Hersteller</Label>
            <select className="h-9 rounded-lg border px-2 text-sm" value={payload.manufacturer_id} onChange={(event) => setPayload({ ...payload, manufacturer_id: Number(event.target.value), device_id: null })}>
              <option value={0}>Hersteller auswählen</option>
              {manufacturers.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
            </select>
            {fieldErrors.manufacturer_id && <p className="text-xs text-red-600">{fieldErrors.manufacturer_id}</p>}
          </div>
          <div className={fieldClass()}>
            <Label>Gerät</Label>
            <select className="h-9 rounded-lg border px-2 text-sm" value={payload.device_id ?? ""} onChange={(event) => setPayload({ ...payload, device_id: event.target.value ? Number(event.target.value) : null })} disabled={!payload.manufacturer_id || filteredDevices.length === 0}>
              <option value="">Gerät auswählen</option>
              {filteredDevices.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
            </select>
            {payload.manufacturer_id && filteredDevices.length === 0 && (
              <p className="text-xs text-amber-700">Für diesen Hersteller existiert noch kein Gerät.</p>
            )}
            {fieldErrors.device_id && <p className="text-xs text-red-600">{fieldErrors.device_id}</p>}
          </div>
          <div className={fieldClass()}><Label>Titel</Label><Input value={payload.title} onChange={(event) => setPayload({ ...payload, title: event.target.value })} />{fieldErrors.title && <p className="text-xs text-red-600">{fieldErrors.title}</p>}</div>
          <div className={fieldClass()}><Label>Typ</Label><select className="h-9 rounded-lg border px-2 text-sm" value={payload.document_type} onChange={(event) => setPayload({ ...payload, document_type: event.target.value as DocumentType })}>{documentTypes.map(([value, label]) => <option key={value} value={value}>{label}</option>)}</select>{fieldErrors.document_type && <p className="text-xs text-red-600">{fieldErrors.document_type}</p>}</div>
          <div className={fieldClass()}><Label>Sprache</Label><Input value={payload.language} onChange={(event) => setPayload({ ...payload, language: event.target.value })} /></div>
          <div className={fieldClass()}><Label>Paperless-ID</Label><Input value={payload.paperless_document_id} onChange={(event) => setPayload({ ...payload, paperless_document_id: event.target.value })} /></div>
          <div className={fieldClass()}><Label>Externe URL</Label><Input value={payload.external_url ?? ""} onChange={(event) => setPayload({ ...payload, external_url: event.target.value || null })} /></div>
          {!document && <div className={fieldClass()}><Label>Datei</Label><input type="file" className="h-9 rounded-lg border px-2 py-1 text-sm" onChange={(event) => setFile(event.target.files?.[0] ?? null)} />{fieldErrors.file && <p className="text-xs text-red-600">{fieldErrors.file}</p>}</div>}
          <div className={fieldClass()}><Label>Tags</Label><Input value={tags} onChange={(event) => setTags(event.target.value)} placeholder="cb-funk, schaltplan" /></div>
          <div className="grid gap-2 sm:col-span-2"><Label>Beschreibung</Label><textarea className="min-h-24 rounded-lg border border-input p-2 text-sm" value={payload.description} onChange={(event) => setPayload({ ...payload, description: event.target.value })} /></div>
          {selectedManufacturer && filteredDevices.length === 0 && (
            <p className="text-sm text-amber-700 sm:col-span-2">
              Für {selectedManufacturer.name} existiert noch kein Gerät. Dokumente wie Schaltpläne oder Service Manuals müssen einem Gerät zugeordnet werden.
            </p>
          )}
          {error && <p className="text-sm text-red-600 sm:col-span-2">{error}</p>}
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={pending}>Abbrechen</Button>
          <Button onClick={submit} disabled={pending}>Speichern</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

export function KnowledgeNoteFormDialog({
  open,
  note,
  manufacturers,
  devices,
  pending,
  error,
  onOpenChange,
  onSubmit,
}: {
  open: boolean;
  note: KnowledgeNote | null;
  manufacturers: KnowledgeManufacturer[];
  devices: KnowledgeDevice[];
  pending: boolean;
  error: string;
  onOpenChange: (open: boolean) => void;
  onSubmit: (payload: NotePayload) => void;
}) {
  const [payload, setPayload] = useState<NotePayload>({ manufacturer_id: null, device_id: null, title: "", content: "", note_type: "general", severity: "", tags: [] });
  const [tags, setTags] = useState("");

  useEffect(() => {
    queueMicrotask(() => {
      setPayload(note ? {
        manufacturer_id: note.manufacturer_id,
        device_id: note.device_id,
        title: note.title,
        content: note.content,
        note_type: note.note_type,
        severity: note.severity,
        tags: note.tags,
      } : { manufacturer_id: null, device_id: null, title: "", content: "", note_type: "general", severity: "", tags: [] });
      setTags(note ? tagsToText(note.tags) : "");
    });
  }, [note, open]);

  const filteredDevices = payload.manufacturer_id ? devices.filter((device) => device.manufacturer_id === payload.manufacturer_id) : devices;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-3xl">
        <DialogHeader><DialogTitle>{note ? "Notiz bearbeiten" : "Notiz erstellen"}</DialogTitle></DialogHeader>
        <div className="grid gap-4 sm:grid-cols-2">
          <div className={fieldClass()}><Label>Hersteller</Label><select className="h-9 rounded-lg border px-2 text-sm" value={payload.manufacturer_id ?? ""} onChange={(event) => setPayload({ ...payload, manufacturer_id: event.target.value ? Number(event.target.value) : null, device_id: null })}><option value="">Kein Hersteller</option>{manufacturers.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}</select></div>
          <div className={fieldClass()}><Label>Gerät</Label><select className="h-9 rounded-lg border px-2 text-sm" value={payload.device_id ?? ""} onChange={(event) => setPayload({ ...payload, device_id: event.target.value ? Number(event.target.value) : null })}><option value="">Kein Gerät</option>{filteredDevices.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}</select></div>
          <div className={fieldClass()}><Label>Titel</Label><Input value={payload.title} onChange={(event) => setPayload({ ...payload, title: event.target.value })} /></div>
          <div className={fieldClass()}><Label>Typ</Label><select className="h-9 rounded-lg border px-2 text-sm" value={payload.note_type} onChange={(event) => setPayload({ ...payload, note_type: event.target.value as NoteType })}>{noteTypes.map(([value, label]) => <option key={value} value={value}>{label}</option>)}</select></div>
          <div className={fieldClass()}><Label>Schweregrad</Label><select className="h-9 rounded-lg border px-2 text-sm" value={payload.severity} onChange={(event) => setPayload({ ...payload, severity: event.target.value as NotePayload["severity"] })}><option value="">Keiner</option><option value="low">Niedrig</option><option value="medium">Mittel</option><option value="high">Hoch</option><option value="critical">Kritisch</option></select></div>
          <div className={fieldClass()}><Label>Tags</Label><Input value={tags} onChange={(event) => setTags(event.target.value)} /></div>
          <div className="grid gap-2 sm:col-span-2"><Label>Inhalt</Label><textarea className="min-h-40 rounded-lg border border-input p-2 text-sm" value={payload.content} onChange={(event) => setPayload({ ...payload, content: event.target.value })} /></div>
          {error && <p className="text-sm text-red-600 sm:col-span-2">{error}</p>}
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={pending}>Abbrechen</Button>
          <Button onClick={() => onSubmit({ ...payload, tags: textToTags(tags) })} disabled={pending}>Speichern</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
