"use client";

import { Plus, Trash2 } from "lucide-react";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { deletePosition } from "@/actions/positions";
import { Button } from "@/components/ui/Button";
import { useToast } from "@/components/ui/Toast";
import { fmtDate } from "@/lib/format";
import type { OpenPositionResolved } from "@/lib/positions";
import { CreatePositionModal, type UnitOption } from "./CreatePositionModal";
import { EditPositionModal } from "./EditPositionModal";

type OpenPositionWithDays = OpenPositionResolved & { daysOpen: number };

type PositionsPageClientProps = {
  openPositions: OpenPositionWithDays[];
  units: UnitOption[];
};

export function PositionsPageClient({ openPositions, units }: PositionsPageClientProps) {
  const { showToast } = useToast();
  const router = useRouter();
  const [createOpen, setCreateOpen] = useState(false);
  const [editing, setEditing] = useState<OpenPositionWithDays | null>(null);
  const [deletingId, setDeletingId] = useState<string | null>(null);

  // Getrennt, weil es zwei verschiedene Aussagen sind: „hier fehlt jemand"
  // und „das entsteht erst". In einer Liste vermischt liest sich eine
  // Planstelle zum 01.10. wie eine Vakanz, um die sich niemand kümmert.
  const offen = openPositions.filter((p) => !p.future);
  const kuenftig = openPositions.filter((p) => p.future);

  async function handleDelete(id: string) {
    setDeletingId(id);
    const result = await deletePosition(id);
    setDeletingId(null);
    if (result.success) {
      showToast("Planstelle entfernt.");
      router.refresh();
    } else {
      showToast(result.error ?? "Fehler beim Löschen.", "error");
    }
  }

  function Karte({ p }: { p: OpenPositionWithDays }) {
    return (
      <div className="relative flex flex-col rounded border border-border transition-colors focus-within:border-brand-500 hover:border-brand-500">
        {/* Die ganze Karte öffnet den Änderungsdialog; der Papierkorb liegt
            absolut darüber. Ein Knopf im Knopf wäre ungültiges HTML und mit
            der Tastatur nicht erreichbar. */}
        <button
          type="button"
          onClick={() => setEditing(p)}
          aria-label={`Planstelle ${p.position_number} (${p.title}) ändern`}
          className="flex flex-col items-start rounded p-3 pr-10 text-left
                     focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-500"
        >
          <span className="text-sm font-semibold text-ink">{p.title}</span>
          <span className="text-xs text-ink-muted">
            {p.position_number} · {p.orgLabel}
          </span>
          <span className="mt-1 text-xs text-ink-muted">
            {p.is_chief ? "Leitungsplanstelle · " : ""}
            {p.future ? `gültig ab ${fmtDate(p.valid_from)}` : `seit ${p.daysOpen} Tagen unbesetzt`}
          </span>
          {p.valid_to && <span className="text-xs font-semibold text-warning-text">endet am {fmtDate(p.valid_to)}</span>}
          {p.managerName && <span className="text-xs text-ink-muted">berichtet an {p.managerName}</span>}
        </button>

        <Button
          variant="icon"
          onClick={() => handleDelete(p.id)}
          pending={deletingId === p.id}
          aria-label={`Planstelle ${p.position_number} (${p.title}) entfernen`}
          className="absolute right-2 top-2 hover:!text-danger-solid"
        >
          <Trash2 className="h-3.5 w-3.5" />
        </Button>
      </div>
    );
  }

  return (
    <div className="flex flex-col gap-6">
      <section className="rounded border border-border bg-white p-4">
        <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
          <h2 className="text-sm font-bold text-ink">Unbesetzte Planstellen ({offen.length})</h2>
          <Button onClick={() => setCreateOpen(true)}>
            <Plus className="h-4 w-4" />
            Planstelle anlegen
          </Button>
        </div>
        {offen.length === 0 ? (
          <p className="text-sm text-ink-muted">Derzeit ist jede geltende Planstelle besetzt oder vergeben.</p>
        ) : (
          <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3">
            {offen.map((p) => (
              <Karte key={p.id} p={p} />
            ))}
          </div>
        )}
      </section>

      {kuenftig.length > 0 && (
        <section className="rounded border border-border bg-white p-4">
          <h2 className="text-sm font-bold text-ink">Künftige Planstellen ({kuenftig.length})</h2>
          <p className="mb-3 mt-1 text-xs text-ink-muted">
            Beschlossen, aber noch nicht gültig. Sie zählen nicht als Vakanz und lassen sich bis zum Beginn ändern.
          </p>
          <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3">
            {kuenftig.map((p) => (
              <Karte key={p.id} p={p} />
            ))}
          </div>
        </section>
      )}

      <CreatePositionModal open={createOpen} onClose={() => setCreateOpen(false)} units={units} />
      {/* `key` sorgt dafür, dass React je Planstelle einen frischen Dialog
          baut — sonst blieben beim zweiten Öffnen die Werte des ersten
          stehen. */}
      {editing && (
        <EditPositionModal key={editing.id} position={editing} units={units} onClose={() => setEditing(null)} />
      )}
    </div>
  );
}
