import { useState } from "react";

import { apiRequest } from "../../api/client";
import type { Beladungsvorlage, Fach, Material, Objekttyp } from "../../api/types";
import { FachAuswahl } from "./FachAuswahl";

interface PositionZeile {
  materialId: number | "";
  fach: string;
  sollmenge: string;
}

const LEERE_ZEILE: PositionZeile = { materialId: "", fach: "", sollmenge: "1" };

interface Props {
  vorlagen: Beladungsvorlage[];
  objekttypen: Objekttyp[];
  materialien: Material[];
  faecher: Fach[];
  onGeaendert: () => Promise<void>;
  onFehler: (text: string) => void;
}

export function VorlageSection({ vorlagen, objekttypen, materialien, faecher, onGeaendert, onFehler }: Props) {
  const [name, setName] = useState("");
  const [objekttypId, setObjekttypId] = useState<number | "">("");
  const [zeilen, setZeilen] = useState<PositionZeile[]>([LEERE_ZEILE]);
  const [wirdAngelegt, setWirdAngelegt] = useState(false);
  const [ausgeklapptId, setAusgeklapptId] = useState<number | null>(null);
  const [neueVersionZeilen, setNeueVersionZeilen] = useState<PositionZeile[]>([]);
  const [wirdVersioniert, setWirdVersioniert] = useState(false);

  function versionBearbeiten(v: Beladungsvorlage) {
    setAusgeklapptId(ausgeklapptId === v.id ? null : v.id);
    setNeueVersionZeilen(
      v.positionen.map((p) => ({
        materialId: p.material_id,
        fach: p.fach ?? "",
        sollmenge: p.sollmenge,
      }))
    );
  }

  function neueVersionZeileAendern(index: number, zeile: Partial<PositionZeile>) {
    setNeueVersionZeilen((bisherige) => bisherige.map((z, i) => (i === index ? { ...z, ...zeile } : z)));
  }

  async function neueVersionSpeichern(vorlageId: number) {
    const positionen = neueVersionZeilen
      .filter((z) => z.materialId !== "")
      .map((z) => ({ material_id: z.materialId, fach: z.fach || null, sollmenge: z.sollmenge }));
    setWirdVersioniert(true);
    try {
      await apiRequest(`/vorlagen/${vorlageId}/neue-version`, { method: "POST", body: { positionen } });
      setAusgeklapptId(null);
      await onGeaendert();
    } catch {
      onFehler("Neue Version konnte nicht angelegt werden.");
    } finally {
      setWirdVersioniert(false);
    }
  }

  function zeileAendern(index: number, zeile: Partial<PositionZeile>) {
    setZeilen((bisherige) => bisherige.map((z, i) => (i === index ? { ...z, ...zeile } : z)));
  }

  async function anlegen() {
    if (objekttypId === "") {
      onFehler("Objekttyp auswählen.");
      return;
    }
    const positionen = zeilen
      .filter((z) => z.materialId !== "")
      .map((z) => ({ material_id: z.materialId, fach: z.fach || null, sollmenge: z.sollmenge }));

    setWirdAngelegt(true);
    try {
      await apiRequest("/vorlagen", {
        method: "POST",
        body: { objekttyp_id: objekttypId, name, positionen },
      });
      setName("");
      setZeilen([LEERE_ZEILE]);
      await onGeaendert();
    } catch {
      onFehler("Vorlage konnte nicht angelegt werden.");
    } finally {
      setWirdAngelegt(false);
    }
  }

  return (
    <section className="section">
      <h2>Vorlage anlegen</h2>
      <div className="card">
        {objekttypen.length === 0 ? (
          <p className="text-muted">Erst einen Objekttyp anlegen.</p>
        ) : (
          <div className="stack">
            <div className="row">
              <select
                className="input"
                value={objekttypId}
                onChange={(e) => setObjekttypId(Number(e.target.value) || "")}
              >
                <option value="">Objekttyp wählen…</option>
                {objekttypen.map((o) => (
                  <option key={o.id} value={o.id}>
                    {o.name}
                  </option>
                ))}
              </select>
              <input className="input" value={name} onChange={(e) => setName(e.target.value)} placeholder="Name" />
            </div>

            <p className="text-muted" style={{ marginBottom: 0 }}>
              Positionen (optional, können auch später nachgepflegt werden)
            </p>
            {zeilen.map((zeile, i) => (
              <div className="row" key={i}>
                <select
                  className="input"
                  value={zeile.materialId}
                  onChange={(e) => zeileAendern(i, { materialId: Number(e.target.value) || "" })}
                >
                  <option value="">Material…</option>
                  {materialien.map((m) => (
                    <option key={m.id} value={m.id}>
                      {m.name}
                    </option>
                  ))}
                </select>
                <FachAuswahl
                  faecher={faecher.filter((f) => f.objekttyp_id === objekttypId)}
                  wert={zeile.fach}
                  onAendern={(wert) => zeileAendern(i, { fach: wert })}
                />
                <input
                  className="input"
                  style={{ width: "5rem" }}
                  type="number"
                  value={zeile.sollmenge}
                  onChange={(e) => zeileAendern(i, { sollmenge: e.target.value })}
                />
              </div>
            ))}
            <button className="btn btn-secondary" onClick={() => setZeilen((z) => [...z, LEERE_ZEILE])}>
              + Position
            </button>

            <button className="btn btn-primary" onClick={anlegen} disabled={!name || wirdAngelegt}>
              Vorlage anlegen
            </button>
          </div>
        )}

        {vorlagen.length > 0 && (
          <ul className="card-list" style={{ marginTop: "1.25rem" }}>
            {vorlagen.map((v) => (
              <li key={v.id} style={{ padding: "0.4rem 0" }}>
                <div className="row-between">
                  <span>
                    {v.name} <span className="badge badge-neutral">v{v.version}</span>
                  </span>
                  <button className="btn btn-secondary" onClick={() => versionBearbeiten(v)}>
                    {ausgeklapptId === v.id ? "Schließen" : "Positionen / neue Version"}
                  </button>
                </div>
                {ausgeklapptId === v.id && (
                  <div className="stack" style={{ marginTop: "0.6rem" }}>
                    <p className="text-muted" style={{ marginBottom: 0 }}>
                      Änderungen erzeugen eine neue Version – die aktuelle v{v.version} bleibt unverändert
                      erhalten.
                    </p>
                    {neueVersionZeilen.map((zeile, i) => (
                      <div className="row" key={i}>
                        <select
                          className="input"
                          value={zeile.materialId}
                          onChange={(e) =>
                            neueVersionZeileAendern(i, { materialId: Number(e.target.value) || "" })
                          }
                        >
                          <option value="">Material…</option>
                          {materialien.map((m) => (
                            <option key={m.id} value={m.id}>
                              {m.name}
                            </option>
                          ))}
                        </select>
                        <FachAuswahl
                          faecher={faecher.filter((f) => f.objekttyp_id === v.objekttyp_id)}
                          wert={zeile.fach}
                          onAendern={(wert) => neueVersionZeileAendern(i, { fach: wert })}
                        />
                        <input
                          className="input"
                          style={{ width: "5rem" }}
                          type="number"
                          value={zeile.sollmenge}
                          onChange={(e) => neueVersionZeileAendern(i, { sollmenge: e.target.value })}
                        />
                      </div>
                    ))}
                    <button
                      className="btn btn-secondary"
                      onClick={() => setNeueVersionZeilen((z) => [...z, LEERE_ZEILE])}
                    >
                      + Position
                    </button>
                    <button
                      className="btn btn-primary"
                      onClick={() => neueVersionSpeichern(v.id)}
                      disabled={wirdVersioniert}
                    >
                      Neue Version speichern
                    </button>
                  </div>
                )}
              </li>
            ))}
          </ul>
        )}
      </div>
    </section>
  );
}
