/* najemnici-de.jsx — Mieter & Zahlungen (PRO-Modul, deutsche Marktvariante)
   Parallel zu /najemnici.jsx: EUR statt CZK, SEPA-Fuzzy-Match statt Variabler
   Symbol, CAMT.053/MT940-Import statt GPC/ABO. Teilt api-client.js und
   styles.css mit dem Dashboard — siehe de/README.md für den Konsolidierungsplan. */
const { useState, useEffect, useMemo, useCallback, useRef } = React;

/* ---------- Formatierung ---------- */
const fmtEUR = (n) => {
  const sign = n < 0 ? "−" : "";
  const abs = Math.abs(Math.round(n || 0)).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
  return `${sign}${abs} €`;
};
const MONTHS = ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"];
const deDate = (iso) => { if (!iso) return "—"; const d = new Date(iso); return isNaN(d) ? "—" : d.toLocaleDateString("de-DE"); };
const todayIso = () => new Date().toISOString().slice(0, 10);

const STATUS = {
  PAID:    { label: "Bezahlt", cls: "ok" },
  PARTIAL: { label: "Teilweise", cls: "warn" },
  OPEN:    { label: "Offen", cls: "bad" },
};

/* ---------- kleine UI-Bausteine ---------- */
function Logo() {
  return (
    <div className="logo">
      <span className="logo-a">Spocit</span><span className="logo-ai">AI</span>
      <span className="logo-a">to</span><span className="logo-cz">.de</span>
    </div>
  );
}
function Spinner({ label = "Lädt…" }) {
  return (
    <div className="rent-center">
      <div className="rent-spin" />
      <p>{label}</p>
    </div>
  );
}
function Chip({ status }) {
  const s = STATUS[status] || STATUS.OPEN;
  return <span className={`rent-chip ${s.cls}`}>{s.label}</span>;
}
function Field({ label, children, hint }) {
  return (
    <label className="rent-field">
      <span className="rent-field-label">{label}</span>
      {children}
      {hint && <span className="rent-field-hint">{hint}</span>}
    </label>
  );
}

/* ======================================================================
   Zugangssperre: nicht eingeloggt / kein PRO-Tarif
====================================================================== */
function AccessGate({ mode }) {
  const startCheckout = async (tier) => {
    try { window.location.href = await window.API.checkout(tier, "EUR"); }
    catch { window.location.href = "/de/#pricing"; }
  };
  return (
    <div className="rent-gate">
      <div className="rent-gate-card">
        <div className="rent-gate-icon">{mode === "login" ? "🔑" : "✨"}</div>
        {mode === "login" ? (
          <>
            <h1>Bitte anmelden</h1>
            <p>Die Mieter- und Zahlungsverwaltung ist nach der Anmeldung verfügbar.</p>
            <a className="rent-btn primary" href={window.API.loginUrl()}>Anmelden</a>
          </>
        ) : (
          <>
            <h1>Mieter &amp; Zahlungen freischalten</h1>
            <p>Behalten Sie den Überblick, wer bezahlt hat und wer offen ist, senden Sie automatische Erinnerungen und rechnen Sie am Jahresende die Betriebskosten mit einem Klick ab. Teil des <strong>Pro</strong>-Tarifs.</p>
            <div className="rent-gate-tiers">
              <button className="rent-btn primary" onClick={() => startCheckout("PRO")}>Pro holen — 19 €/Monat</button>
              <button className="rent-btn ghost" onClick={() => startCheckout("BUSINESS")}>Business — 39 €/Monat</button>
            </div>
            <p className="rent-muted" style={{ fontSize: "12px", marginTop: "10px" }}>EUR-Abrechnung befindet sich noch im Aufbau — falls der Checkout fehlschlägt, ist der Preis in Stripe noch nicht angelegt.</p>
          </>
        )}
        <a className="rent-back" href="Dashboard.html">← Zurück zur Übersicht</a>
      </div>
    </div>
  );
}

/* ======================================================================
   Tab 1 — Zahlungsübersicht
====================================================================== */
function PaymentsTab({ notify }) {
  const now = new Date();
  const [year, setYear] = useState(now.getUTCFullYear());
  const [month, setMonth] = useState(now.getUTCMonth() + 1);
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [busyId, setBusyId] = useState(null);

  const load = useCallback(async () => {
    setLoading(true);
    try { setData(await window.API.rent.overview(year, month)); }
    catch (e) { notify("Übersicht konnte nicht geladen werden: " + e.message, "bad"); }
    finally { setLoading(false); }
  }, [year, month, notify]);
  useEffect(() => { load(); }, [load]);

  const markPaid = async (id) => {
    setBusyId(id);
    try { await window.API.rent.markCharge(id, "markPaid"); await load(); notify("Als bezahlt markiert.", "ok"); }
    catch (e) { notify("Fehler: " + e.message, "bad"); }
    finally { setBusyId(null); }
  };
  const markUnpaid = async (id) => {
    setBusyId(id);
    try { await window.API.rent.markCharge(id, "markUnpaid"); await load(); }
    catch (e) { notify("Fehler: " + e.message, "bad"); }
    finally { setBusyId(null); }
  };
  const remind = async (row) => {
    if (!row.tenantEmail) { notify("Mieter hat keine E-Mail — bitte im Mietvertrag ergänzen.", "warn"); return; }
    setBusyId(row.id);
    try {
      const r = await window.API.rent.sendReminder({ chargeId: row.id });
      const res = r.result || {};
      if (res.sent) notify(`Erinnerung (Stufe ${res.stage}) an ${res.toEmail} gesendet.`, "ok");
      else if (res.skipped === "already_sent") notify("Diese Stufe wurde bereits gesendet.", "warn");
      else if (res.skipped === "no_api_key_logged") notify("Erinnerung protokolliert (E-Mail-Versand folgt nach Resend-Einrichtung).", "warn");
      else notify("Erinnerung konnte nicht gesendet werden: " + (res.skipped || "?"), "bad");
      await load();
    } catch (e) { notify("Fehler: " + e.message, "bad"); }
    finally { setBusyId(null); }
  };
  const remindAll = async () => {
    try {
      const r = await window.API.rent.sendReminder({ all: true });
      notify(`${r.sent} Erinnerungen gesendet.`, "ok");
      await load();
    } catch (e) { notify("Fehler: " + e.message, "bad"); }
  };

  const s = data?.summary;
  return (
    <div>
      <div className="rent-toolbar">
        <div className="rent-period">
          <button className="rent-nav-btn" onClick={() => { const d = new Date(Date.UTC(year, month - 2, 1)); setYear(d.getUTCFullYear()); setMonth(d.getUTCMonth() + 1); }} aria-label="Vorheriger Monat">‹</button>
          <span className="rent-period-label">{MONTHS[month - 1]} {year}</span>
          <button className="rent-nav-btn" onClick={() => { const d = new Date(Date.UTC(year, month, 1)); setYear(d.getUTCFullYear()); setMonth(d.getUTCMonth() + 1); }} aria-label="Nächster Monat">›</button>
        </div>
        <button className="rent-btn ghost sm" onClick={remindAll} disabled={!s || (s.countOpen + s.countPartial) === 0}>Alle offenen Erinnerungen senden</button>
      </div>

      {s && (
        <div className="rent-cards">
          <div className="rent-card"><div className="rent-card-k">Erwartet</div><div className="rent-card-v">{fmtEUR(s.totalExpected)}</div></div>
          <div className="rent-card ok"><div className="rent-card-k">Bezahlt</div><div className="rent-card-v">{fmtEUR(s.totalPaid)}</div><div className="rent-card-sub">{s.countPaid} beglichen</div></div>
          <div className="rent-card bad"><div className="rent-card-k">Offen</div><div className="rent-card-v">{fmtEUR(s.totalUnpaid)}</div><div className="rent-card-sub">{s.countOpen + s.countPartial} unbezahlt</div></div>
          <div className="rent-card warn"><div className="rent-card-k">Nicht zugeordnet</div><div className="rent-card-v">{s.unmatchedCount}</div><div className="rent-card-sub">Zahlungen zum Zuordnen</div></div>
        </div>
      )}

      {loading ? <Spinner /> : !data?.charges?.length ? (
        <div className="rent-empty">Für diesen Monat noch keine Sollstellungen. Fügen Sie einen Mieter und Mietvertrag im Tab <strong>Mieter &amp; Verträge</strong> hinzu.</div>
      ) : (
        <div className="rent-table-wrap">
          <table className="rent-table">
            <thead><tr><th>Mieter</th><th>Immobilie</th><th>Fällig</th><th className="r">Soll</th><th className="r">Bezahlt</th><th>Status</th><th></th></tr></thead>
            <tbody>
              {data.charges.map((r) => (
                <tr key={r.id}>
                  <td>{r.tenant}</td>
                  <td className="rent-muted">{r.property}</td>
                  <td>{deDate(r.dueDate)}</td>
                  <td className="r">{fmtEUR(r.amount)}</td>
                  <td className="r">{fmtEUR(r.paidAmount)}</td>
                  <td><Chip status={r.status} />{r.reminderStage > 0 && <span className="rent-stage" title="Letzte Erinnerungsstufe">Stufe {r.reminderStage}</span>}</td>
                  <td className="rent-actions">
                    {r.status !== "PAID" ? (
                      <>
                        <button className="rent-btn xs primary" disabled={busyId === r.id} onClick={() => markPaid(r.id)}>Bezahlt</button>
                        <button className="rent-btn xs" disabled={busyId === r.id} onClick={() => remind(r)} title={r.tenantEmail ? "Erinnerung senden" : "E-Mail des Mieters fehlt"}>Erinnerung{r.suggestedStage > 0 ? ` ${Math.max(r.suggestedStage, r.reminderStage + 1)}` : ""}</button>
                      </>
                    ) : (
                      <button className="rent-btn xs ghost" disabled={busyId === r.id} onClick={() => markUnpaid(r.id)}>Zurücksetzen</button>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

/* ======================================================================
   Tab 2 — Kontoauszug importieren (CAMT.053 / MT940)
====================================================================== */
function ImportTab({ notify, leases, reloadLeases }) {
  const [content, setContent] = useState("");
  const [filename, setFilename] = useState("");
  const [preview, setPreview] = useState(null);
  const [busy, setBusy] = useState(false);
  const [unmatched, setUnmatched] = useState([]);
  const fileRef = useRef(null);

  const loadUnmatched = useCallback(async () => {
    try { const d = await window.API.rent.listPayments(true); setUnmatched(d.payments || []); }
    catch (e) { /* ignore */ }
  }, []);
  useEffect(() => { loadUnmatched(); }, [loadUnmatched]);

  const onFile = (e) => {
    const f = e.target.files?.[0];
    if (!f) return;
    setFilename(f.name);
    const reader = new FileReader();
    reader.onload = () => setContent(String(reader.result || ""));
    reader.readAsText(f, "utf-8");
  };
  const doPreview = async () => {
    if (!content.trim()) { notify("Bitte Kontoauszug einfügen oder eine Datei hochladen.", "warn"); return; }
    setBusy(true);
    try { setPreview(await window.API.rent.importStatement(content, filename, false)); }
    catch (e) { notify("Fehler bei der Vorschau: " + e.message, "bad"); }
    finally { setBusy(false); }
  };
  const doImport = async () => {
    setBusy(true);
    try {
      const r = await window.API.rent.importStatement(content, filename, true);
      notify(`Importiert: ${r.summary.matched} zugeordnet, ${r.summary.unmatched} nicht zugeordnet, ${r.summary.duplicate} Duplikate.`, "ok");
      setPreview(null); setContent(""); setFilename("");
      await loadUnmatched();
    } catch (e) { notify("Fehler beim Import: " + e.message, "bad"); }
    finally { setBusy(false); }
  };
  const assign = async (paymentId, leaseId) => {
    if (!leaseId) return;
    try { await window.API.rent.assignPayment(paymentId, leaseId, null); notify("Zahlung zugeordnet.", "ok"); await loadUnmatched(); }
    catch (e) { notify("Fehler: " + e.message, "bad"); }
  };

  return (
    <div>
      <div className="rent-panel">
        <h3>Kontoauszug hochladen</h3>
        <p className="rent-muted">Wir unterstützen <strong>CAMT.053</strong> (XML) und <strong>MT940</strong> von Ihrer Bank. SEPA kennt keinen Verwendungszweck-Code wie in Tschechien — Zahlungen werden per <strong>Betrag + Zahlername</strong> automatisch zugeordnet.</p>
        <div className="rent-import-row">
          <button className="rent-btn" onClick={() => fileRef.current?.click()}>Datei auswählen…</button>
          <input ref={fileRef} type="file" accept=".xml,.sta,.940,.mt940,.csv,.txt" style={{ display: "none" }} onChange={onFile} />
          {filename && <span className="rent-muted">{filename}</span>}
        </div>
        <textarea className="rent-textarea" placeholder="…oder Inhalt des Kontoauszugs hier einfügen (CAMT.053 / MT940)" value={content} onChange={(e) => setContent(e.target.value)} rows={5} />
        <div className="rent-import-actions">
          <button className="rent-btn" onClick={doPreview} disabled={busy}>Zuordnungsvorschau</button>
          <button className="rent-btn primary" onClick={doImport} disabled={busy || !content.trim()}>Importieren</button>
        </div>
      </div>

      {preview && (
        <div className="rent-panel">
          <h3>Vorschau ({preview.source}) — {preview.summary.matched} zugeordnet, {preview.summary.unmatched} ohne Treffer</h3>
          {preview.warnings?.map((w, i) => <div key={i} className="rent-warnline">⚠ {w}</div>)}
          <div className="rent-table-wrap">
            <table className="rent-table">
              <thead><tr><th>Datum</th><th className="r">Betrag</th><th>Zahler</th><th>Verwendungszweck</th><th>Ergebnis</th></tr></thead>
              <tbody>
                {preview.outcomes.map((o, i) => (
                  <tr key={i}>
                    <td>{deDate(o.tx.receivedAt)}</td>
                    <td className="r">{fmtEUR(o.tx.amount)}</td>
                    <td className="rent-muted">{o.tx.counterparty || "—"}</td>
                    <td className="rent-muted">{o.tx.note || "—"}</td>
                    <td>{o.status === "matched" ? <span className="rent-chip ok">zugeordnet</span> : o.status === "duplicate" ? <span className="rent-chip warn">Duplikat</span> : <span className="rent-chip bad">kein Treffer</span>}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}

      <div className="rent-panel">
        <h3>Nicht zugeordnete Zahlungen ({unmatched.length})</h3>
        {!unmatched.length ? <p className="rent-muted">Alles zugeordnet. 🎉</p> : (
          <div className="rent-table-wrap">
            <table className="rent-table">
              <thead><tr><th>Datum</th><th className="r">Betrag</th><th>Zahler</th><th>Verwendungszweck</th><th>Mietvertrag zuordnen</th></tr></thead>
              <tbody>
                {unmatched.map((p) => (
                  <tr key={p.id}>
                    <td>{deDate(p.receivedAt)}</td>
                    <td className="r">{fmtEUR(p.amount)}</td>
                    <td className="rent-muted">{p.counterparty || "—"}</td>
                    <td className="rent-muted">{p.note || "—"}</td>
                    <td>
                      <select className="rent-select" defaultValue="" onChange={(e) => assign(p.id, e.target.value)}>
                        <option value="" disabled>Auswählen…</option>
                        {leases.map((l) => <option key={l.id} value={l.id}>{l.tenant?.name} — {l.property?.name}</option>)}
                      </select>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </div>
  );
}

/* ======================================================================
   Tab 3 — Mieter & Verträge
====================================================================== */
function TenantsTab({ notify, properties, tenants, leases, reloadTenants, reloadLeases }) {
  const [t, setT] = useState({ name: "", email: "", phone: "" });
  const emptyLease = { propertyId: "", tenantId: "", rentAmount: "", servicesAmount: "", dueDay: 15, startDate: todayIso(), personCount: 1, areaM2: "" };
  const [l, setL] = useState(emptyLease);

  const addTenant = async () => {
    if (!t.name.trim()) { notify("Bitte Namen des Mieters angeben.", "warn"); return; }
    try { await window.API.rent.createTenant(t); setT({ name: "", email: "", phone: "" }); await reloadTenants(); notify("Mieter hinzugefügt.", "ok"); }
    catch (e) { notify("Fehler: " + e.message, "bad"); }
  };
  const delTenant = async (id) => {
    if (!confirm("Mieter inklusive Verträge und Zahlungen löschen?")) return;
    try { await window.API.rent.deleteTenant(id); await reloadTenants(); await reloadLeases(); }
    catch (e) { notify("Fehler: " + e.message, "bad"); }
  };
  const addLease = async () => {
    if (!l.propertyId || !l.tenantId) { notify("Bitte Immobilie und Mieter auswählen.", "warn"); return; }
    try {
      await window.API.rent.createLease({
        propertyId: l.propertyId, tenantId: l.tenantId,
        rentAmount: Number(l.rentAmount) || 0, servicesAmount: Number(l.servicesAmount) || 0,
        currency: "EUR",
        dueDay: Number(l.dueDay) || 15,
        startDate: l.startDate, personCount: Number(l.personCount) || 1,
        ...(l.areaM2 ? { areaM2: Number(l.areaM2) } : {}),
      });
      setL(emptyLease); await reloadLeases(); notify("Mietvertrag erstellt.", "ok");
    } catch (e) { notify("Fehler: " + e.message, "bad"); }
  };
  const delLease = async (id) => {
    if (!confirm("Mietvertrag inklusive Sollstellungen und Zahlungen löschen?")) return;
    try { await window.API.rent.deleteLease(id); await reloadLeases(); }
    catch (e) { notify("Fehler: " + e.message, "bad"); }
  };

  return (
    <div className="rent-two-col">
      <div className="rent-panel">
        <h3>Mieter</h3>
        <div className="rent-form-row">
          <input className="rent-input" placeholder="Vor- und Nachname" value={t.name} onChange={(e) => setT({ ...t, name: e.target.value })} />
          <input className="rent-input" placeholder="E-Mail (für Erinnerungen)" value={t.email} onChange={(e) => setT({ ...t, email: e.target.value })} />
          <input className="rent-input" placeholder="Telefon" value={t.phone} onChange={(e) => setT({ ...t, phone: e.target.value })} />
          <button className="rent-btn primary" onClick={addTenant}>Hinzufügen</button>
        </div>
        {!tenants.length ? <p className="rent-muted">Noch keine Mieter.</p> : (
          <ul className="rent-list">
            {tenants.map((x) => (
              <li key={x.id}>
                <div><strong>{x.name}</strong><br /><span className="rent-muted">{x.email || "keine E-Mail"}{x.phone ? " · " + x.phone : ""}</span></div>
                <button className="rent-btn xs ghost" onClick={() => delTenant(x.id)}>Löschen</button>
              </li>
            ))}
          </ul>
        )}
      </div>

      <div className="rent-panel">
        <h3>Mietverträge</h3>
        {!properties.length ? (
          <p className="rent-muted">Fügen Sie zuerst eine Immobilie in der <a href="Dashboard.html">Übersicht</a> hinzu.</p>
        ) : (
          <div className="rent-lease-form">
            <Field label="Immobilie">
              <select className="rent-select" value={l.propertyId} onChange={(e) => setL({ ...l, propertyId: e.target.value })}>
                <option value="">Auswählen…</option>
                {properties.map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}
              </select>
            </Field>
            <Field label="Mieter">
              <select className="rent-select" value={l.tenantId} onChange={(e) => setL({ ...l, tenantId: e.target.value })}>
                <option value="">Auswählen…</option>
                {tenants.map((x) => <option key={x.id} value={x.id}>{x.name}</option>)}
              </select>
            </Field>
            <div className="rent-grid2">
              <Field label="Kaltmiete (€/Monat)"><input className="rent-input" type="number" value={l.rentAmount} onChange={(e) => setL({ ...l, rentAmount: e.target.value })} /></Field>
              <Field label="Nebenkostenvorauszahlung (€/Monat)"><input className="rent-input" type="number" value={l.servicesAmount} onChange={(e) => setL({ ...l, servicesAmount: e.target.value })} /></Field>
              <Field label="Fälligkeit (Tag im Monat)"><input className="rent-input" type="number" min="1" max="28" value={l.dueDay} onChange={(e) => setL({ ...l, dueDay: e.target.value })} /></Field>
              <Field label="Beginn"><input className="rent-input" type="date" value={l.startDate} onChange={(e) => setL({ ...l, startDate: e.target.value })} /></Field>
              <Field label="Personenzahl" hint="für die Betriebskostenabrechnung"><input className="rent-input" type="number" min="1" value={l.personCount} onChange={(e) => setL({ ...l, personCount: e.target.value })} /></Field>
              <Field label="Fläche (m²)" hint="optional"><input className="rent-input" type="number" value={l.areaM2} onChange={(e) => setL({ ...l, areaM2: e.target.value })} /></Field>
            </div>
            <p className="rent-muted" style={{ fontSize: "12px" }}>SEPA hat keinen Verwendungszweck-Code — Zahlungen werden automatisch per Betrag + Zahlername zugeordnet, kein Feld nötig.</p>
            <button className="rent-btn primary" onClick={addLease}>Mietvertrag erstellen</button>
          </div>
        )}
        {!!leases.length && (
          <ul className="rent-list" style={{ marginTop: "1rem" }}>
            {leases.map((x) => (
              <li key={x.id}>
                <div><strong>{x.tenant?.name}</strong> — {x.property?.name}<br /><span className="rent-muted">{fmtEUR(x.rentAmount + x.servicesAmount)}/Monat · fällig am {x.dueDay}.</span></div>
                <button className="rent-btn xs ghost" onClick={() => delLease(x.id)}>Löschen</button>
              </li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}

/* ======================================================================
   Tab 4 — Betriebskostenabrechnung
====================================================================== */
const METHOD_LABEL = { PERSONS: "nach Personen", AREA: "nach Fläche (m²)", EQUAL: "zu gleichen Teilen", CUSTOM: "manuelle Gewichtung" };

function SettlementsTab({ notify, properties }) {
  const [list, setList] = useState([]);
  const [open, setOpen] = useState(null);
  const [computation, setComputation] = useState(null);
  const [creating, setCreating] = useState(false);
  const pdfRef = useRef(null);

  const y = new Date().getUTCFullYear() - 1;
  const emptyForm = { propertyId: "", title: `Betriebskostenabrechnung ${y}`, periodStart: `${y}-01-01`, periodEnd: `${y}-12-31`, method: "PERSONS", items: [{ label: "Wasser", actual: "" }, { label: "Heizung", actual: "" }] };
  const [form, setForm] = useState(emptyForm);

  const loadList = useCallback(async () => {
    try { const d = await window.API.rent.listSettlements(); setList(d.settlements || []); }
    catch (e) { notify("Fehler: " + e.message, "bad"); }
  }, [notify]);
  useEffect(() => { loadList(); }, [loadList]);

  const create = async () => {
    if (!form.propertyId) { notify("Bitte Immobilie auswählen.", "warn"); return; }
    try {
      await window.API.rent.createSettlement({
        propertyId: form.propertyId, title: form.title,
        periodStart: form.periodStart, periodEnd: form.periodEnd, method: form.method,
        items: form.items.filter((it) => it.label && it.actual !== "").map((it) => ({ label: it.label, actual: Number(it.actual) || 0 })),
      });
      setCreating(false); setForm(emptyForm); await loadList(); notify("Abrechnung erstellt.", "ok");
    } catch (e) { notify("Fehler: " + e.message, "bad"); }
  };
  const openDetail = async (id) => {
    try {
      const d = await window.API.rent.getSettlement(id);
      setOpen(d.settlement);
      const c = await window.API.rent.computeSettlement(id);
      setComputation(c.computation);
    } catch (e) { notify("Fehler: " + e.message, "bad"); }
  };
  const del = async (id) => {
    if (!confirm("Abrechnung löschen?")) return;
    try { await window.API.rent.deleteSettlement(id); if (open?.id === id) { setOpen(null); setComputation(null); } await loadList(); }
    catch (e) { notify("Fehler: " + e.message, "bad"); }
  };
  const downloadPdf = () => {
    if (!pdfRef.current || !window.html2pdf) { notify("PDF-Bibliothek lädt noch.", "warn"); return; }
    window.html2pdf().set({ margin: 10, filename: `${open.title}.pdf`, html2canvas: { scale: 2 }, jsPDF: { unit: "mm", format: "a4" } }).from(pdfRef.current).save();
  };

  const setItem = (i, k, v) => setForm((f) => ({ ...f, items: f.items.map((it, j) => j === i ? { ...it, [k]: v } : it) }));

  return (
    <div>
      <div className="rent-toolbar">
        <p className="rent-muted" style={{ margin: 0 }}>Jährliche Betriebskostenabrechnung (§ 556 BGB, BetrKV) — vergleicht gezahlte Vorauszahlungen mit den tatsächlichen Kosten und rechnet die Differenz zwischen den Mietern ab.</p>
        <button className="rent-btn primary sm" onClick={() => setCreating((v) => !v)}>{creating ? "Schließen" : "+ Neue Abrechnung"}</button>
      </div>

      {creating && (
        <div className="rent-panel">
          <div className="rent-grid2">
            <Field label="Immobilie">
              <select className="rent-select" value={form.propertyId} onChange={(e) => setForm({ ...form, propertyId: e.target.value })}>
                <option value="">Auswählen…</option>
                {properties.map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}
              </select>
            </Field>
            <Field label="Titel"><input className="rent-input" value={form.title} onChange={(e) => setForm({ ...form, title: e.target.value })} /></Field>
            <Field label="Zeitraum von"><input className="rent-input" type="date" value={form.periodStart} onChange={(e) => setForm({ ...form, periodStart: e.target.value })} /></Field>
            <Field label="Zeitraum bis"><input className="rent-input" type="date" value={form.periodEnd} onChange={(e) => setForm({ ...form, periodEnd: e.target.value })} /></Field>
            <Field label="Umlageschlüssel">
              <select className="rent-select" value={form.method} onChange={(e) => setForm({ ...form, method: e.target.value })}>
                {Object.entries(METHOD_LABEL).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
              </select>
            </Field>
          </div>
          <h4 className="rent-subh">Tatsächliche Kosten (BetrKV §2)</h4>
          {form.items.map((it, i) => (
            <div className="rent-item-row" key={i}>
              <input className="rent-input" placeholder="Position (Wasser, Heizung…)" value={it.label} onChange={(e) => setItem(i, "label", e.target.value)} />
              <input className="rent-input" type="number" placeholder="€" value={it.actual} onChange={(e) => setItem(i, "actual", e.target.value)} />
              <button className="rent-btn xs ghost" onClick={() => setForm((f) => ({ ...f, items: f.items.filter((_, j) => j !== i) }))}>×</button>
            </div>
          ))}
          <button className="rent-btn xs" onClick={() => setForm((f) => ({ ...f, items: [...f.items, { label: "", actual: "" }] }))}>+ Position hinzufügen</button>
          <div style={{ marginTop: "1rem" }}><button className="rent-btn primary" onClick={create}>Erstellen und berechnen</button></div>
        </div>
      )}

      <div className="rent-two-col">
        <div className="rent-panel">
          <h3>Abrechnungen</h3>
          {!list.length ? <p className="rent-muted">Noch keine Abrechnung.</p> : (
            <ul className="rent-list">
              {list.map((x) => (
                <li key={x.id}>
                  <button className="rent-linkbtn" onClick={() => openDetail(x.id)}><strong>{x.title}</strong><br /><span className="rent-muted">{x.property?.name} · {METHOD_LABEL[x.method]}</span></button>
                  <button className="rent-btn xs ghost" onClick={() => del(x.id)}>Löschen</button>
                </li>
              ))}
            </ul>
          )}
        </div>

        <div className="rent-panel">
          {!open || !computation ? <p className="rent-muted">Wählen Sie links eine Abrechnung für das Ergebnis.</p> : (
            <>
              <div className="rent-toolbar" style={{ marginTop: 0 }}>
                <h3 style={{ margin: 0 }}>Ergebnis</h3>
                <button className="rent-btn sm" onClick={downloadPdf}>PDF herunterladen</button>
              </div>
              <div ref={pdfRef} className="rent-pdf">
                <h2 style={{ margin: "0 0 4px" }}>{open.title}</h2>
                <p className="rent-muted" style={{ marginTop: 0 }}>{open.property?.name} · {deDate(open.periodStart)} – {deDate(open.periodEnd)} · Umlage {METHOD_LABEL[computation.method]}</p>
                <p>Tatsächliche Kosten gesamt: <strong>{fmtEUR(computation.totalActual)}</strong> · erhaltene Vorauszahlungen: <strong>{fmtEUR(computation.totalAdvances)}</strong></p>
                <table className="rent-table">
                  <thead><tr><th>Mieter</th><th className="r">Monate</th><th className="r">Vorauszahlung</th><th className="r">Kosten</th><th className="r">Differenz</th></tr></thead>
                  <tbody>
                    {computation.rows.map((r) => (
                      <tr key={r.leaseId}>
                        <td>{r.tenantName}</td>
                        <td className="r">{r.monthsActive}</td>
                        <td className="r">{fmtEUR(r.advances)}</td>
                        <td className="r">{fmtEUR(r.allocated)}</td>
                        <td className="r" style={{ color: r.balance >= 0 ? "#16a34a" : "#dc2626", fontWeight: 600 }}>
                          {r.balance >= 0 ? "Guthaben " : "Nachzahlung "}{fmtEUR(Math.abs(r.balance))}
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
                <p className="rent-muted" style={{ fontSize: "0.75rem", marginTop: 8 }}>+ Guthaben = an Mieter zurückzahlen · − Nachzahlung = Mieter zahlt nach. Orientierungswert, ersetzt keinen Buchhaltungsbeleg.</p>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

/* ======================================================================
   Modul-Wurzel
====================================================================== */
function RentModule({ me }) {
  const [tab, setTab] = useState("zahlungen");
  const [toast, setToast] = useState(null);
  const [properties, setProperties] = useState([]);
  const [tenants, setTenants] = useState([]);
  const [leases, setLeases] = useState([]);

  const notify = useCallback((msg, kind = "ok") => {
    setToast({ msg, kind });
    setTimeout(() => setToast(null), 4200);
  }, []);

  const reloadTenants = useCallback(async () => { try { const d = await window.API.rent.listTenants(); setTenants(d.tenants || []); } catch {} }, []);
  const reloadLeases = useCallback(async () => { try { const d = await window.API.rent.listLeases(); setLeases(d.leases || []); } catch {} }, []);
  useEffect(() => {
    (async () => {
      try { setProperties(await window.API.listProperties()); } catch {}
      reloadTenants(); reloadLeases();
    })();
  }, [reloadTenants, reloadLeases]);

  const TABS = [
    { id: "zahlungen", label: "Zahlungsübersicht" },
    { id: "import", label: "Kontoauszug importieren" },
    { id: "mieter", label: "Mieter & Verträge" },
    { id: "abrechnung", label: "Betriebskostenabrechnung" },
  ];

  return (
    <div className="rent">
      <header className="header">
        <div className="container header-inner">
          <a href="Dashboard.html" className="logo-link"><Logo /></a>
          <nav className="header-nav">
            <a className="nav-link" href="Dashboard.html">Ertragsübersicht</a>
            <span className="nav-link active">Mieter &amp; Zahlungen</span>
          </nav>
          <div className="header-right">
            <div className="plan-badge" style={{ color: "#16a34a" }}><span className="plan-dot" style={{ background: "#16a34a" }} />{me.tierLabel || "PRO"}</div>
          </div>
        </div>
      </header>

      <div className="container rent-body">
        <div className="rent-tabs">
          {TABS.map((t) => (
            <button key={t.id} className={`rent-tab ${tab === t.id ? "active" : ""}`} onClick={() => setTab(t.id)}>{t.label}</button>
          ))}
        </div>

        {tab === "zahlungen" && <PaymentsTab notify={notify} />}
        {tab === "import" && <ImportTab notify={notify} leases={leases} reloadLeases={reloadLeases} />}
        {tab === "mieter" && <TenantsTab notify={notify} properties={properties} tenants={tenants} leases={leases} reloadTenants={reloadTenants} reloadLeases={reloadLeases} />}
        {tab === "abrechnung" && <SettlementsTab notify={notify} properties={properties} />}
      </div>

      {toast && <div className={`rent-toast ${toast.kind}`}>{toast.msg}</div>}
    </div>
  );
}

function RentApp() {
  const [state, setState] = useState({ loading: true });
  useEffect(() => {
    (async () => {
      try {
        const me = await window.API.me();
        if (!me.authenticated) { setState({ loading: false, gate: "login" }); return; }
        const tier = String(me.user?.tier || "FREE").toUpperCase();
        const allowed = me.user?.isAdmin || tier === "PRO" || tier === "BUSINESS";
        setState({ loading: false, gate: allowed ? null : "upsell", me: me.user });
      } catch {
        setState({ loading: false, gate: "login" });
      }
    })();
  }, []);

  if (state.loading) return <Spinner label="Modul lädt…" />;
  if (state.gate) return <AccessGate mode={state.gate} />;
  return <RentModule me={state.me} />;
}

window.RentApp = RentApp;
