"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { Icon } from "@/components/ui/Icon";
import { confirmDialog, alertDialog } from "@/components/ui/Dialog";
import {
  createPositionAction,
  deletePositionAction,
  setPositionActiveAction,
  updatePositionAction,
  type PositionInput,
} from "@/lib/forms/actions";
import {
  APPLICATION_CATEGORIES,
  APPLICATION_FIELD_TYPES,
  fieldKeyFrom,
  slugFrom,
} from "@/lib/forms/contract";
import type { PositionDTO } from "@/lib/forms/queries";

type DraftField = {
  /** Nur zum Zeichnen der Liste — nicht gespeichert. */
  uid: number;
  label: string;
  type: string;
  required: boolean;
  placeholder: string;
  optionsText: string;
};

let uidCounter = 0;
const newField = (): DraftField => ({
  uid: ++uidCounter,
  label: "",
  type: "text",
  required: false,
  placeholder: "",
  optionsText: "",
});

function toDraft(p: PositionDTO): DraftField[] {
  return p.fields.map((f) => ({
    uid: ++uidCounter,
    label: f.label,
    type: f.type,
    required: f.required,
    placeholder: f.placeholder,
    optionsText: f.options.join("\n"),
  }));
}

export function PositionsPanel({
  positions,
  canManage,
}: {
  positions: PositionDTO[];
  canManage: boolean;
}) {
  const router = useRouter();
  const [editing, setEditing] = useState<PositionDTO | "new" | null>(null);
  const [busy, setBusy] = useState<number | null>(null);

  const run = async (id: number, fn: () => Promise<{ error?: string }>) => {
    setBusy(id);
    const res = await fn();
    setBusy(null);
    if (res.error) await alertDialog({ title: "Fehler", message: res.error, danger: true });
    else router.refresh();
  };

  const remove = async (p: PositionDTO) => {
    const ok = await confirmDialog({
      title: `Stelle „${p.title}“ löschen?`,
      message:
        p.applicationCount > 0
          ? `${p.applicationCount} Bewerbung(en) bleiben erhalten und werden nur von dieser Stelle gelöst — Titel und Kategorie stehen in der Bewerbung selbst.`
          : "Die Ausschreibung verschwindet von der Website.",
      confirmLabel: "Löschen",
      danger: true,
    });
    if (!ok) return;
    await run(p.id, () => deletePositionAction(p.id));
  };

  return (
    <>
      <div className="mb-4 flex flex-wrap items-center justify-between gap-3">
        <p className="text-muted text-sm">
          {positions.length} Stelle(n) · {positions.filter((p) => p.isActive).length} auf der
          Website sichtbar
        </p>
        {canManage ? (
          <button className="btn btn-primary btn-sm" onClick={() => setEditing("new")}>
            <Icon name="plus" size={15} /> Neue Stelle
          </button>
        ) : null}
      </div>

      {positions.length === 0 ? (
        <div className="ui-empty">
          <span className="ui-empty-mark">
            <Icon name="list" size={26} />
          </span>
          <p className="ui-empty-title">Noch keine Stellen</p>
          <p className="ui-empty-text">
            Lege eine Ausschreibung an — sie erscheint samt Bewerbungsformular auf der Website.
          </p>
          {canManage ? (
            <div className="ui-empty-actions">
              <button className="btn btn-primary btn-sm" onClick={() => setEditing("new")}>
                <Icon name="plus" size={15} /> Neue Stelle
              </button>
            </div>
          ) : null}
        </div>
      ) : (
        <div className="rc-list">
          {positions.map((p) => (
            <article key={p.id} className="rc-item">
              <div className="rc-head" style={{ cursor: "default" }}>
                <span
                  className="rc-dot"
                  style={
                    p.isActive
                      ? undefined
                      : { background: "var(--muted)", boxShadow: "none", opacity: 0.5 }
                  }
                />
                <span className="min-w-0 flex-1">
                  <span className="rc-title block truncate">{p.title}</span>
                  <span className="rc-sub block truncate">
                    {APPLICATION_CATEGORIES[p.category] ?? p.category} · /{p.slug} · {p.fields.length}{" "}
                    Feld(er) · {p.applicationCount} Bewerbung(en)
                    {p.isActive ? "" : " · versteckt"}
                  </span>
                </span>
                {canManage ? (
                  <span className="flex shrink-0 items-center gap-1.5">
                    <button
                      className="pill"
                      data-active={p.isActive}
                      disabled={busy === p.id}
                      onClick={() => void run(p.id, () => setPositionActiveAction(p.id, !p.isActive))}
                      title={p.isActive ? "Von der Website nehmen" : "Auf der Website zeigen"}
                    >
                      {p.isActive ? "Sichtbar" : "Versteckt"}
                    </button>
                    <button className="btn btn-ghost btn-sm" onClick={() => setEditing(p)}>
                      <Icon name="edit" size={14} /> Bearbeiten
                    </button>
                    <button
                      className="btn btn-ghost btn-sm"
                      disabled={busy === p.id}
                      onClick={() => void remove(p)}
                      title="Löschen"
                    >
                      <Icon name="trash" size={14} />
                    </button>
                  </span>
                ) : null}
              </div>
              {p.summary ? (
                <div className="rc-body" style={{ paddingBottom: 12 }}>
                  <p className="text-muted text-sm">{p.summary}</p>
                </div>
              ) : null}
            </article>
          ))}
        </div>
      )}

      {editing ? (
        <PositionDrawer
          position={editing === "new" ? null : editing}
          onClose={() => setEditing(null)}
          onSaved={() => {
            setEditing(null);
            router.refresh();
          }}
        />
      ) : null}
    </>
  );
}

// ── Erstellen / Bearbeiten ────────────────────────────────────────────────

function PositionDrawer({
  position,
  onClose,
  onSaved,
}: {
  position: PositionDTO | null;
  onClose: () => void;
  onSaved: () => void;
}) {
  const isNew = position === null;
  const [title, setTitle] = useState(position?.title ?? "");
  const [category, setCategory] = useState(position?.category ?? "team");
  const [summary, setSummary] = useState(position?.summary ?? "");
  const [description, setDescription] = useState(position?.description ?? "");
  const [sortOrder, setSortOrder] = useState(String(position?.sortOrder ?? 0));
  const [isActive, setIsActive] = useState(position?.isActive ?? true);
  const [fields, setFields] = useState<DraftField[]>(
    position ? toDraft(position) : [newField()],
  );
  const [error, setError] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);

  const patch = (uid: number, next: Partial<DraftField>) =>
    setFields((list) => list.map((f) => (f.uid === uid ? { ...f, ...next } : f)));

  const move = (index: number, delta: number) =>
    setFields((list) => {
      const to = index + delta;
      if (to < 0 || to >= list.length) return list;
      const copy = [...list];
      const [item] = copy.splice(index, 1);
      copy.splice(to, 0, item);
      return copy;
    });

  const save = async () => {
    setError(null);
    const input: PositionInput = {
      title,
      category,
      summary,
      description,
      sortOrder: Number.parseInt(sortOrder, 10) || 0,
      isActive,
      fields: fields.map((f) => ({
        label: f.label,
        type: f.type,
        required: f.required,
        placeholder: f.placeholder,
        options: f.optionsText.split("\n").map((o) => o.trim()).filter(Boolean),
      })),
    };

    setSaving(true);
    const res = position
      ? await updatePositionAction(position.id, input)
      : await createPositionAction(input);
    setSaving(false);

    // Ein stiller Fehlschlag wäre das Schlimmste — hier bleibt der Entwurf stehen.
    if (res.error) {
      setError(res.error);
      return;
    }
    onSaved();
  };

  return (
    <div className="drawer-overlay" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
      <div className="drawer drawer-wide animate-in">
        <div className="mb-5 flex items-center justify-between">
          <span className="eyebrow">{isNew ? "Neue Stelle" : "Stelle bearbeiten"}</span>
          <button className="btn btn-ghost btn-sm" onClick={onClose} aria-label="Schließen">
            <Icon name="close" size={16} />
          </button>
        </div>

        {error ? <p className="field-error mb-3">{error}</p> : null}

        <div className="flex flex-col gap-4">
          <div className="field">
            <label className="label">Titel</label>
            <input
              className="input"
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              placeholder="z. B. Video-Editor (m/w/d)"
            />
            <p className="fb-key mt-1">
              Adresse auf der Website: /{title.trim() ? slugFrom(title) : "…"}
            </p>
          </div>

          <div className="fb-row" style={{ gridTemplateColumns: "minmax(0,1fr) minmax(0,1fr)" }}>
            <div className="field">
              <label className="label">Kategorie</label>
              <select
                className="select"
                value={category}
                onChange={(e) => setCategory(e.target.value)}
              >
                {Object.entries(APPLICATION_CATEGORIES).map(([key, label]) => (
                  <option key={key} value={key}>
                    {label}
                  </option>
                ))}
              </select>
            </div>
            <div className="field">
              <label className="label">Reihenfolge</label>
              <input
                className="input"
                type="number"
                value={sortOrder}
                onChange={(e) => setSortOrder(e.target.value)}
                placeholder="0"
              />
            </div>
          </div>

          <div className="field">
            <label className="label">Kurzfassung</label>
            <input
              className="input"
              value={summary}
              onChange={(e) => setSummary(e.target.value)}
              placeholder="Ein Satz für die Übersicht auf der Website"
              maxLength={255}
            />
          </div>

          <div className="field">
            <label className="label">Beschreibung</label>
            <textarea
              className="textarea"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="Aufgaben, Anforderungen, Arbeitsweise …"
              style={{ minHeight: 140 }}
            />
          </div>

          <label className="pill w-fit" data-active={isActive}>
            <input
              type="checkbox"
              checked={isActive}
              onChange={(e) => setIsActive(e.target.checked)}
              style={{ accentColor: "var(--blue)" }}
            />
            Auf der Website sichtbar
          </label>

          {/* ── Feld-Baukasten ── */}
          <div className="field">
            <div className="mb-2 flex items-center justify-between gap-3">
              <label className="label" style={{ margin: 0 }}>
                Formularfelder ({fields.length})
              </label>
              <button
                type="button"
                className="btn btn-ghost btn-sm"
                onClick={() => setFields((l) => [...l, newField()])}
              >
                <Icon name="plus" size={14} /> Feld
              </button>
            </div>

            <div className="flex flex-col gap-2.5">
              {fields.map((f, i) => (
                <div key={f.uid} className="fb-field">
                  <div className="fb-row">
                    <div className="field">
                      <label className="label">Beschriftung</label>
                      <input
                        className="input"
                        value={f.label}
                        onChange={(e) => patch(f.uid, { label: e.target.value })}
                        placeholder="z. B. Portfolio-Link"
                      />
                    </div>
                    <div className="field">
                      <label className="label">Art</label>
                      <select
                        className="select"
                        value={f.type}
                        onChange={(e) => patch(f.uid, { type: e.target.value })}
                      >
                        {Object.entries(APPLICATION_FIELD_TYPES).map(([key, label]) => (
                          <option key={key} value={key}>
                            {label}
                          </option>
                        ))}
                      </select>
                    </div>
                    <div className="flex items-center gap-1 pb-1">
                      <button
                        type="button"
                        className="btn btn-ghost btn-sm"
                        onClick={() => move(i, -1)}
                        disabled={i === 0}
                        title="Nach oben"
                      >
                        <Icon name="chevron" size={14} style={{ transform: "rotate(-90deg)" }} />
                      </button>
                      <button
                        type="button"
                        className="btn btn-ghost btn-sm"
                        onClick={() => move(i, 1)}
                        disabled={i === fields.length - 1}
                        title="Nach unten"
                      >
                        <Icon name="chevron" size={14} style={{ transform: "rotate(90deg)" }} />
                      </button>
                      <button
                        type="button"
                        className="btn btn-ghost btn-sm"
                        onClick={() => setFields((l) => l.filter((x) => x.uid !== f.uid))}
                        title="Feld entfernen"
                      >
                        <Icon name="trash" size={14} />
                      </button>
                    </div>
                  </div>

                  {f.type === "select" ? (
                    <div className="field">
                      <label className="label">Optionen — eine pro Zeile</label>
                      <textarea
                        className="textarea"
                        value={f.optionsText}
                        onChange={(e) => patch(f.uid, { optionsText: e.target.value })}
                        placeholder={"Vollzeit\nTeilzeit\nAushilfe"}
                        style={{ minHeight: 80 }}
                      />
                    </div>
                  ) : f.type === "checkbox" ? null : (
                    <div className="field">
                      <label className="label">Platzhalter (optional)</label>
                      <input
                        className="input"
                        value={f.placeholder}
                        onChange={(e) => patch(f.uid, { placeholder: e.target.value })}
                        placeholder="Hinweis im leeren Feld"
                      />
                    </div>
                  )}

                  <div className="flex flex-wrap items-center justify-between gap-2">
                    <label className="pill" data-active={f.required}>
                      <input
                        type="checkbox"
                        checked={f.required}
                        onChange={(e) => patch(f.uid, { required: e.target.checked })}
                        style={{ accentColor: "var(--blue)" }}
                      />
                      Pflichtfeld
                    </label>
                    {/* Der Schlüssel landet in der Bewerbung — bei Umbenennung
                        ändert er sich, alte Bewerbungen behalten ihre Beschriftung. */}
                    <span className="fb-key">
                      Schlüssel: {f.label.trim() ? fieldKeyFrom(f.label) : "—"}
                    </span>
                  </div>
                </div>
              ))}
            </div>

            {fields.length === 0 ? (
              <p className="text-muted mt-2 text-sm">
                Mindestens ein Feld ist nötig — Name und E-Mail fragt das Formular immer ab.
              </p>
            ) : null}
          </div>
        </div>

        <div className="mt-6 flex justify-end gap-2">
          <button className="btn btn-ghost" onClick={onClose}>
            Abbrechen
          </button>
          <button className="btn btn-primary" onClick={() => void save()} disabled={saving}>
            {saving ? "Speichert …" : isNew ? "Stelle anlegen" : "Speichern"}
          </button>
        </div>
      </div>
    </div>
  );
}
