'use client';

import {
  useCallback,
  useEffect,
  useState,
  ChangeEvent,
  Dispatch,
  SetStateAction,
} from 'react';
import Modal from '@/components/ui/Modal';
import { PencilIcon, CheckCircleIcon } from '@heroicons/react/24/solid';
import DeviceHistorySidebar from './DeviceHistorySidebar';
import TagMultiCombobox, { TagOption } from '@/components/ui/TagMultiCombobox';
import Button from '@/components/ui/Button';
import Tabs from '@/components/ui/Tabs';
import type { DeviceDetail } from './page';
import { Dropdown } from '@/components/ui/Dropdown';
import AppCombobox from '@/components/ui/Combobox';


type DeviceEditModalProps = {
  open: boolean;
  inventoryNumber: string | null;
  onClose: () => void;
  onSaved: (device: DeviceDetail) => void;
  allTags: TagOption[];
  setAllTags: Dispatch<SetStateAction<TagOption[]>>;
};

type DeviceOption = {
  inventoryNumber: string;
  name: string;
};

export default function DeviceEditModal({
  open,
  inventoryNumber,
  onClose,
  onSaved,
  allTags,
  setAllTags,
}: DeviceEditModalProps) {
  const [editDevice, setEditDevice] = useState<DeviceDetail | null>(null);
  const [editLoading, setEditLoading] = useState(false);
  const [editError, setEditError] = useState<string | null>(null);
  const [saveLoading, setSaveLoading] = useState(false);
  const [justSaved, setJustSaved] = useState(false);
  const [historyRefresh, setHistoryRefresh] = useState(0);
  
  const [deviceOptions, setDeviceOptions] = useState<DeviceOption[]>([]);
  const [optionsLoading, setOptionsLoading] = useState(false);
  const [optionsError, setOptionsError] = useState<string | null>(null);

  // 👇 NEU: Tabs im Edit-Modal
  const [activeTab, setActiveTab] =
    useState<'fields' | 'relations'>('fields');

  useEffect(() => {
    if (!open || !inventoryNumber) return;

    const inv = inventoryNumber;
    let cancelled = false;

    setEditLoading(true);
    setEditError(null);
    setJustSaved(false);
    setEditDevice(null);

    async function loadDevice() {
      try {
        const res = await fetch(
          `/api/devices/${encodeURIComponent(inv)}`,
          {
            method: 'GET',
            headers: { 'Content-Type': 'application/json' },
            cache: 'no-store',
          },
        );

        if (!res.ok) {
          if (res.status === 404) {
            throw new Error('Gerät wurde nicht gefunden.');
          }
          throw new Error(
            'Beim Laden der Gerätedaten ist ein Fehler aufgetreten.',
          );
        }

        const data = (await res.json()) as DeviceDetail;
        if (!cancelled) {
          setEditDevice(data);
        }
      } catch (err: any) {
        console.error('Error loading device', err);
        if (!cancelled) {
          setEditError(
            err instanceof Error
              ? err.message
              : 'Netzwerkfehler beim Laden der Gerätedaten.',
          );
        }
      } finally {
        if (!cancelled) {
          setEditLoading(false);
        }
      }
    }

    loadDevice();

    return () => {
      cancelled = true;
    };
  }, [open, inventoryNumber]);

  useEffect(() => {
    if (!justSaved) return;

    const id = setTimeout(() => {
      setJustSaved(false);
    }, 1500);

    return () => clearTimeout(id);
  }, [justSaved]);

  useEffect(() => {
    if (!open) return;

    let cancelled = false;
    setOptionsLoading(true);
    setOptionsError(null);

    async function loadDeviceOptions() {
      try {
        const res = await fetch('/api/devices', {
          method: 'GET',
          headers: { 'Content-Type': 'application/json' },
          cache: 'no-store',
        });

        if (!res.ok) {
          throw new Error('Geräteliste konnte nicht geladen werden.');
        }

        const data = await res.json() as {
          inventoryNumber: string;
          name: string;
        }[];

        if (!cancelled) {
          setDeviceOptions(data);
        }
      } catch (err: any) {
        console.error('Error loading device options', err);
        if (!cancelled) {
          setOptionsError(
            err instanceof Error
              ? err.message
              : 'Netzwerkfehler beim Laden der Geräteliste.',
          );
        }
      } finally {
        if (!cancelled) {
          setOptionsLoading(false);
        }
      }
    }

    loadDeviceOptions();
    return () => {
      cancelled = true;
    };
  }, [open]);

  const handleFieldChange = (
    field: keyof DeviceDetail,
    e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
  ) => {
    const value = e.target.value;
    setEditDevice((prev) =>
      prev ? ({ ...prev, [field]: value } as DeviceDetail) : prev,
    );
  };

  const handleSave = useCallback(async () => {
    if (!editDevice) return;

    setSaveLoading(true);
    setEditError(null);

    try {
      const res = await fetch(
        `/api/devices/${encodeURIComponent(
          editDevice.inventoryNumber,
        )}`,
        {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            name: editDevice.name,
            manufacturer: editDevice.manufacturer,
            model: editDevice.model,
            serialNumber: editDevice.serialNumber || null,
            productNumber: editDevice.productNumber || null,
            comment: editDevice.comment || null,
            group: editDevice.group || null,
            location: editDevice.location || null,
            ipv4Address: editDevice.ipv4Address || null,
            ipv6Address: editDevice.ipv6Address || null,
            macAddress: editDevice.macAddress || null,
            username: editDevice.username || null,
            passwordHash: editDevice.passwordHash || null,
            tags: editDevice.tags ?? [],
            // 👇 NEU: Hauptgerät speichern
            parentInventoryNumber:
              editDevice.parentInventoryNumber?.trim() || null,
          }),
        },
      );

      if (!res.ok) {
        if (res.status === 404) {
          throw new Error('Gerät wurde nicht gefunden.');
        }
        throw new Error('Speichern der Änderungen ist fehlgeschlagen.');
      }

      const updated = (await res.json()) as DeviceDetail;
      setEditDevice(updated);
      onSaved(updated);

      setJustSaved(true);
      setHistoryRefresh((prev) => prev + 1);
    } catch (err: any) {
      console.error('Error saving device', err);
      setEditError(
        err instanceof Error
          ? err.message
          : 'Netzwerkfehler beim Speichern der Gerätedaten.',
      );
    } finally {
      setSaveLoading(false);
    }
  }, [editDevice, onSaved]);

  const handleClose = () => {
    if (saveLoading) return;
    onClose();
  };

  // 🔹 Hilfswerte für „Verknüpfungen“-Tab
  const hasParent = !!editDevice?.parentInventoryNumber;
  const hasAccessories =
    !!editDevice &&
    Array.isArray(editDevice.accessories) &&
    editDevice.accessories.length > 0;

  const relationRows =
    editDevice == null
      ? []
      : ([
          {
            role: hasParent ? 'Zubehör' : 'Hauptgerät',
            inventoryNumber: editDevice.inventoryNumber,
            name: editDevice.name ?? null,
          },
          ...(hasParent
            ? [
                {
                  role: 'Hauptgerät',
                  inventoryNumber:
                    editDevice.parentInventoryNumber!,
                  name: editDevice.parentName ?? null,
                },
              ]
            : []),
          ...(hasAccessories
            ? editDevice.accessories!.map((acc) => ({
                role: 'Zubehör',
                inventoryNumber: acc.inventoryNumber,
                name: acc.name ?? null,
              }))
            : []),
        ] satisfies {
          role: string;
          inventoryNumber: string;
          name: string | null;
        }[]);

  // Geräte, die als Hauptgerät in Frage kommen (nicht das Gerät selbst)
  const selectableParents =
    editDevice == null
      ? []
      : deviceOptions.filter(
          (d) => d.inventoryNumber !== editDevice.inventoryNumber,
        );

  // Spezielle Option "kein Hauptgerät"
  const noParentOption: DeviceOption = {
    inventoryNumber: '__NONE__',
    name: 'Kein Hauptgerät (eigenständiges Gerät)',
  };

  const parentOptions: DeviceOption[] = [noParentOption, ...selectableParents];

  // Welche Option ist aktuell gewählt?
  const selectedParentOption: DeviceOption =
    editDevice && editDevice.parentInventoryNumber
      ? parentOptions.find(
          (d) =>
            d.inventoryNumber === editDevice.parentInventoryNumber,
        ) ?? noParentOption
      : noParentOption;


  return (
    <Modal
      open={open}
      onClose={handleClose}
      title={
        editDevice
          ? `Gerät bearbeiten: ${editDevice.name}`
          : 'Gerätedaten werden geladen …'
      }
      icon={<PencilIcon className="size-6" />}
      tone={justSaved ? 'success' : 'info'}
      variant="centered"
      size="xl"
      footer={
        <div className="px-4 py-3 sm:px-6">
          <div className="flex flex-col gap-3 sm:flex-row-reverse">
            <Button
              type="button"
              onClick={handleSave}
              size="lg"
              variant="primary"
              tone={justSaved ? 'emerald' : 'indigo'}
              disabled={saveLoading}
              className="w-full sm:flex-1"
              icon={
                justSaved ? (
                  <CheckCircleIcon
                    aria-hidden="true"
                    className="-ml-0.5 size-5"
                  />
                ) : undefined
              }
              iconPosition="leading"
            >
              {saveLoading
                ? 'Speichern …'
                : justSaved
                ? 'Gespeichert'
                : 'Speichern'}
            </Button>

            <Button
              type="button"
              onClick={handleClose}
              size="lg"
              variant="secondary"
              tone="gray"
              className="w-full sm:flex-1"
            >
              Abbrechen
            </Button>
          </div>
        </div>
      }
      sidebar={
        editDevice ? (
          <DeviceHistorySidebar
            key={editDevice.updatedAt}
            inventoryNumber={editDevice.inventoryNumber}
            asSidebar
            refreshToken={historyRefresh}
          />
        ) : undefined
      }
    >
      {editLoading && (
        <p className="text-sm text-gray-500 dark:text-gray-400">
          Gerätedaten werden geladen …
        </p>
      )}

      {editError && (
        <p className="text-sm text-red-600 dark:text-red-400">
          {editError}
        </p>
      )}

      {!editLoading && !editError && editDevice && (
        <div className="pr-2 mt-3 text-sm">
          {/* 🔹 Tabs im Edit-Body */}
          <Tabs
            tabs={[
              { id: 'fields', label: 'Stammdaten' },
              { id: 'relations', label: 'Zubehör' },
            ]}
            value={activeTab}
            onChange={(id) => setActiveTab(id as 'fields' | 'relations')}
            ariaLabel="Bearbeitungsansicht wählen"
          />

          {/* TAB 1: Stammdaten (dein bisheriges Grid) */}
          {activeTab === 'fields' && (
            <div className="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2">
              {/* Inventarnummer */}
              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Inventar-Nr.
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-400 shadow-xs ring-1 ring-inset ring-gray-800"
                  value={editDevice.inventoryNumber}
                  readOnly
                />
              </div>

              {/* Bezeichnung */}
              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Bezeichnung
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.name ?? ""}
                  onChange={(e) => handleFieldChange('name', e)}
                />
              </div>

              {/* Hersteller / Modell */}
              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Hersteller
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.manufacturer ?? ""}
                  onChange={(e) =>
                    handleFieldChange('manufacturer', e)
                  }
                />
              </div>

              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Modell
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.model ?? ""}
                  onChange={(e) => handleFieldChange('model', e)}
                />
              </div>

              {/* Seriennummer / Produktnummer */}
              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Seriennummer
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.serialNumber ?? ''}
                  onChange={(e) =>
                    handleFieldChange('serialNumber', e)
                  }
                />
              </div>

              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Produktnummer
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.productNumber ?? ''}
                  onChange={(e) =>
                    handleFieldChange('productNumber', e)
                  }
                />
              </div>

              {/* Standort / Gruppe */}
              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Standort / Raum
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.location ?? ''}
                  onChange={(e) => handleFieldChange('location', e)}
                />
              </div>

              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Gruppe
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.group ?? ''}
                  onChange={(e) => handleFieldChange('group', e)}
                />
              </div>

              {/* Netzwerkdaten */}
              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  IPv4-Adresse
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.ipv4Address ?? ''}
                  onChange={(e) =>
                    handleFieldChange('ipv4Address', e)
                  }
                />
              </div>

              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  IPv6-Adresse
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.ipv6Address ?? ''}
                  onChange={(e) =>
                    handleFieldChange('ipv6Address', e)
                  }
                />
              </div>

              <div className="sm:col-span-2">
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  MAC-Adresse
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.macAddress ?? ''}
                  onChange={(e) =>
                    handleFieldChange('macAddress', e)
                  }
                />
              </div>

              {/* Zugangsdaten */}
              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Benutzername
                </p>
                <input
                  type="text"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.username ?? ''}
                  onChange={(e) =>
                    handleFieldChange('username', e)
                  }
                />
              </div>

              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Passwort
                </p>
                <input
                  type="password"
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.passwordHash ?? ''}
                  onChange={(e) =>
                    handleFieldChange('passwordHash', e)
                  }
                />
              </div>

              {/* Tags */}
              <div className="sm:col-span-2">
                <TagMultiCombobox
                  label="Tags"
                  availableTags={allTags}
                  value={(editDevice.tags ?? []).map((name) => ({
                    name,
                  }))}
                  onChange={(next) => {
                    const names = next.map((t) => t.name);

                    setEditDevice((prev) =>
                      prev
                        ? ({
                            ...prev,
                            tags: names,
                          } as DeviceDetail)
                        : prev,
                    );

                    setAllTags((prev) => {
                      const map = new Map(
                        prev.map((t) => [
                          t.name.toLowerCase(),
                          t,
                        ]),
                      );
                      for (const t of next) {
                        const key = t.name.toLowerCase();
                        if (!map.has(key)) {
                          map.set(key, t);
                        }
                      }
                      return Array.from(map.values());
                    });
                  }}
                  placeholder="z.B. Drucker, Serverraum, kritisch"
                />
              </div>

              {/* Kommentar */}
              <div className="sm:col-span-2">
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Kommentar
                </p>
                <textarea
                  rows={3}
                  className="mt-1 block w-full rounded-md border-0 bg-gray-900/40 px-2.5 py-1.5 text-sm text-gray-100 shadow-xs ring-1 ring-inset ring-gray-700 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none"
                  value={editDevice.comment ?? ''}
                  onChange={(e) =>
                    handleFieldChange('comment', e)
                  }
                />
              </div>
            </div>
          )}

          {/* TAB 2: Hauptgerät & Zubehör */}
          {activeTab === 'relations' && (
            <div className="mt-4 space-y-4 text-sm">
              {/* Combobox: Hauptgerät (Inventar-Nr.) */}
              <div className="w-full">
                <AppCombobox<DeviceOption>
                  label="Hauptgerät"
                  options={parentOptions}
                  value={selectedParentOption}
                  onChange={(selected) => {
                    setEditDevice((prev) => {
                      if (!prev || !selected) return prev;

                      // Spezialfall: "kein Hauptgerät"
                      if (selected.inventoryNumber === '__NONE__') {
                        return {
                          ...prev,
                          parentInventoryNumber: null,
                          parentName: null,
                        } as DeviceDetail;
                      }

                      return {
                        ...prev,
                        parentInventoryNumber: selected.inventoryNumber,
                        parentName: selected.name,
                      } as DeviceDetail;
                    });
                  }}
                  getKey={(d) => d.inventoryNumber}
                  getPrimaryLabel={(d) => d.name}
                  placeholder={
                    optionsLoading
                      ? 'Hauptgerät wird geladen …'
                      : 'Hauptgerät auswählen …'
                  }
                  allowCreateFromQuery={false}
                />

                {optionsLoading && (
                  <p className="mt-1 text-xs text-gray-500">
                    Geräteliste wird geladen …
                  </p>
                )}

                {optionsError && (
                  <p className="mt-1 text-xs text-rose-400">
                    {optionsError}
                  </p>
                )}

                {!optionsLoading && !optionsError && (
                  <p className="mt-1 text-xs text-gray-500">
                    Wähle ein Hauptgerät aus oder lasse "Kein Hauptgerät" ausgewählt, wenn dieses Gerät eigenständig ist.
                  </p>
                )}
              </div>


              {/* Tabelle mit aktuellen Beziehungen */}
              <div>
                <p className="text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Aktuelle Verknüpfungen
                </p>

                <div className="mt-2 overflow-x-auto rounded-md border border-gray-700">
                  <table className="min-w-full divide-y divide-gray-700 text-xs">
                    <thead className="bg-gray-800/80">
                      <tr>
                        <th className="px-3 py-2 text-left font-medium text-gray-200">
                          Rolle
                        </th>
                        <th className="px-3 py-2 text-left font-medium text-gray-200">
                          Inventar-Nr.
                        </th>
                        <th className="px-3 py-2 text-left font-medium text-gray-200">
                          Bezeichnung
                        </th>
                      </tr>
                    </thead>
                    <tbody className="divide-y divide-gray-700 bg-gray-900/60">
                      {relationRows.map((row) => (
                        <tr
                          key={`${row.role}-${row.inventoryNumber}`}
                        >
                          <td className="px-3 py-2 text-gray-200">
                            {row.role}
                          </td>
                          <td className="px-3 py-2 text-gray-100 font-medium">
                            {row.inventoryNumber}
                          </td>
                          <td className="px-3 py-2 text-gray-200">
                            {row.name || '–'}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>

                {!hasAccessories && hasParent && (
                  <p className="mt-2 text-xs text-gray-500">
                    Dieses Gerät ist Zubehör zu einem Hauptgerät,
                    hat aber selbst kein weiteres Zubehör.
                  </p>
                )}

                {hasAccessories && !hasParent && (
                  <p className="mt-2 text-xs text-gray-500">
                    Dieses Gerät ist ein Hauptgerät und besitzt die
                    oben aufgeführten Zubehör-Geräte.
                  </p>
                )}
              </div>
            </div>
          )}
        </div>
      )}
    </Modal>
  );
}
