// app/(app)/devices/LoanDeviceModal.tsx
'use client';

import { useEffect, useMemo, useState } from 'react';
import Modal from '@/components/ui/Modal';
import Button from '@/components/ui/Button';
import Dropdown, { type DropdownSection } from '@/components/ui/Dropdown';
import type { DeviceDetail } from './page';

type LoanDeviceModalProps = {
  open: boolean;
  onClose: () => void;
  device: DeviceDetail;
  /**
   * Wird nach erfolgreichem Speichern/Beenden aufgerufen,
   * damit der Parent den lokalen State aktualisieren kann.
   */
  onUpdated?: (patch: {
    loanedTo: string | null;
    loanedFrom: string | null;
    loanedUntil: string | null;
    loanComment: string | null;
  }) => void;
};

// gleiche Logik wie bei den User-Gruppen:
function getBaseGroupName(name: string): string {
  const trimmed = name.trim();
  if (!trimmed) return '';

  const beforeDash = trimmed.split('-')[0].trim() || trimmed;
  const withoutDigits = beforeDash.replace(/\d+$/, '').trim();

  return withoutDigits || beforeDash;
}

type LoanUserOption = {
  value: string;   // wird in loanedTo gespeichert (z.B. arbeitsname)
  label: string;   // Anzeige-Text im Dropdown
  group: string;   // Hauptgruppe (BaseKey)
};

type UsersApiGroup = {
  id: string;
  name: string;
  users: {
    nwkennung: string;
    arbeitsname: string;
    firstName: string | null;
    lastName: string | null;
  }[];
};

function toDateInputValue(iso: string | null | undefined): string {
  if (!iso) return '';
  const d = new Date(iso);
  if (isNaN(d.getTime())) return '';

  const year = d.getFullYear();
  const month = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');

  // lokale Datumskomponenten -> passend für <input type="date">
  return `${year}-${month}-${day}`;
}

function fromDateInputValue(v: string): string | null {
  if (!v) return null;
  // Wir nehmen 00:00 Uhr lokale Zeit; toISOString() speichert sauber in DB
  const d = new Date(v + 'T00:00:00');
  if (isNaN(d.getTime())) return null;
  return d.toISOString();
}

const dtf = new Intl.DateTimeFormat('de-DE', {
  dateStyle: 'short',
});

// "heute" im <input type="date">-Format
function todayInputDate(): string {
  const d = new Date();
  const year = d.getFullYear();
  const month = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`; // z.B. 2025-02-19
}

export default function LoanDeviceModal({
  open,
  onClose,
  device,
  onUpdated,
}: LoanDeviceModalProps) {
  const [loanedTo, setLoanedTo] = useState('');
  const [loanedFrom, setLoanedFrom] = useState('');
  const [loanedUntil, setLoanedUntil] = useState('');
  const [loanComment, setLoanComment] = useState('');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const [userOptions, setUserOptions] = useState<LoanUserOption[]>([]);
  const [optionsLoading, setOptionsLoading] = useState(false);
  const [optionsError, setOptionsError] = useState<string | null>(null);

  // Beim Öffnen / Gerätewechsel Felder setzen
  useEffect(() => {
    if (!open) return;

    const existingFrom = toDateInputValue(device.loanedFrom);
    const nextLoanedFrom = existingFrom || todayInputDate();

    setLoanedTo(device.loanedTo ?? '');
    setLoanedFrom(nextLoanedFrom);
    setLoanedUntil(toDateInputValue(device.loanedUntil));
    setLoanComment(device.loanComment ?? '');
    setError(null);
  }, [
    open,
    device.inventoryNumber,
    device.loanedFrom,
    device.loanedUntil,
    device.loanComment,
    device.loanedTo,
  ]);

  // Beim Öffnen User für Dropdown laden (nur User aus Gruppen, gruppiert nach Hauptgruppen)
  useEffect(() => {
    if (!open) return;

    async function loadUsers() {
      setOptionsLoading(true);
      setOptionsError(null);
      try {
        const res = await fetch('/api/users');
        if (!res.ok) {
          throw new Error(`Fehler beim Laden der Benutzer (HTTP ${res.status})`);
        }

        const data = await res.json();
        const groups = (data.groups ?? []) as UsersApiGroup[];

        const opts: LoanUserOption[] = [];

        for (const g of groups) {
          const mainGroup = getBaseGroupName(g.name) || g.name;
          for (const u of g.users ?? []) {
            if (!u.arbeitsname) continue;

            const nameParts: string[] = [u.arbeitsname];
            const extra: string[] = [];
            if (u.firstName) extra.push(u.firstName);
            if (u.lastName) extra.push(u.lastName);
            if (extra.length) {
              nameParts.push('– ' + extra.join(' '));
            }

            opts.push({
              value: u.arbeitsname, // in loanedTo speichern wir weiterhin den Arbeitsnamen
              label: nameParts.join(' '),
              group: mainGroup,
            });
          }
        }

        // bestehenden Wert, der kein User ist, als "Andere"-Option anhängen
        const currentLoanedTo = device.loanedTo ?? '';
        if (
          currentLoanedTo &&
          !opts.some((o) => o.value === currentLoanedTo)
        ) {
          opts.push({
            value: currentLoanedTo,
            label: `${currentLoanedTo} (bisheriger Eintrag)`,
            group: 'Andere',
          });
        }

        // sortieren: erst nach Gruppe, dann nach Label
        opts.sort((a, b) => {
          const gComp = a.group.localeCompare(b.group, 'de');
          if (gComp !== 0) return gComp;
          return a.label.localeCompare(b.label, 'de');
        });

        setUserOptions(opts);
      } catch (err) {
        console.error('Fehler beim Laden der Benutzerliste für Verleih', err);
        setOptionsError('Empfängerliste konnte nicht geladen werden.');
      } finally {
        setOptionsLoading(false);
      }
    }

    loadUsers();
  }, [open, device.loanedTo]);

  // Optionen nach Hauptgruppe gruppieren
  const groupedOptions = useMemo(() => {
    const map = new Map<string, LoanUserOption[]>();

    for (const opt of userOptions) {
      const key = opt.group || 'Andere';
      if (!map.has(key)) {
        map.set(key, []);
      }
      map.get(key)!.push(opt);
    }

    return Array.from(map.entries()).sort(([a], [b]) =>
      a.localeCompare(b, 'de'),
    );
  }, [userOptions]);

  // Dropdown-Sektionen für deine Dropdown-Komponente
  const dropdownSections = useMemo<DropdownSection[]>(() => {
    const sections: DropdownSection[] = [];

    // Erste Sektion: Zurücksetzen / keine Auswahl
    sections.push({
      id: 'base',
      items: [
        {
          id: 'none',
          label: '— Bitte auswählen —',
          onClick: () => setLoanedTo(''),
        },
      ],
    });

    // Danach je Hauptgruppe eine eigene Sektion mit Label als Trenner
    for (const [groupName, opts] of groupedOptions) {
      sections.push({
        id: groupName,
        label: groupName,              // <-- wird als Trenner angezeigt
        items: opts.map((opt) => ({
          id: `${groupName}-${opt.value}`,
          label: opt.label,            // <-- nur der Name, ohne Gruppen-Präfix
          onClick: () => setLoanedTo(opt.value),
        })),
      });
    }

    return sections;
  }, [groupedOptions, setLoanedTo]);

  // Aktuell ausgewähltes Label für den Trigger-Button
  const currentSelected = useMemo(
    () => userOptions.find((o) => o.value === loanedTo) ?? null,
    [userOptions, loanedTo],
  );

  const dropdownLabel =
    currentSelected?.label || (loanedTo || 'Bitte auswählen …');

  const isLoaned = !!device.loanedTo;

  async function saveLoan() {
    if (!device.inventoryNumber) return;

    if (!loanedTo.trim()) {
      setError('Bitte einen Empfänger (an wen) auswählen.');
      return;
    }

    setSaving(true);
    setError(null);

    try {
      const res = await fetch(
        `/api/devices/${encodeURIComponent(device.inventoryNumber)}`,
        {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            // ⚠️ PATCH-Route erwartet alle Felder, nicht nur Verleihfelder!
            name: device.name,
            manufacturer: device.manufacturer,
            model: device.model,
            serialNumber: device.serialNumber,
            productNumber: device.productNumber,
            comment: device.comment,
            ipv4Address: device.ipv4Address,
            ipv6Address: device.ipv6Address,
            macAddress: device.macAddress,
            username: device.username,
            passwordHash: (device as any).passwordHash ?? null,
            group: device.group,
            location: device.location,
            tags: device.tags ?? [],

            // Verleihfelder
            loanedTo: loanedTo.trim(),
            loanedFrom: fromDateInputValue(loanedFrom),
            loanedUntil: fromDateInputValue(loanedUntil),
            loanComment: loanComment.trim() || null,
          }),
        },
      );

      if (!res.ok) {
        const data = await res.json().catch(() => null);
        throw new Error(
          data?.error ?? `Fehler beim Speichern (HTTP ${res.status})`,
        );
      }

      const patch = {
        loanedTo: loanedTo.trim(),
        loanedFrom: fromDateInputValue(loanedFrom),
        loanedUntil: fromDateInputValue(loanedUntil),
        loanComment: loanComment.trim() || null,
      };

      onUpdated?.(patch);
      onClose();
    } catch (err: any) {
      console.error('Error saving loan', err);
      setError(
        err instanceof Error
          ? err.message
          : 'Fehler beim Speichern des Verleihstatus.',
      );
    } finally {
      setSaving(false);
    }
  }

  async function endLoan() {
    if (!device.inventoryNumber) return;

    setSaving(true);
    setError(null);

    try {
      const res = await fetch(
        `/api/devices/${encodeURIComponent(device.inventoryNumber)}`,
        {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            // Alle bisherigen Felder durchreichen
            name: device.name,
            manufacturer: device.manufacturer,
            model: device.model,
            serialNumber: device.serialNumber,
            productNumber: device.productNumber,
            comment: device.comment,
            ipv4Address: device.ipv4Address,
            ipv6Address: device.ipv6Address,
            macAddress: device.macAddress,
            username: device.username,
            passwordHash: (device as any).passwordHash ?? null,
            group: device.group,
            location: device.location,
            tags: device.tags ?? [],

            // Verleih zurücksetzen
            loanedTo: null,
            loanedFrom: null,
            loanedUntil: null,
            loanComment: null,
          }),
        },
      );

      if (!res.ok) {
        const data = await res.json().catch(() => null);
        throw new Error(
          data?.error ?? `Fehler beim Beenden des Verleihs (HTTP ${res.status})`,
        );
      }

      onUpdated?.({
        loanedTo: null,
        loanedFrom: null,
        loanedUntil: null,
        loanComment: null,
      });

      onClose();
    } catch (err: any) {
      console.error('Error ending loan', err);
      setError(
        err instanceof Error
          ? err.message
          : 'Fehler beim Beenden des Verleihs.',
      );
    } finally {
      setSaving(false);
    }
  }

  const title = isLoaned
    ? `Verleih bearbeiten – ${device.name}`
    : `Gerät verleihen – ${device.name}`;

  return (
    <Modal
      open={open}
      onClose={onClose}
      title={title}
      tone={isLoaned ? 'warning' : 'info'}
      variant="centered"
      size="md"
      primaryAction={{
        label: saving
          ? 'Speichere …'
          : isLoaned
          ? 'Verleih aktualisieren'
          : 'Gerät verleihen',
        onClick: saveLoan,
        variant: 'primary',
      }}
      secondaryAction={{
        label: 'Abbrechen',
        onClick: onClose,
        variant: 'secondary',
      }}
      useGrayFooter
    >
      <div className="space-y-4 text-sm">
        {/* Aktueller Verleih-Hinweis mit deutlich sichtbarem „Verleih beenden“ */}
        {isLoaned && (
          <div className="rounded-md border border-amber-300 bg-amber-50 px-3 py-3 text-xs text-amber-900 dark:border-amber-700/70 dark:bg-amber-950/40 dark:text-amber-50">
            <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
              <div>
                <p className="text-[11px] font-semibold uppercase tracking-wide">
                  Verliehen an
                </p>
                <p className="mt-0.5">
                  <span className="font-medium">{device.loanedTo}</span>
                  {device.loanedFrom && (
                    <>
                      {' '}seit{' '}
                      {dtf.format(new Date(device.loanedFrom))}
                    </>
                  )}
                  {device.loanedUntil && (
                    <>
                      {' '}bis{' '}
                      {dtf.format(new Date(device.loanedUntil))}
                    </>
                  )}
                  {device.loanComment && (
                    <>
                      {' '}- Hinweis: {device.loanComment}
                    </>
                  )}
                </p>
              </div>

              <Button
                size="sm"
                variant="secondary"
                tone="gray"
                onClick={endLoan}
                disabled={saving}
              >
                Verleih beenden
              </Button>
            </div>
          </div>
        )}

        <p className="text-xs text-gray-500 dark:text-gray-400">
          {isLoaned
            ? 'Passe die Verleihdaten an oder beende den Verleih, wenn das Gerät zurückgegeben wurde.'
            : 'Lege fest, an wen das Gerät verliehen wird und in welchem Zeitraum.'}
        </p>

        {/* Formularfelder */}
        <div className="space-y-3 text-sm">
          <div>
            <label className="block text-xs font-medium text-gray-700 dark:text-gray-300">
              Verliehen an
            </label>

            <Dropdown
              label={dropdownLabel}
              ariaLabel="Empfänger auswählen"
              align="left"
              triggerVariant="button"
              disabled={optionsLoading || userOptions.length === 0}
              sections={dropdownSections}
              triggerClassName="mt-1 w-full justify-between"
            />

            {optionsLoading && (
              <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                Lade Benutzer …
              </p>
            )}
            {optionsError && (
              <p className="mt-1 text-xs text-red-600 dark:text-red-400">
                {optionsError}
              </p>
            )}
          </div>

          <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
            <div>
              <label className="block text-xs font-medium text-gray-700 dark:text-gray-300">
                Verliehen seit
              </label>
              <input
                type="date"
                className="mt-1 block w-full rounded-md border border-gray-300 bg-white px-2.5 py-1.5 text-sm text-gray-900 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100"
                value={loanedFrom}
                onChange={(e) => setLoanedFrom(e.target.value)}
              />
            </div>

            <div>
              <label className="block text-xs font-medium text-gray-700 dark:text-gray-300">
                Verliehen bis (optional)
              </label>
              <input
                type="date"
                className="mt-1 block w-full rounded-md border border-gray-300 bg-white px-2.5 py-1.5 text-sm text-gray-900 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100"
                value={loanedUntil}
                onChange={(e) => setLoanedUntil(e.target.value)}
              />
            </div>
          </div>

          <div>
            <label className="block text-xs font-medium text-gray-700 dark:text-gray-300">
              Hinweis / Kommentar (optional)
            </label>
            <textarea
              rows={3}
              className="mt-1 block w-full rounded-md border border-gray-300 bg-white px-2.5 py-1.5 text-sm text-gray-900 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100"
              value={loanComment}
              onChange={(e) => setLoanComment(e.target.value)}
            />
          </div>
        </div>

        {error && (
          <p className="text-xs text-red-600 dark:text-red-400">
            {error}
          </p>
        )}
      </div>
    </Modal>
  );
}
