/* ================================================
   Wizard — 4 Steps
================================================ */

/* Convert a Leaflet ring ([[lat,lng],...]) to a GeoJSON polygon feature
   (lon/lat + closed ring). */
function ringToGeoJson(ring) {
  const coords = ring.map(([lat, lng]) => [lng, lat]);
  const first = coords[0];
  const last = coords[coords.length - 1];
  if (!first || !last) return null;
  if (first[0] !== last[0] || first[1] !== last[1]) coords.push([...first]);
  return { type: "Feature", geometry: { type: "Polygon", coordinates: [coords] }, properties: {} };
}

/* Merge a list of Flurstück objects into a single outer ring in [lat,lng]
   format, suitable for storage in parcel.koordinaten and Leaflet rendering.
   Uses Turf.js union when available; falls back to the first ring. */
function mergeFlurstuecke(flurstuecke) {
  if (!flurstuecke || flurstuecke.length === 0) return [];
  if (flurstuecke.length === 1) return flurstuecke[0].koordinaten.slice();

  const turfAvail = typeof window !== "undefined" && window.turf && typeof window.turf.union === "function";
  if (!turfAvail) return flurstuecke[0].koordinaten.slice();

  try {
    let merged = ringToGeoJson(flurstuecke[0].koordinaten);
    for (let i = 1; i < flurstuecke.length; i++) {
      const next = ringToGeoJson(flurstuecke[i].koordinaten);
      if (!next) continue;
      // Turf 7 expects a FeatureCollection for union()
      const fc = { type: "FeatureCollection", features: [merged, next] };
      const u = window.turf.union(fc);
      if (u && u.geometry) merged = u;
    }
    const g = merged.geometry;
    let ring;
    if (g.type === "Polygon") {
      ring = g.coordinates[0];
    } else if (g.type === "MultiPolygon") {
      // pick the biggest polygon by point count
      let best = g.coordinates[0][0];
      for (const poly of g.coordinates) {
        if (poly[0].length > best.length) best = poly[0];
      }
      ring = best;
    } else {
      return flurstuecke[0].koordinaten.slice();
    }
    const out = ring.map(([lng, lat]) => [lat, lng]);
    if (out.length > 1) {
      const a = out[0], b = out[out.length - 1];
      if (a[0] === b[0] && a[1] === b[1]) out.pop();
    }
    return out;
  } catch (e) {
    console.warn("mergeFlurstuecke failed:", e);
    return flurstuecke[0].koordinaten.slice();
  }
}

// Standard-Zentrum: Achkarren (Ortsteil von Vogtsburg im Kaiserstuhl)
const DEFAULT_CENTER = [48.0712, 7.6612];
const DEFAULT_PLZ = "79235";

function Wizard({ onClose, onSave, onDelete, mapStyle, existingParcels, editParcel }) {
  const isEdit = !!editParcel;
  const [step, setStep] = React.useState(0);
  const [confirmDelete, setConfirmDelete] = React.useState(false);
  const [pickerStatus, setPickerStatus] = React.useState({ loading: false, message: null, count: 0, truncated: false });
  const [plz, setPlz] = React.useState(DEFAULT_PLZ);
  const [plzStatus, setPlzStatus] = React.useState({ loading: false, error: null, info: null });
  // flyTo-Signal für den Picker: {lat, lng, zoom, ts} – ts triggert den Effect.
  const [flyTo, setFlyTo] = React.useState(null);

  const [data, setData] = React.useState(() => editParcel ? {
    lagebuch: editParcel.lagebuch,
    lage: editParcel.lage,
    region: "",
    flaeche: editParcel.flaeche || 0,
    center: editParcel.koordinaten[0] || DEFAULT_CENTER,
    flurstuecke: editParcel.flurstuecke || [],
    prevKoordinaten: editParcel.koordinaten || [],
    sorte: editParcel.sorte,
    pflanzjahr: editParcel.pflanzjahr,
    erziehung: editParcel.erziehung,
    notizen: editParcel.notizen === "—" ? "" : (editParcel.notizen || ""),
  } : {
    lagebuch: `LB-${new Date().getFullYear()}-${String(existingParcels.length + 1).padStart(3, "0")}`,
    lage: "",
    region: "",
    flaeche: 0,
    center: DEFAULT_CENTER,
    flurstuecke: [],
    prevKoordinaten: [],
    sorte: "",
    pflanzjahr: new Date().getFullYear(),
    erziehung: "Drahtrahmen",
    notizen: "",
  });

  // "Touched"-Flags: sobald der Benutzer manuell eintippt, hört die Auto-
  // Befüllung auf. Beim Edit starten wir als touched, damit vorhandene Werte
  // bestehen bleiben.
  const [lageTouched, setLageTouched] = React.useState(isEdit);
  const [regionTouched, setRegionTouched] = React.useState(isEdit);
  const [flaecheTouched, setFlaecheTouched] = React.useState(isEdit);

  const flaecheHa = React.useMemo(
    () => data.flurstuecke.reduce((s, f) => s + (f.flaeche_ha || 0), 0),
    [data.flurstuecke]
  );

  // Auto-Befüllung (Lage / Region / Fläche) aus dem ersten Flurstück.
  // Region = gemarkung_name (so vom Benutzer gewünscht).
  React.useEffect(() => {
    if (data.flurstuecke.length === 0) return;
    const f = data.flurstuecke[0];
    setData(d => ({
      ...d,
      lage: lageTouched
        ? d.lage
        : (f.gemarkung_name ? `${f.gemarkung_name} ${f.flurstueckstext || ""}`.trim() : d.lage),
      region: regionTouched ? d.region : (f.gemarkung_name || d.region),
      flaeche: flaecheTouched ? d.flaeche : Number(flaecheHa.toFixed(2)),
    }));
  }, [data.flurstuecke.map(f => f.kennzeichen).join("|"), flaecheHa]);

  // Merged polygon (outer ring, in [lat,lng]) for saving + preview
  const mergedPolygon = React.useMemo(() => mergeFlurstuecke(data.flurstuecke), [data.flurstuecke]);

  // Step-Validierung: 0 = Flurstücke, 1 = Stammdaten, 2 = Sorte, 3 = Summary
  const canAdvance = {
    0: data.flurstuecke.length >= 1 && mergedPolygon.length >= 3,
    1: !!String(data.lagebuch || "").trim()
       && !!String(data.lage || "").trim()
       && Number(data.flaeche) > 0,
    2: !!data.sorte && !!data.pflanzjahr,
    3: true,
  }[step];

  const steps = [
    { n: 1, label: "Flurstücke wählen", sub: "Auf der Karte auswählen" },
    { n: 2, label: "Stammdaten", sub: "Lagebuch, Lage, Fläche" },
    { n: 3, label: "Sorte & Details", sub: "Rebsorte und Angaben" },
    { n: 4, label: "Zusammenfassung", sub: "Überprüfen & speichern" },
  ];

  async function searchPlz() {
    const clean = String(plz || "").replace(/\D+/g, "");
    if (clean.length !== 5) {
      setPlzStatus({ loading: false, error: "PLZ muss 5 Ziffern enthalten.", info: null });
      return;
    }
    setPlzStatus({ loading: true, error: null, info: null });
    try {
      const r = await fetch(`/api/geocode/plz?plz=${clean}`, { headers: { Accept: "application/json" } });
      const j = await r.json();
      if (!r.ok) {
        setPlzStatus({ loading: false, error: j.error || "Nicht gefunden.", info: null });
        return;
      }
      setFlyTo({ lat: j.lat, lng: j.lon, zoom: 17, ts: Date.now() });
      setPlzStatus({
        loading: false,
        error: null,
        info: j.display_name ? j.display_name.split(",").slice(0, 3).join(",") : `PLZ ${clean}`,
      });
    } catch (e) {
      setPlzStatus({ loading: false, error: "Netzwerkfehler.", info: null });
    }
  }

  function handleSave() {
    onSave({
      // Lagebuchnummer ist die ID – keine separate p-xxx-ID mehr.
      id: data.lagebuch,
      lagebuch: data.lagebuch,
      lage: data.lage,
      sorte: data.sorte,
      pflanzjahr: Number(data.pflanzjahr),
      erziehung: data.erziehung,
      notizen: data.notizen || "—",
      flaeche: Number(Number(data.flaeche).toFixed(2)),
      koordinaten: mergedPolygon,
      flurstuecke: data.flurstuecke.map(f => ({
        kennzeichen: f.kennzeichen,
        gemarkung_name: f.gemarkung_name,
        gemeinde_name: f.gemeinde_name,
        flurnummer: f.flurnummer,
        zaehler: f.zaehler,
        nenner: f.nenner,
        flurstueckstext: f.flurstueckstext,
        flaeche_ha: f.flaeche_ha,
        koordinaten: f.koordinaten,
      })),
      letzteBearbeitung: new Date().toISOString().slice(0, 10),
      historie: editParcel
        ? [{ datum: new Date().toISOString().slice(0, 10), text: "Fläche bearbeitet" }, ...editParcel.historie]
        : [{ datum: new Date().toISOString().slice(0, 10), text: "Fläche angelegt" }],
      farbe: window.getSorteFarbe(data.sorte),
    });
  }

  return (
    <div className="modal-backdrop">
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h2>Neue Fläche anlegen</h2>
          <span className="mono" style={{ color: "var(--ink-3)", fontSize: 12 }}>{data.lagebuch}</span>
          <button className="modal-close" onClick={onClose}><Icon.X /></button>
        </div>
        <div className="wizard-steps">
          {steps.map((s, i) => (
            <div key={i} className={`wiz-step ${i === step ? "active" : ""} ${i < step ? "done" : ""}`}>
              <div className="wiz-step-num">{i < step ? <Icon.Check style={{ width: 12, height: 12 }} /> : s.n}</div>
              <div>
                <div className="wiz-step-label">{s.label}</div>
                <div className="wiz-step-sub">{s.sub}</div>
              </div>
            </div>
          ))}
        </div>

        <div className="modal-body">
          {step === 0 && (
            <div className="wiz-map-wrap">
              <div className="wiz-map">
                <div className="plz-bar">
                  <label htmlFor="wiz-plz">PLZ</label>
                  <input
                    id="wiz-plz"
                    className="mono"
                    value={plz}
                    onChange={(e) => setPlz(e.target.value)}
                    onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); searchPlz(); } }}
                    placeholder="79235"
                    maxLength={5}
                    inputMode="numeric"
                  />
                  <button className="btn btn-secondary plz-btn" onClick={searchPlz} disabled={plzStatus.loading}>
                    {plzStatus.loading ? "…" : "Karte zentrieren"}
                  </button>
                  {plzStatus.error && <span className="plz-msg err">{plzStatus.error}</span>}
                  {plzStatus.info && !plzStatus.error && <span className="plz-msg ok">{plzStatus.info}</span>}
                </div>
                <FlurstueckPicker
                  selected={data.flurstuecke}
                  onChange={(fs) => setData(d => ({ ...d, flurstuecke: fs }))}
                  mapStyle={mapStyle}
                  center={data.center}
                  onStatus={setPickerStatus}
                  initialOutline={data.prevKoordinaten}
                  flyTo={flyTo}
                />
              </div>
              <div className="wiz-map-panel">
                <div className="wiz-map-instruct">
                  <strong>So gehts:</strong> Über die PLZ kannst du die Karte schnell in deine Region bringen. Zoome dann weiter hinein (ab Zoom 16 werden ALKIS-Flurstücke eingeblendet) und klicke die gewünschten Flurstücke an. Auch mehrere benachbarte sind möglich — sie werden zu einer Fläche zusammengefasst.
                </div>

                <div className="flur-picker-status">
                  {pickerStatus.loading && <span>⏳ Flurstücke werden geladen…</span>}
                  {!pickerStatus.loading && pickerStatus.message && <span>ℹ️ {pickerStatus.message}</span>}
                  {!pickerStatus.loading && !pickerStatus.message && pickerStatus.count > 0 && (
                    <span>{pickerStatus.count} Flurstücke im Sichtbereich{pickerStatus.truncated ? " (abgeschnitten)" : ""}</span>
                  )}
                </div>

                <div className="wiz-calc">
                  <div className="wiz-calc-row"><span className="lbl">Ausgewählte Flurstücke</span><span className="val">{data.flurstuecke.length}</span></div>
                  <div className="wiz-calc-row total"><span className="lbl">Amtliche Fläche</span><span className="val">{data.flurstuecke.length ? `${fmtNum(flaecheHa)} ha` : "—"}</span></div>
                </div>

                <div style={{ display: "flex", justifyContent: "space-between", marginTop: 12, marginBottom: 6, alignItems: "center" }}>
                  <div style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: "0.1em", color: "var(--ink-3)", fontWeight: 600 }}>
                    Auswahl
                  </div>
                  {data.flurstuecke.length > 0 && (
                    <button
                      className="btn btn-ghost"
                      style={{ padding: "4px 8px", fontSize: 11, color: "var(--err)" }}
                      onClick={() => setData({ ...data, flurstuecke: [] })}
                    >
                      <Icon.Trash style={{ width: 12, height: 12 }} /> Alle entfernen
                    </button>
                  )}
                </div>

                <div className="flur-selected-list">
                  {data.flurstuecke.length === 0 && (
                    <div style={{ color: "var(--ink-4)", padding: "6px 0", fontSize: 12 }}>
                      Noch keine Flurstücke ausgewählt.
                    </div>
                  )}
                  {data.flurstuecke.map((f) => (
                    <div key={f.kennzeichen} className="flur-selected-row">
                      <div className="flur-selected-head">
                        <span className="flur-selected-gemarkung">{f.gemarkung_name || "?"}</span>
                        <span className="flur-selected-ha">{fmtNum(f.flaeche_ha)} ha</span>
                      </div>
                      <div className="flur-selected-sub">
                        Flur {f.flurnummer} · Flst. {f.flurstueckstext || f.zaehler}
                        {f.nenner ? `/${f.nenner}` : ""} · {f.gemeinde_name || ""}
                      </div>
                      <button
                        className="flur-selected-remove"
                        title="Entfernen"
                        onClick={() => setData({ ...data, flurstuecke: data.flurstuecke.filter(x => x.kennzeichen !== f.kennzeichen) })}
                      >
                        <Icon.X />
                      </button>
                    </div>
                  ))}
                </div>

                {data.flurstuecke.length > 1 && (
                  <div className="flur-merge-hint">
                    Die gewählten Flurstücke werden zu einer Fläche zusammengefasst. Bei nicht zusammenhängender Auswahl wird der größte Teil übernommen.
                  </div>
                )}
              </div>
            </div>
          )}

          {step === 1 && (
            <div className="form-grid">
              <div className="field">
                <label>Lagebuchnummer</label>
                <input
                  className="mono"
                  value={data.lagebuch}
                  onChange={(e) => setData({ ...data, lagebuch: e.target.value })}
                />
                <span className="hint">Wird automatisch vorgeschlagen, manuell anpassbar. Dient als eindeutige ID.</span>
              </div>
              <div className="field">
                <label>Fläche (ha)</label>
                <input
                  type="number"
                  step="0.01"
                  min="0"
                  className="mono"
                  value={data.flaeche}
                  onChange={(e) => { setFlaecheTouched(true); setData({ ...data, flaeche: e.target.value }); }}
                />
                <span className="hint">
                  {flaecheTouched
                    ? <>Manuell überschrieben. <button type="button" className="btn-link" onClick={() => { setFlaecheTouched(false); setData(d => ({ ...d, flaeche: Number(flaecheHa.toFixed(2)) })); }}>Aus Flurstücken übernehmen ({fmtNum(flaecheHa)} ha)</button></>
                    : <>Automatisch aus der Summe der gewählten Flurstücke.</>}
                </span>
              </div>
              <div className="field">
                <label>Lage / Gewann</label>
                <input
                  value={data.lage}
                  onChange={(e) => { setLageTouched(true); setData({ ...data, lage: e.target.value }); }}
                  placeholder="z.B. Achkarren Schlossberg"
                />
                <span className="hint">{lageTouched ? "Manuell überschrieben." : "Vorschlag aus Gemarkung + Flurstücksnummer."}</span>
              </div>
              <div className="field">
                <label>Region</label>
                <input
                  value={data.region}
                  onChange={(e) => { setRegionTouched(true); setData({ ...data, region: e.target.value }); }}
                  placeholder="z.B. Kaiserstuhl"
                />
                <span className="hint">
                  {regionTouched
                    ? <>Manuell überschrieben.{data.flurstuecke[0]?.gemarkung_name ? <> <button type="button" className="btn-link" onClick={() => { setRegionTouched(false); setData(d => ({ ...d, region: data.flurstuecke[0].gemarkung_name })); }}>Aus Gemarkung übernehmen ({data.flurstuecke[0].gemarkung_name})</button></> : null}</>
                    : <>Automatisch aus der Gemarkung des ersten Flurstücks.</>}
                </span>
              </div>
            </div>
          )}

          {step === 2 && (
            <div className="form-grid">
              <div className="field full">
                <label>Rebsorte</label>
                <div className="radio-group">
                  {SORTEN.map((s) => (
                    <button
                      key={s.name}
                      type="button"
                      className={`radio-card ${data.sorte === s.name ? "selected" : ""}`}
                      onClick={() => setData({ ...data, sorte: s.name })}
                    >
                      <span style={{ display: "inline-block", width: 10, height: 10, borderRadius: 2, background: s.farbe, marginRight: 8, verticalAlign: "middle", border: "1px solid rgba(0,0,0,0.15)" }} />
                      <span className="radio-card-title" style={{ display: "inline" }}>{s.name}</span>
                    </button>
                  ))}
                </div>
              </div>
              <div className="field">
                <label>Pflanzjahr</label>
                <input type="number" className="mono" value={data.pflanzjahr} onChange={(e) => setData({ ...data, pflanzjahr: e.target.value })} min="1950" max={new Date().getFullYear()} />
              </div>
              <div className="field">
                <label>Erziehungssystem</label>
                <select value={data.erziehung} onChange={(e) => setData({ ...data, erziehung: e.target.value })}>
                  {ERZIEHUNGEN.map((e) => <option key={e} value={e}>{e}</option>)}
                </select>
              </div>
              <div className="field full">
                <label>Notizen / Bemerkungen</label>
                <textarea placeholder="Bodenart, Exposition, Besonderheiten…" value={data.notizen} onChange={(e) => setData({ ...data, notizen: e.target.value })} />
              </div>
            </div>
          )}

          {step === 3 && (
            <div className="summary">
              <div>
                <div className="summary-section">
                  <h3>Stammdaten</h3>
                  <div className="summary-row"><span className="k">Lagebuch-Nr.</span><span className="v">{data.lagebuch}</span></div>
                  <div className="summary-row"><span className="k">Lage</span><span className="v">{data.lage}</span></div>
                  <div className="summary-row"><span className="k">Region</span><span className="v">{data.region || "—"}</span></div>
                  <div className="summary-row"><span className="k">Sorte</span><span className="v">{data.sorte}</span></div>
                  <div className="summary-row"><span className="k">Pflanzjahr</span><span className="v">{data.pflanzjahr}</span></div>
                  <div className="summary-row"><span className="k">Erziehung</span><span className="v">{data.erziehung}</span></div>
                </div>
                <div className="summary-section" style={{ marginTop: 16 }}>
                  <h3>Flurstücke · Geometrie</h3>
                  <div className="summary-row"><span className="k">Flurstücke</span><span className="v">{data.flurstuecke.length}</span></div>
                  <div className="summary-row">
                    <span className="k">Fläche</span>
                    <span className="v" style={{ color: "var(--burgundy)", fontFamily: "var(--font-display)", fontSize: 18 }}>{fmtNum(Number(data.flaeche) || 0)} ha</span>
                  </div>
                  {flaecheTouched && Math.abs((Number(data.flaeche) || 0) - flaecheHa) > 0.001 && (
                    <div className="summary-row"><span className="k">Amtlich (Flurstücke)</span><span className="v" style={{ fontSize: 12 }}>{fmtNum(flaecheHa)} ha</span></div>
                  )}
                  {data.flurstuecke.slice(0, 5).map(f => (
                    <div key={f.kennzeichen} className="summary-row">
                      <span className="k mono" style={{ fontSize: 11 }}>{f.kennzeichen}</span>
                      <span className="v" style={{ fontSize: 12 }}>{f.gemarkung_name} · {f.flurstueckstext || f.zaehler} · {fmtNum(f.flaeche_ha)} ha</span>
                    </div>
                  ))}
                  {data.flurstuecke.length > 5 && (
                    <div className="summary-row"><span className="k">…</span><span className="v">+{data.flurstuecke.length - 5} weitere</span></div>
                  )}
                </div>
                {data.notizen && (
                  <div className="summary-section" style={{ marginTop: 16 }}>
                    <h3>Notizen</h3>
                    <div style={{ fontSize: 13, color: "var(--ink-2)", lineHeight: 1.6 }}>{data.notizen}</div>
                  </div>
                )}
              </div>
              <div>
                <div style={{ fontSize: 10, textTransform: "uppercase", letterSpacing: "0.12em", color: "var(--ink-3)", fontWeight: 600, marginBottom: 8 }}>
                  Kartenvorschau
                </div>
                <div className="summary-map" style={{ height: 400 }}>
                  <SingleParcelMap
                    parcel={{ koordinaten: mergedPolygon, farbe: "#6B1F2E" }}
                    mapStyle={mapStyle}
                  />
                </div>
              </div>
            </div>
          )}
        </div>

        <div className="modal-foot">
          {/* Löschen ganz links — nur im Edit-Modus */}
          {isEdit && !confirmDelete && (
            <button
              className="btn btn-ghost wiz-btn-delete"
              onClick={() => setConfirmDelete(true)}
            >
              <Icon.Trash style={{ width: 14, height: 14 }} /> Löschen
            </button>
          )}
          {isEdit && confirmDelete && (
            <div className="wiz-confirm-delete">
              <span><strong>Wirklich löschen?</strong> {editParcel.lagebuch} wird unwiderruflich entfernt.</span>
              <button className="btn btn-ghost" onClick={() => setConfirmDelete(false)}>Abbrechen</button>
              <button className="btn wiz-btn-confirm-delete" onClick={() => onDelete(editParcel.id)}>
                <Icon.Trash style={{ width: 13, height: 13 }} /> Endgültig löschen
              </button>
            </div>
          )}

          {step === 0 && data.flurstuecke.length >= 1 && !confirmDelete && (
            <span className="foot-hint">Fläche: {fmtNum(flaecheHa)} ha · {data.flurstuecke.length} Flurstück{data.flurstuecke.length > 1 ? "e" : ""}</span>
          )}
          <div className="foot-spacer" />
          {!confirmDelete && (
            <>
              <button className="btn btn-ghost" onClick={onClose}>Abbrechen</button>
              {step > 0 && <button className="btn btn-secondary" onClick={() => setStep(step - 1)}>Zurück</button>}
              {step < 3 ? (
                <button className="btn btn-primary" disabled={!canAdvance} onClick={() => setStep(step + 1)} style={{ opacity: canAdvance ? 1 : 0.5 }}>
                  Weiter <Icon.Arrow />
                </button>
              ) : (
                <button className="btn btn-primary" onClick={handleSave}>
                  <Icon.Check /> Fläche speichern
                </button>
              )}
            </>
          )}
        </div>
      </div>
    </div>
  );
}

window.Wizard = Wizard;
