/* PRIORITEITSSCHERMEN: Dashboard, Huurders (+detail), Facturen (+detail), Documenten */

(function () {
window.Screens = window.Screens || {};

const { Icons } = window;

// Data en formatters worden per render uit window.SW_DATA gelezen — de data
// wordt pas na het inloggen geladen, dus niet bovenaan de module destructuren.

const NL_MAANDEN = ['januari','februari','maart','april','mei','juni',
  'juli','augustus','september','oktober','november','december'];

/* ============================================================
   VERZENDWAARSCHUWING
   Een factuur die niet verstuurd is, is het enige dat hier echt
   fout kan gaan: de huurder krijgt niets en betaalt dus niet.
   Daarom staat dit bovenaan het dashboard en niet in een logbestand.
   ============================================================ */
function VerzendWaarschuwing({ mail, navigate, reload }) {
  const { Icons } = window;
  const [bezig, setBezig] = React.useState(null);
  if (!mail) return null;

  const mislukt = mail.failed || [];
  const dryRun = mail.dryRun || [];
  if (!mislukt.length && !dryRun.length && mail.active) return null;

  async function opnieuw(nummer) {
    setBezig(nummer);
    try {
      const r = await window.API.verstuurFactuur(nummer);
      if (reload) await reload();
      if (r && r.dryRun) {
        alert('Verstuurd in proefstand: er is geen echte e-mail uitgegaan.');
      }
    } catch (e) {
      alert(`Versturen mislukte opnieuw:\n\n${e.message}`);
    } finally {
      setBezig(null);
    }
  }

  return (
    <div className="stack">
      {mislukt.length > 0 && (
        <div className="banner banner-danger">
          <span className="banner-icoon"><Icons.X size={18} stroke={2} /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <strong>{mislukt.length === 1 ? 'Eén factuur is niet verstuurd' : `${mislukt.length} facturen zijn niet verstuurd`}</strong>
            <div className="verzend-fouten">
              {mislukt.map(f => (
                <div className="verzend-fout" key={f.number}>
                  <span className="invnum">{f.number}</span>
                  <span className="verzend-fout-tekst" title={f.error}>{f.error}</span>
                  <span className="muted">
                    {f.date}{f.attempts > 1 ? ` · ${f.attempts} pogingen` : ''}
                  </span>
                  <button className="btn btn-sm" disabled={bezig === f.number}
                          onClick={() => opnieuw(f.number)}>
                    {bezig === f.number ? 'Bezig…' : 'Opnieuw versturen'}
                  </button>
                </div>
              ))}
            </div>
            <div className="muted" style={{ marginTop: 8 }}>
              De huurder heeft deze factuur niet ontvangen. Het systeem probeert het morgen om 07:00 opnieuw.
            </div>
          </div>
        </div>
      )}

      {!mail.active && (
        <div className="banner banner-warning">
          <span className="banner-icoon"><Icons.Mail size={18} stroke={2} /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <strong>E-mailverzending staat uit (proefstand)</strong>
            <div className="muted">
              Er is geen MailerSend-sleutel ingesteld. Facturen worden wél als verzonden
              gemarkeerd, maar er gaat geen e-mail uit
              {dryRun.length ? ` — dat is al ${dryRun.length} keer gebeurd` : ''}.
              Vul <code>MAILERSEND_API_KEY</code> in het <code>.env</code>-bestand op de server.
            </div>
          </div>
        </div>
      )}

      {mail.active && dryRun.length > 0 && (
        <div className="banner banner-warning">
          <span className="banner-icoon"><Icons.Mail size={18} stroke={2} /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <strong>{dryRun.length} {dryRun.length === 1 ? 'factuur staat' : 'facturen staan'} op verzonden, maar zijn nooit gemaild</strong>
            <div className="muted">
              Verstuurd toen de e-mailkoppeling nog uit stond: {dryRun.slice(0, 6).map(f => f.number).join(', ')}
              {dryRun.length > 6 ? ' …' : ''}. Controleer of de huurder ze alsnog moet krijgen.
            </div>
          </div>
          <button className="btn btn-sm" onClick={() => navigate('invoices')}>Naar facturen</button>
        </div>
      )}
    </div>
  );
}

/* ============================================================
   TE INDEXEREN
   De huur van een contract waarvan de indexatiedatum is bereikt
   gaat anders ongewijzigd de volgende factuurronde in.
   ============================================================ */
function TeIndexeren({ lijst, reload }) {
  const { fmtEUR } = window.SW_DATA;
  const [pct, setPct] = React.useState(() => {
    const eerste = (lijst || []).find(c => c.percentage);
    return eerste ? String(eerste.percentage).replace('.', ',') : '';
  });
  const [bezig, setBezig] = React.useState(null);
  if (!lijst || !lijst.length) return null;

  const percentage = parseFloat(String(pct).replace(',', '.'));
  const geldig = Number.isFinite(percentage) && percentage > 0 && percentage <= 25;
  const nieuwBedrag = (huur) => geldig ? huur * (1 + percentage / 100) : null;

  async function indexeer(c) {
    if (!geldig) return;
    const nieuw = nieuwBedrag(c.rentNet);
    if (!confirm(`Huur van ${c.tenantName} verhogen van ${fmtEUR(c.rentNet)} naar ` +
      `${fmtEUR(nieuw)} per maand (+${pct}%)?\n\nDit geldt vanaf de eerstvolgende factuur.`)) return;
    setBezig(c.contractId);
    try {
      await window.API.indexeerContract(c.contractId, percentage);
      if (reload) await reload();
    } catch (e) {
      alert('Indexeren mislukt: ' + e.message);
    } finally { setBezig(null); }
  }

  return (
    <div className="banner banner-warning" style={{ alignItems: 'flex-start' }}>
      <span className="banner-icoon"><Icons.Trend size={18} stroke={2} /></span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <strong>{lijst.length === 1 ? 'Eén huurder kan geïndexeerd worden' : `${lijst.length} huurders kunnen geïndexeerd worden`}</strong>
        <div className="muted" style={{ marginBottom: 10 }}>
          De indexatiedatum is bereikt. Zolang dit niet gebeurt, gaat de oude huur mee in de volgende factuurronde.
        </div>
        <div className="row" style={{ gap: 8, marginBottom: 10, alignItems: 'center' }}>
          <label className="muted" htmlFor="indexpct">Indexatiepercentage</label>
          <input id="indexpct" className="input" style={{ width: 90 }} value={pct}
                 onChange={e => setPct(e.target.value)} placeholder="3,30" />
          <span className="muted">%</span>
        </div>
        <div className="verzend-fouten">
          {lijst.map(c => (
            <div className="verzend-fout" key={c.contractId}>
              <span style={{ fontWeight: 550 }}>{c.tenantName}</span>
              <span className="muted">unit {c.unit} · per {c.indexDate}</span>
              <span className="muted" style={{ marginLeft: 'auto' }}>
                {fmtEUR(c.rentNet)}{geldig && <> → <strong>{fmtEUR(nieuwBedrag(c.rentNet))}</strong></>}
              </span>
              <button className="btn btn-sm" disabled={!geldig || bezig === c.contractId}
                      onClick={() => indexeer(c)}>
                {bezig === c.contractId ? 'Bezig…' : 'Indexatie doorvoeren'}
              </button>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   DASHBOARD
   ============================================================ */
function Dashboard({ navigate, reload }) {
  const { Stat, Card, StatusBadge, Unit, MaintenanceStatus } = window.UI;
  const { TENANTS, INVOICES, MAINTENANCE, MONTHLY_NET, MAIL, INDEXATIE,
    fmtEUR, fmtEURnoCents, fmtDateShort } = window.SW_DATA;

  const open = INVOICES.filter(i => i.sent && !i.paid);
  const openTotal = open.reduce((s,i) => s + i.total, 0);
  const toSend = INVOICES.filter(i => !i.sent);
  const openMaint = MAINTENANCE.filter(m => m.status !== 'afgerond');

  // contracten die binnen 6 maanden aflopen
  const today = new Date();
  const sixMo = new Date(today); sixMo.setMonth(sixMo.getMonth() + 6);
  const ending = TENANTS.filter(t => {
    if (!t.endDate) return false;   // doorlopend contract
    const end = t.endDate ? new Date(t.endDate) : null;
    return end >= today && end <= sixMo;
  }).sort((a,b) => a.endDate < b.endDate ? -1 : 1);

  const recentMaint = [...MAINTENANCE].sort((a,b) => a.date < b.date ? 1 : -1).slice(0, 4);
  const sentCount = INVOICES.filter(i => i.sent).length;

  return (
    <div className="stack-lg">
      <VerzendWaarschuwing mail={MAIL} navigate={navigate} reload={reload} />
      <TeIndexeren lijst={INDEXATIE} reload={reload} />
      <div className="stat-grid">
        <Stat
          label="Maandomzet"
          value={fmtEURnoCents(MONTHLY_NET)}
          color="green"
          pct={100}
          delta={{ value: 'ex btw', sign: 'neutral' }}
          foot={<span className="muted">{TENANTS.length} huurders</span>}
        />
        <Stat
          label="Openstaande facturen"
          value={open.length}
          color="yellow"
          pct={sentCount ? Math.round((open.length / sentCount) * 100) : 0}
          delta={{ value: fmtEUR(openTotal), sign: open.length ? 'neg' : 'pos' }}
          foot={<span className="muted">totaal openstaand</span>}
        />
        <Stat
          label="Openstaand onderhoud"
          value={openMaint.length}
          color="blue"
          pct={MAINTENANCE.length ? Math.round((openMaint.length / MAINTENANCE.length) * 100) : 0}
          delta={{ value: `${openMaint.filter(m => m.status==='open').length} open`, sign: 'neutral' }}
          foot={<span className="muted">{openMaint.filter(m => m.status==='in_behandeling').length} in behandeling</span>}
        />
        <Stat
          label="Contracten aflopend ≤ 6 mnd"
          value={ending.length}
          color="purple"
          pct={TENANTS.length ? Math.round((ending.length / TENANTS.length) * 100) : 0}
          delta={{ value: ending.length ? `1e: ${fmtDateShort(ending[0].endDate)}` : '—', sign: ending.length ? 'neg' : 'neutral' }}
          foot={<span className="muted">van {TENANTS.length} totaal</span>}
        />
      </div>

      <div className="split-2-3">
        {/* Te versturen */}
        <Card title="Te versturen facturen"
              action={<span className="muted" style={{ fontSize: 12.5 }}>verstuurt automatisch op de 20<sup>e</sup></span>}
              flush>
          <table className="table">
            <thead>
              <tr>
                <th>Factuur</th>
                <th>Huurder</th>
                <th className="right">Bedrag</th>
              </tr>
            </thead>
            <tbody>
              {toSend.slice(0, 6).map(inv => (
                <tr key={inv.id} className="clickable" onClick={() => navigate('invoices/' + inv.id)}>
                  <td><span className="invnum">{inv.number}</span></td>
                  <td>
                    {inv.tenantName}
                    {inv.sendError && <span className="badge badge-danger" style={{ marginLeft: 8 }}>
                      <span className="dot"></span>mislukt
                    </span>}
                  </td>
                  <td className="amount">{fmtEUR(inv.total)}</td>
                </tr>
              ))}
              {toSend.length === 0 && (
                <tr><td colSpan={3} style={{ textAlign: 'center', padding: 28, color: 'var(--muted)' }}>Geen facturen klaargezet.</td></tr>
              )}
            </tbody>
          </table>
          {toSend.length > 0 && (
            <div style={{ padding: '12px 16px', borderTop: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <span className="muted" style={{ fontSize: 12.5 }}>Batch klaargezet: {toSend.length} facturen</span>
              <button className="btn btn-sm" onClick={() => navigate('invoices')}>Alles bekijken <Icons.Chevron size={13} /></button>
            </div>
          )}
        </Card>

        {/* Openstaande */}
        <Card title="Openstaande facturen" flush
              action={<button className="btn btn-sm btn-ghost" onClick={() => navigate('invoices')}>Bekijken <Icons.Chevron size={13} /></button>}>
          <table className="table">
            <thead>
              <tr>
                <th>Factuur</th>
                <th>Huurder</th>
                <th>Periode</th>
                <th className="right">Bedrag</th>
                <th>Status</th>
              </tr>
            </thead>
            <tbody>
              {open.map(inv => (
                <tr key={inv.id} className="clickable" onClick={() => navigate('invoices/' + inv.id)}>
                  <td><span className="invnum">{inv.number}</span></td>
                  <td>{inv.tenantName}</td>
                  <td className="muted">{inv.periodLabel}</td>
                  <td className="amount">{fmtEUR(inv.total)}</td>
                  <td><StatusBadge paid={inv.paid} sent={inv.sent} error={inv.sendError} channel={inv.sendChannel} /></td>
                </tr>
              ))}
              {open.length === 0 && (
                <tr><td colSpan={5} style={{ textAlign: 'center', padding: 28, color: 'var(--muted)' }}>Geen openstaande facturen.</td></tr>
              )}
            </tbody>
          </table>
        </Card>
      </div>

      <Card title="Recente onderhoudsmeldingen" flush
            action={<button className="btn btn-sm btn-ghost" onClick={() => navigate('maintenance')}>Alles bekijken <Icons.Chevron size={13} /></button>}>
        <table className="table">
          <thead>
            <tr>
              <th style={{ width: 110 }}>ID</th>
              <th>Onderwerp</th>
              <th>Unit</th>
              <th>Datum</th>
              <th>Status</th>
              <th className="right">Kosten</th>
            </tr>
          </thead>
          <tbody>
            {recentMaint.map(m => (
              <tr key={m.id} className="clickable" onClick={() => navigate('maintenance/' + m.id)}>
                <td className="mono" style={{ color: 'var(--muted)' }}>{m.id}</td>
                <td>{m.title}</td>
                <td>{m.unit === 'algemeen' ? <span className="muted">algemeen</span> : <Unit>{m.unit}</Unit>}</td>
                <td className="muted">{fmtDateShort(m.date)}</td>
                <td><MaintenanceStatus status={m.status} /></td>
                <td className="amount">{m.cost ? fmtEUR(m.cost) : <span className="muted">—</span>}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </Card>
    </div>
  );
}

/* ============================================================
   HUURDERS — LIJST
   ============================================================ */
function TenantsList({ navigate, reload }) {
  const { Card, Search, Unit } = window.UI;
  const { TENANTS, fmtEUR } = window.SW_DATA;
  const [q, setQ] = React.useState('');
  const [formOpen, setFormOpen] = React.useState(false);

  const filtered = TENANTS.filter(t =>
    !q || (t.name + t.contact + t.unit + t.invoiceEmail).toLowerCase().includes(q.toLowerCase())
  );
  const totalNet = filtered.reduce((s, t) => s + t.rentNet, 0);

  return (
    <div className="stack-lg">
      <div className="row-between">
        <Search value={q} onChange={setQ} placeholder="Zoek huurder, unit of e-mail…" />
        <button className="btn btn-primary" onClick={() => setFormOpen(true)}><Icons.Plus />Nieuwe huurder</button>
      </div>

      <Card flush>
        <table className="table">
          <thead>
            <tr>
              <th>Huurder</th>
              <th>Contactpersoon</th>
              <th>Unit</th>
              <th>Facturatie-e-mail</th>
              <th className="right">Maandhuur ex btw</th>
              <th>Indexatiemaand</th>
            </tr>
          </thead>
          <tbody>
            {filtered.map(t => (
              <tr key={t.id} className="clickable" onClick={() => navigate('tenants/' + t.id)}>
                <td style={{ fontWeight: 550 }}>{t.name}</td>
                <td><div>{t.contact || '—'}</div><div className="muted" style={{ fontSize: 12 }}>{t.contactRole}</div></td>
                <td><Unit>{t.unit}</Unit></td>
                <td className="muted">{t.invoiceEmail}</td>
                <td className="amount" style={{ fontWeight: 550 }}>{fmtEUR(t.rentNet)}</td>
                <td>{t.indexMonth}</td>
              </tr>
            ))}
            {filtered.length === 0 && (
              <tr><td colSpan={6} style={{ textAlign: 'center', padding: 40, color: 'var(--muted)' }}>Geen huurders gevonden.</td></tr>
            )}
          </tbody>
          <tfoot>
            <tr className="table-foot">
              <td colSpan={4}>Totale maandomzet ex btw</td>
              <td className="amount">{fmtEUR(totalNet)}</td>
              <td></td>
            </tr>
          </tfoot>
        </table>
      </Card>

      {formOpen && (
        <TenantFormModal mode="create" onClose={() => setFormOpen(false)}
          onSaved={async () => { await reload(); setFormOpen(false); }} />
      )}
    </div>
  );
}

/* ============================================================
   HUURDER — DETAIL
   ============================================================ */
function TenantDetail({ id, navigate, reload }) {
  const { Card, Breadcrumb, Unit, StatusBadge } = window.UI;
  const { TENANTS, INVOICES, fmtEUR, fmtDate, fmtDateShort } = window.SW_DATA;
  const [editOpen, setEditOpen] = React.useState(false);

  const t = TENANTS.find(x => x.id === id);
  if (!t) return <div>Huurder niet gevonden</div>;

  const invs = INVOICES.filter(i => i.tenantId === t.id);
  const today = new Date();
  const end = t.endDate ? new Date(t.endDate) : null;
  const monthsToEnd = end ? Math.round((end - today) / (1000 * 60 * 60 * 24 * 30.4)) : null;

  return (
    <div className="stack-lg">
      <Breadcrumb navigate={navigate} items={[
        { label: 'Huurders', to: 'tenants' },
        { label: t.name },
      ]} />

      <div className="row-between">
        <div>
          <div className="h1">{t.name}</div>
          <div className="muted" style={{ marginTop: 6 }}>KvK {t.kvk || '—'} · Contactpersoon {t.contact || '—'}</div>
        </div>
        <div className="row">
          <a className="btn" href={t.email ? `mailto:${t.email}` : undefined}><Icons.Mail />E-mail</a>
          <button className="btn" onClick={() => setEditOpen(true)}><Icons.Edit />Bewerken</button>
        </div>
      </div>

      <div className="split-2-3">
        <div className="stack">
          <Card title="Bedrijfs- en contactgegevens">
            <div className="form-grid">
              <KV label="Bedrijfsnaam" value={t.name} />
              <KV label="KvK-nummer" value={t.kvk || '—'} />
              <KV label="Contactpersoon" value={`${t.contact || '—'}${t.contactRole ? ' · ' + t.contactRole : ''}`} />
              <KV label="Telefoon" value={t.phone || '—'} />
              <KV label="Algemeen e-mail" value={t.email || '—'} />
              <KV label="Facturatie-e-mail" value={t.invoiceEmail || '—'} />
            </div>
          </Card>

          <Card title="Gehuurde unit">
            <div className="form-grid">
              <KV label="Adres" value={t.unitAddress || `Schoenerweg ${t.unit}`} />
              <KV label="Unit" value={<Unit>{t.unit}</Unit>} />
              <KV label="Oppervlakte" value={`${(t.surface || 0).toLocaleString('nl-NL')} m²`} />
              <KV label="Huurprijs ex btw" value={fmtEUR(t.rentNet) + ' / maand'} />
            </div>
          </Card>
        </div>

        <Card title="Lopend contract"
              action={<button className="btn btn-sm btn-ghost" onClick={() => navigate('contracts/' + t.id)}>Bekijk contract <Icons.Chevron size={13} /></button>}>
          <div className="stack" style={{ gap: 14 }}>
            <KV label="Ingangsdatum" value={fmtDate(t.startDate)} />
            <KV label="Einddatum" value={
              <span>
                {t.endDate ? fmtDate(t.endDate) : 'doorlopend'}{' '}
                {monthsToEnd !== null && monthsToEnd <= 6 && monthsToEnd >= 0
                  ? <span className="badge badge-warning" style={{ marginLeft: 6 }}><span className="dot"></span>over {monthsToEnd} mnd</span>
                  : null}
              </span>
            } />
            <KV label="Looptijd" value={t.termYears ? `${Math.round(t.termYears)} jaar` : 'onbepaalde tijd'} />
            <KV label="Opzegtermijn" value={`${t.noticeMonths} maanden`} />
            <KV label="BTW-belast" value={t.vatApplicable ? 'Ja' : 'Nee'} />
            <KV label="Indexatiemaand" value={t.indexMonth} />
            <KV label="Huurprijs ex btw" value={<strong>{fmtEUR(t.rentNet)}</strong>} />
          </div>
        </Card>
      </div>

      <Card title={`Facturen — ${t.name}`} flush
            action={<button className="btn btn-sm btn-ghost" onClick={() => navigate('invoices')}>Alles in Facturen <Icons.Chevron size={13} /></button>}>
        <table className="table">
          <thead>
            <tr>
              <th>Factuur</th>
              <th>Periode</th>
              <th>Aangemaakt</th>
              <th>Verzonden</th>
              <th className="right">Bedrag</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            {invs.slice(0, 14).map(inv => (
              <tr key={inv.id} className="clickable" onClick={() => navigate('invoices/' + inv.id)}>
                <td><span className="invnum">{inv.number}</span></td>
                <td>{inv.periodLabel}</td>
                <td className="muted">{fmtDateShort(inv.createdDate)}</td>
                <td className="muted">{inv.sent ? fmtDateShort(inv.sentDate) : <span style={{ color: 'var(--warning)' }}>nog niet</span>}</td>
                <td className="amount">{fmtEUR(inv.total)}</td>
                <td><StatusBadge paid={inv.paid} sent={inv.sent} error={inv.sendError} channel={inv.sendChannel} /></td>
              </tr>
            ))}
            {invs.length === 0 && (
              <tr><td colSpan={6} style={{ textAlign: 'center', padding: 28, color: 'var(--muted)' }}>Nog geen facturen.</td></tr>
            )}
          </tbody>
        </table>
      </Card>

      {editOpen && (
        <TenantFormModal mode="edit" tenant={t} onClose={() => setEditOpen(false)}
          onSaved={async () => { await reload(); setEditOpen(false); }} />
      )}
    </div>
  );
}

function KV({ label, value }) {
  return (
    <div>
      <div className="field-label">{label}</div>
      <div style={{ fontSize: 13.5 }}>{value}</div>
    </div>
  );
}

/* ============================================================
   HUURDER/CONTRACT — FORMULIER (nieuw of bewerken)
   ============================================================ */
function TenantFormModal({ mode, tenant, onClose, onSaved }) {
  const { Modal } = window.UI;
  const isEdit = mode === 'edit';

  const [f, setF] = React.useState({
    name: tenant ? tenant.name : '',
    contactVoornaam: tenant ? (tenant.contactVoornaam || '') : '',
    contactAchternaam: tenant ? (tenant.contactAchternaam || '') : '',
    contactRole: tenant ? tenant.contactRole : '',
    phone: tenant ? tenant.phone : '',
    email: tenant ? tenant.email : '',
    invoiceEmail: tenant ? tenant.invoiceEmail : '',
    kvk: tenant ? tenant.kvk : '',
    unit: tenant ? tenant.unit : '',
    surface: tenant ? tenant.surface : '',
    rentNet: tenant ? tenant.rentNet : '',
    vatApplicable: tenant ? tenant.vatApplicable : true,
    indexMonthIdx: tenant ? tenant.indexMonthIdx : 1,
    startDate: tenant ? tenant.startDate : '',
    endDate: tenant ? tenant.endDate : '',
    noticeMonths: tenant ? tenant.noticeMonths : 6,
  });
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState('');
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));

  const valid = String(f.name).trim() && String(f.unit).trim() && Number(f.rentNet) > 0;

  const opslaan = async () => {
    setBusy(true); setError('');
    try {
      if (isEdit) {
        await window.API.wijzigHuurder(tenant.id, {
          name: f.name, contactVoornaam: f.contactVoornaam, contactAchternaam: f.contactAchternaam,
          contactRole: f.contactRole, phone: f.phone, email: f.email,
          invoiceEmail: f.invoiceEmail, kvk: f.kvk, surface: Number(f.surface) || 0,
        });
        await window.API.wijzigContract(tenant.contractId, {
          rentNet: Number(f.rentNet), vatApplicable: f.vatApplicable,
          indexMonthIdx: Number(f.indexMonthIdx), startDate: f.startDate,
          endDate: f.endDate, noticeMonths: Number(f.noticeMonths),
        });
      } else {
        await window.API.nieuweHuurder({
          name: f.name, contactVoornaam: f.contactVoornaam, contactAchternaam: f.contactAchternaam,
          contactRole: f.contactRole, phone: f.phone, email: f.email,
          invoiceEmail: f.invoiceEmail, kvk: f.kvk, unit: String(f.unit).trim(),
          surface: Number(f.surface) || 0, rentNet: Number(f.rentNet),
          vatApplicable: f.vatApplicable, indexMonthIdx: Number(f.indexMonthIdx),
          startDate: f.startDate, endDate: f.endDate, noticeMonths: Number(f.noticeMonths),
        });
      }
      await onSaved();
    } catch (e) {
      setError(e.message);
      setBusy(false);
    }
  };

  return (
    <Modal title={isEdit ? 'Huurder bewerken' : 'Nieuwe huurder'}
           sub={isEdit ? tenant.name : 'Huurder, unit en contract in één keer vastleggen.'}
           onClose={onClose} size="lg"
           footer={<>
             <button className="btn" onClick={onClose} disabled={busy}>Annuleren</button>
             <button className="btn btn-accent" disabled={!valid || busy}
                     onClick={opslaan} style={{ opacity: (valid && !busy) ? 1 : 0.4 }}>
               <Icons.Check />{busy ? 'Bezig…' : 'Opslaan'}
             </button>
           </>}>
      <div className="stack">
        {error && <div className="banner banner-warning" style={{ fontSize: 12.5 }}>{error}</div>}
        <div>
          <label className="field-label">Bedrijfsnaam</label>
          <input className="input" value={f.name} onChange={e => set('name', e.target.value)} autoFocus />
        </div>
        <div className="form-grid">
          <div>
            <label className="field-label">Contact — voornaam</label>
            <input className="input" value={f.contactVoornaam} onChange={e => set('contactVoornaam', e.target.value)} />
          </div>
          <div>
            <label className="field-label">Contact — achternaam</label>
            <input className="input" value={f.contactAchternaam} onChange={e => set('contactAchternaam', e.target.value)} />
          </div>
          <div>
            <label className="field-label">Functie</label>
            <input className="input" value={f.contactRole} onChange={e => set('contactRole', e.target.value)} />
          </div>
          <div>
            <label className="field-label">Telefoon</label>
            <input className="input" value={f.phone} onChange={e => set('phone', e.target.value)} />
          </div>
          <div>
            <label className="field-label">Algemeen e-mail</label>
            <input className="input" value={f.email} onChange={e => set('email', e.target.value)} />
          </div>
          <div>
            <label className="field-label">Facturatie-e-mail</label>
            <input className="input" value={f.invoiceEmail} onChange={e => set('invoiceEmail', e.target.value)} />
          </div>
          <div>
            <label className="field-label">KvK-nummer</label>
            <input className="input" value={f.kvk} onChange={e => set('kvk', e.target.value)} />
          </div>
          <div>
            <label className="field-label">Unit</label>
            <input className="input" value={f.unit} onChange={e => set('unit', e.target.value)}
                   disabled={isEdit} placeholder="bijv. 1f" />
          </div>
          <div>
            <label className="field-label">Oppervlakte (m²)</label>
            <input className="input" type="number" value={f.surface} onChange={e => set('surface', e.target.value)} />
          </div>
          <div>
            <label className="field-label">Huurprijs ex btw / maand</label>
            <input className="input" type="number" step="0.01" value={f.rentNet} onChange={e => set('rentNet', e.target.value)} />
          </div>
          <div>
            <label className="field-label">BTW-belast</label>
            <select className="select" value={f.vatApplicable ? 'ja' : 'nee'}
                    onChange={e => set('vatApplicable', e.target.value === 'ja')}>
              <option value="ja">Ja — 21%</option>
              <option value="nee">Nee — vrijgesteld / verlegd</option>
            </select>
          </div>
          <div>
            <label className="field-label">Indexatiemaand</label>
            <select className="select" value={f.indexMonthIdx} onChange={e => set('indexMonthIdx', e.target.value)}>
              {NL_MAANDEN.map((m, i) => <option key={i} value={i + 1}>{m}</option>)}
            </select>
          </div>
          <div>
            <label className="field-label">Ingangsdatum</label>
            <input className="input" type="date" value={f.startDate} onChange={e => set('startDate', e.target.value)} />
          </div>
          <div>
            <label className="field-label">Einddatum</label>
            <input className="input" type="date" value={f.endDate || ''} onChange={e => set('endDate', e.target.value)} />
          </div>
          <div>
            <label className="field-label">Opzegtermijn (maanden)</label>
            <input className="input" type="number" value={f.noticeMonths} onChange={e => set('noticeMonths', e.target.value)} />
          </div>
        </div>
      </div>
    </Modal>
  );
}

/* ============================================================
   FACTUREN — LIJST
   ============================================================ */
function InvoicesList({ navigate, reload }) {
  const { Card, Search, Tabs, Unit, StatusBadge, Modal } = window.UI;
  const { INVOICES, PROPERTY, fmtEUR, fmtDateShort } = window.SW_DATA;
  const invoices = INVOICES;

  const [filter, setFilter] = React.useState('open');
  const [q, setQ] = React.useState('');
  const [markModal, setMarkModal] = React.useState(null);
  const [confirmAmount, setConfirmAmount] = React.useState('');
  const [betaalDatum, setBetaalDatum] = React.useState(new Date().toISOString().slice(0, 10));
  const [busy, setBusy] = React.useState(false);

  const counts = {
    open: invoices.filter(i => i.sent && !i.paid).length,
    paid: invoices.filter(i => i.paid).length,
    all: invoices.length,
    concept: invoices.filter(i => !i.sent).length,
  };

  let rows = invoices;
  if (filter === 'open') rows = rows.filter(i => i.sent && !i.paid);
  else if (filter === 'paid') rows = rows.filter(i => i.paid);
  else if (filter === 'concept') rows = rows.filter(i => !i.sent);
  if (q) {
    const Q = q.toLowerCase();
    rows = rows.filter(i => (i.number + i.tenantName + i.periodLabel + i.unit).toLowerCase().includes(Q));
  }

  const concept = invoices.filter(i => !i.sent);
  const toSendCount = concept.length;

  const expected = markModal ? markModal.total : 0;
  const parsedAmount = parseFloat(String(confirmAmount).replace(/\./g, '').replace(',', '.'));
  const amountOk = !!markModal && Math.abs(parsedAmount - expected) < 0.01;

  const bevestigBetaald = async () => {
    setBusy(true);
    try {
      await window.API.betaalFactuur(markModal.number, { datum: betaalDatum, bedrag: parsedAmount });
      await reload();
      setMarkModal(null);
    } catch (e) { alert('Kon factuur niet op betaald zetten: ' + e.message); }
    setBusy(false);
  };

  const genereerBatch = async () => {
    const nu = new Date();
    if (!confirm(`Concept-facturen aanmaken voor ${NL_MAANDEN[nu.getMonth()]} ${nu.getFullYear()}?`)) return;
    try {
      const r = await window.API.genereerFacturen(nu.getFullYear(), nu.getMonth() + 1);
      await reload();
      alert(r.aangemaakt > 0 ? `${r.aangemaakt} concept-facturen aangemaakt.`
        : 'Alle facturen voor deze maand bestaan al.');
    } catch (e) { alert('Aanmaken mislukt: ' + e.message); }
  };

  const verstuurBatch = async () => {
    if (!concept.length) return;
    const p = concept[0].period;
    if (!confirm(`${toSendCount} facturen nu versturen naar de huurders?`)) return;
    try {
      const r = await window.API.verstuurBatch(p.y, p.m);
      await reload();
      alert(`${r.verstuurd} facturen verstuurd${r.mislukt ? `, ${r.mislukt} mislukt` : ''}.`);
    } catch (e) { alert('Versturen mislukt: ' + e.message); }
  };

  const exporteer = () => {
    const head = ['Factuurnummer','Huurder','Unit','Aanmaakdatum','Periode','Ex btw','BTW','Totaal','Verzonden','Betaald'];
    const lijnen = rows.map(i => [
      i.number, i.tenantName, i.unit, i.createdDate, i.periodLabel,
      i.rentNet, i.vat, i.total, i.sent ? 'ja' : 'nee', i.paid ? 'ja' : 'nee',
    ].join(';'));
    const blob = new Blob([[head.join(';'), ...lijnen].join('\n')], { type: 'text/csv' });
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = 'facturen-export.csv';
    a.click();
    URL.revokeObjectURL(a.href);
  };

  return (
    <div className="stack-lg">
      {toSendCount > 0 && (
        <div className="banner banner-accent">
          <Icons.Send />
          <div className="grow">
            <div style={{ fontWeight: 550, color: 'var(--accent)' }}>Volgende verzendbatch</div>
            <div style={{ fontSize: 12.5, marginTop: 2 }}>{toSendCount} facturen klaar om automatisch te versturen naar de facturatie-e-mailadressen.</div>
          </div>
          <button className="btn btn-sm" onClick={() => setFilter('concept')}>Batch bekijken</button>
          <button className="btn btn-sm btn-accent" style={{ background: 'var(--accent)' }} onClick={verstuurBatch}>Nu versturen</button>
        </div>
      )}

      <div className="row-between">
        <div className="row">
          <Tabs value={filter} onChange={setFilter}
            options={[
              { value: 'open',    label: 'Open',    count: counts.open },
              { value: 'paid',    label: 'Betaald', count: counts.paid },
              { value: 'concept', label: 'Concept', count: counts.concept },
              { value: 'all',     label: 'Alles',   count: counts.all },
            ]} />
          <Search value={q} onChange={setQ} placeholder="Zoek op factuurnummer, huurder…" />
        </div>
        <div className="row">
          <button className="btn" onClick={exporteer}><Icons.Download />Exporteren</button>
          <button className="btn btn-primary" onClick={genereerBatch}><Icons.Plus />Facturen aanmaken</button>
        </div>
      </div>

      <Card flush>
        <table className="table">
          <thead>
            <tr>
              <th>Factuurnummer</th>
              <th>Huurder</th>
              <th>Aanmaakdatum</th>
              <th>Periode</th>
              <th className="right">Ex btw</th>
              <th className="right">BTW</th>
              <th className="right">Totaal</th>
              <th>Verzonden</th>
              <th>Betaald</th>
            </tr>
          </thead>
          <tbody>
            {rows.map(inv => (
              <tr key={inv.id} className="clickable" onClick={() => navigate('invoices/' + inv.id)}>
                <td><span className="invnum">{inv.number}</span></td>
                <td>{inv.tenantName} <span className="muted">· </span><Unit>{inv.unit}</Unit></td>
                <td className="muted">{fmtDateShort(inv.createdDate)}</td>
                <td>{inv.periodLabel}</td>
                <td className="amount">{fmtEUR(inv.rentNet)}</td>
                <td className="amount muted">{inv.vat ? fmtEUR(inv.vat) : '—'}</td>
                <td className="amount" style={{ fontWeight: 550 }}>{fmtEUR(inv.total)}</td>
                <td><window.UI.YesNo yes={inv.sent} yesLabel={inv.sentDate ? fmtDateShort(inv.sentDate) : 'Ja'} noLabel="—" /></td>
                <td onClick={e => e.stopPropagation()}>
                  {inv.paid
                    ? <window.UI.YesNo yes={true} yesLabel={fmtDateShort(inv.paidDate)} />
                    : inv.sent
                      ? <button className="btn btn-sm" onClick={() => { setMarkModal(inv); setConfirmAmount(''); setBetaalDatum(new Date().toISOString().slice(0,10)); }}>Markeer betaald</button>
                      : <span className="muted">—</span>
                  }
                </td>
              </tr>
            ))}
            {rows.length === 0 && (
              <tr><td colSpan={9} style={{ textAlign: 'center', padding: 40, color: 'var(--muted)' }}>Geen facturen in deze weergave.</td></tr>
            )}
          </tbody>
        </table>
      </Card>

      {markModal && (
        <Modal
          title="Factuur op betaald zetten"
          sub={`Factuur ${markModal.number} · ${markModal.tenantName}`}
          onClose={() => setMarkModal(null)}
          footer={
            <>
              <button className="btn" onClick={() => setMarkModal(null)} disabled={busy}>Annuleren</button>
              <button className="btn btn-accent" disabled={!amountOk || busy}
                      onClick={bevestigBetaald}
                      style={{ opacity: (amountOk && !busy) ? 1 : 0.4 }}>
                <Icons.Check />{busy ? 'Bezig…' : 'Bevestigen'}
              </button>
            </>
          }>
          <div className="stack">
            <div className="banner" style={{ background: 'var(--surface-2)' }}>
              <Icons.Alert />
              <div>
                <div style={{ fontSize: 13, fontWeight: 550 }}>Verwacht ontvangen bedrag</div>
                <div style={{ fontSize: 20, fontWeight: 600, marginTop: 2, fontVariantNumeric: 'tabular-nums' }}>
                  {fmtEUR(markModal.total)}
                </div>
              </div>
            </div>
            <div>
              <label className="field-label">Ontvangen bedrag (controle)</label>
              <input className="input" placeholder="€ 0,00" value={confirmAmount}
                     onChange={e => setConfirmAmount(e.target.value)} autoFocus />
              <div style={{ fontSize: 12, marginTop: 6, color: amountOk ? 'var(--success)' : 'var(--muted)' }}>
                {confirmAmount && !amountOk ? 'Bedrag wijkt af van het verwachte bedrag.' :
                 amountOk ? '✓ Bedrag komt overeen met factuur.' : 'Vul het ontvangen bedrag in om te bevestigen.'}
              </div>
            </div>
            <div className="form-grid">
              <div>
                <label className="field-label">Betaaldatum</label>
                <input className="input" type="date" value={betaalDatum}
                       onChange={e => setBetaalDatum(e.target.value)} />
              </div>
              <div>
                <label className="field-label">Rekening</label>
                <input className="input" value={PROPERTY.iban || ''} disabled />
              </div>
            </div>
          </div>
        </Modal>
      )}
    </div>
  );
}

/* ============================================================
   FACTUUR — DETAIL
   ============================================================ */
function InvoiceDetail({ id, navigate, reload }) {
  const { Card, Breadcrumb, StatusBadge, Unit, Modal } = window.UI;
  const { INVOICES, TENANTS, PROPERTY, SETTINGS, fmtEUR, fmtDate } = window.SW_DATA;

  const inv = INVOICES.find(i => i.id === id);
  const [markOpen, setMarkOpen] = React.useState(false);
  const [toonPdf, setToonPdf] = React.useState(false);
  const [confirmAmount, setConfirmAmount] = React.useState('');
  const [betaalDatum, setBetaalDatum] = React.useState(new Date().toISOString().slice(0, 10));
  const [busy, setBusy] = React.useState(false);

  if (!inv) return <div>Factuur niet gevonden</div>;
  const tenant = TENANTS.find(t => t.id === inv.tenantId);

  const parsedAmount = parseFloat(String(confirmAmount).replace(/\./g, '').replace(',', '.'));
  const amountOk = Math.abs(parsedAmount - inv.total) < 0.01;

  // De huur moet vóór de eerste van de gefactureerde maand binnen zijn;
  // er wordt immers vooruit gefactureerd.
  const vervalDatum = () =>
    `${inv.period.y}-${String(inv.period.m).padStart(2, '0')}-01`;

  const bevestigBetaald = async () => {
    setBusy(true);
    try {
      await window.API.betaalFactuur(inv.number, { datum: betaalDatum, bedrag: parsedAmount });
      await reload();
      setMarkOpen(false);
    } catch (e) { alert('Kon factuur niet op betaald zetten: ' + e.message); }
    setBusy(false);
  };

  const verstuurNu = async () => {
    if (!confirm(`Factuur ${inv.number} nu versturen naar ${tenant ? tenant.name : 'de huurder'}?`)) return;
    try {
      const r = await window.API.verstuurFactuur(inv.number);
      await reload();
      alert(r.dryRun
        ? 'Factuur gemarkeerd als verzonden. Er is nog geen e-mailkoppeling actief — stel MailerSend in via .env.'
        : 'Factuur verstuurd.');
    } catch (e) { alert('Versturen mislukt: ' + e.message); }
  };

  return (
    <div className="stack-lg">
      <Breadcrumb navigate={navigate} items={[
        { label: 'Facturen', to: 'invoices' },
        { label: inv.number },
      ]} />

      <div className="row-between">
        <div>
          <div className="row" style={{ gap: 14 }}>
            <div className="h1">Factuur <span className="mono" style={{ fontWeight: 600 }}>{inv.number}</span></div>
            <StatusBadge paid={inv.paid} sent={inv.sent} error={inv.sendError} channel={inv.sendChannel} />
          </div>
          <div className="muted" style={{ marginTop: 6 }}>
            {inv.tenantName} · <Unit>{inv.unit}</Unit> · periode {inv.periodLabel}
          </div>
        </div>
        <div className="row">
          {/* download-attribuut: opslaan, niet een tabblad openen */}
          <a className="btn" href={window.API.pdfUrl(inv.number)}
             download={`Factuur-${inv.number}.pdf`}><Icons.Download />Download PDF</a>
          {inv.sent ? null : <button className="btn" onClick={verstuurNu}><Icons.Send />Nu versturen</button>}
          {!inv.paid && inv.sent && <button className="btn btn-accent" onClick={() => { setMarkOpen(true); setConfirmAmount(''); setBetaalDatum(new Date().toISOString().slice(0,10)); }}>
            <Icons.Check />Markeer betaald
          </button>}
        </div>
      </div>

      {inv.sendError && !inv.sent && (
        <div className="banner banner-danger">
          <span className="banner-icoon"><Icons.X size={18} stroke={2} /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <strong>Deze factuur is niet verstuurd</strong>
            <div className="verzend-fout-tekst" style={{ marginTop: 4, whiteSpace: 'normal' }}>{inv.sendError}</div>
            <div className="muted" style={{ marginTop: 4 }}>
              Laatste poging {fmtDate(inv.sendErrorDate)}
              {inv.sendAttempts > 1 ? ` · ${inv.sendAttempts} pogingen` : ''}. De huurder heeft niets ontvangen.
            </div>
          </div>
        </div>
      )}

      {inv.sent && inv.sendChannel === 'dry-run' && (
        <div className="banner banner-warning">
          <span className="banner-icoon"><Icons.Mail size={18} stroke={2} /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <strong>Als verzonden gemarkeerd, maar nooit gemaild</strong>
            <div className="muted">
              Verstuurd in proefstand ({fmtDate(inv.sentDate)}), toen de e-mailkoppeling uit stond.
            </div>
          </div>
        </div>
      )}

      <div className="split-2-3">
        <div className="stack">
          <Card title="Factuurgegevens">
            <div className="form-grid">
              <KV label="Factuurnummer" value={<span className="mono">{inv.number}</span>} />
              <KV label="Periode" value={inv.periodLabel} />
              <KV label="Aanmaakdatum" value={fmtDate(inv.createdDate)} />
              <KV label="Verzenddatum" value={
                inv.sent
                  ? <>{fmtDate(inv.sentDate)}{inv.sendChannel === 'dry-run' && <span className="muted"> · proefstand, niet gemaild</span>}</>
                  : <span style={{ color: inv.sendError ? 'var(--danger)' : 'var(--warning)' }}>
                      {inv.sendError ? 'Verzending mislukt' : 'Nog niet verzonden'}
                    </span>
              } />
              <KV label="Te voldoen vóór" value={fmtDate(vervalDatum())} />
              <KV label="Betaaldatum" value={inv.paid ? fmtDate(inv.paidDate) : <span className="muted">—</span>} />
            </div>
            <hr className="hr" />
            <table className="table" style={{ border: 0 }}>
              <thead>
                <tr>
                  <th style={{ background: 'transparent', position: 'static' }}>Omschrijving</th>
                  <th className="right" style={{ background: 'transparent', position: 'static' }}>Bedrag</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td>Huur bedrijfsruimte {inv.unitAddress || inv.unit} — {inv.periodLabel}</td>
                  <td className="amount">{fmtEUR(inv.rentNet)}</td>
                </tr>
                <tr>
                  <td className="muted">BTW {inv.vat ? '(21%)' : ''}</td>
                  <td className="amount">{fmtEUR(inv.vat)}</td>
                </tr>
                <tr className="row-strong">
                  <td>Totaal</td>
                  <td className="amount">{fmtEUR(inv.total)}</td>
                </tr>
              </tbody>
            </table>
          </Card>

          {tenant && (
            <Card title="Huurder"
                  action={<button className="btn btn-sm btn-ghost" onClick={() => navigate('tenants/' + tenant.id)}>Naar profiel <Icons.Chevron size={13} /></button>}>
              <div className="form-grid">
                <KV label="Bedrijf" value={tenant.name} />
                <KV label="Contactpersoon" value={tenant.contact || '—'} />
                <KV label="Facturatie-e-mail" value={tenant.invoiceEmail || '—'} />
                <KV label="Telefoon" value={tenant.phone || '—'} />
              </div>
            </Card>
          )}
        </div>

        {/* PDF-voorbeeld — pas ophalen als erom gevraagd wordt.
            Een browser die is ingesteld om PDF's te downloaden in plaats
            van te tonen, begint anders een download zodra je een factuur
            opent. Dat hoort een keuze te zijn, geen bijwerking. */}
        <div>
          <div className="card-header" style={{ borderBottom: 0, padding: '0 0 14px' }}>
            <div className="h2">Factuur</div>
            {toonPdf && (
              <a className="btn btn-sm btn-ghost" href={window.API.pdfUrl(inv.number)}
                 target="_blank" rel="noopener"><Icons.External />Volledig scherm</a>
            )}
          </div>
          {toonPdf
            ? <iframe className="pdf-preview" title={`Factuur ${inv.number}`}
                      src={window.API.pdfUrl(inv.number) + '#toolbar=0&view=FitH'} />
            : (
              <div className="pdf-preview pdf-preview-leeg">
                <Icons.File size={22} />
                <div className="h3" style={{ marginTop: 10 }}>Factuur {inv.number}</div>
                <div className="muted" style={{ fontSize: 13, maxWidth: 280, textAlign: 'center' }}>
                  {inv.tenantName} · {inv.periodLabel} · {fmtEUR(inv.total)}
                </div>
                <button className="btn" style={{ marginTop: 16 }} onClick={() => setToonPdf(true)}>
                  <Icons.Eye />Voorbeeld tonen
                </button>
                <div className="muted" style={{ fontSize: 12, marginTop: 10, textAlign: 'center', maxWidth: 300 }}>
                  Of gebruik <strong>Download PDF</strong> hierboven om hem op te slaan.
                </div>
              </div>
            )}
        </div>
      </div>

      {markOpen && (
        <Modal title="Factuur op betaald zetten"
               sub={`Factuur ${inv.number} · ${inv.tenantName}`}
               onClose={() => setMarkOpen(false)}
               footer={<>
                 <button className="btn" onClick={() => setMarkOpen(false)} disabled={busy}>Annuleren</button>
                 <button className="btn btn-accent" disabled={!amountOk || busy}
                   onClick={bevestigBetaald}
                   style={{ opacity: (amountOk && !busy) ? 1 : 0.4 }}>
                   <Icons.Check />{busy ? 'Bezig…' : 'Bevestigen'}
                 </button>
               </>}>
          <div className="stack">
            <div className="banner" style={{ background: 'var(--surface-2)' }}>
              <Icons.Alert />
              <div>
                <div style={{ fontSize: 13, fontWeight: 550 }}>Verwacht ontvangen bedrag</div>
                <div style={{ fontSize: 20, fontWeight: 600, marginTop: 2 }}>{fmtEUR(inv.total)}</div>
              </div>
            </div>
            <div>
              <label className="field-label">Ontvangen bedrag (controle)</label>
              <input className="input" placeholder="€ 0,00" value={confirmAmount}
                     onChange={e => setConfirmAmount(e.target.value)} autoFocus />
              <div style={{ fontSize: 12, marginTop: 6, color: amountOk ? 'var(--success)' : 'var(--muted)' }}>
                {confirmAmount && !amountOk ? 'Bedrag wijkt af van het verwachte bedrag.' :
                 amountOk ? '✓ Bedrag komt overeen met factuur.' : 'Vul het ontvangen bedrag in om te bevestigen.'}
              </div>
            </div>
            <div>
              <label className="field-label">Betaaldatum</label>
              <input className="input" type="date" value={betaalDatum}
                     onChange={e => setBetaalDatum(e.target.value)} />
            </div>
          </div>
        </Modal>
      )}
    </div>
  );
}

/* ============================================================
   DOCUMENTEN
   ============================================================ */
function DocumentsScreen({ navigate, reload }) {
  const { Card, Search } = window.UI;
  const { DOCUMENTS, TENANTS, fmtDateShort } = window.SW_DATA;
  const [q, setQ] = React.useState('');
  const [cat, setCat] = React.useState('Alle');
  const [uploadOpen, setUploadOpen] = React.useState(false);

  const categories = ['Alle', 'Taxaties', 'Verzekeringspolissen', 'Huurcontracten', 'Aanslagen', 'Offertes', 'Overig'];
  let rows = DOCUMENTS;
  if (cat !== 'Alle') rows = rows.filter(d => d.category === cat);
  if (q) rows = rows.filter(d => (d.name + d.category).toLowerCase().includes(q.toLowerCase()));
  rows = [...rows].sort((a,b) => a.date < b.date ? 1 : -1);

  const openDoc = (d) => {
    if (!d.hasFile) {
      alert('Voor dit voorbeelddocument is geen bestand opgeslagen. Upload het echte bestand om het te kunnen openen.');
      return;
    }
    window.open(window.API.documentUrl(d.id), '_blank');
  };

  return (
    <div className="stack-lg">
      <div className="row-between">
        <div className="row" style={{ flexWrap: 'wrap' }}>
          {categories.map(c => (
            <button key={c} className={'chip' + (cat === c ? ' active' : '')} onClick={() => setCat(c)}>
              {c} <span style={{ opacity: 0.6 }}>{c === 'Alle' ? DOCUMENTS.length : DOCUMENTS.filter(d => d.category === c).length}</span>
            </button>
          ))}
        </div>
        <div className="row">
          <Search value={q} onChange={setQ} placeholder="Zoek document…" />
          <button className="btn btn-primary" onClick={() => setUploadOpen(true)}><Icons.Upload />Uploaden</button>
        </div>
      </div>

      <Card flush>
        <table className="table">
          <thead>
            <tr>
              <th>Naam</th>
              <th>Categorie</th>
              <th>Gekoppeld aan</th>
              <th>Datum</th>
              <th className="right">Grootte</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {rows.map(d => {
              const tenant = d.tenantId ? TENANTS.find(t => t.id === d.tenantId) : null;
              return (
                <tr key={d.id}>
                  <td>
                    <div className="row" style={{ gap: 10 }}>
                      <Icons.File size={15} />
                      <span style={{ fontWeight: 500 }}>{d.name}</span>
                    </div>
                  </td>
                  <td><span className="badge badge-neutral">{d.category}</span></td>
                  <td>
                    {tenant ? <span>{tenant.name} <span className="muted">· </span><span className="unit">{tenant.unit}</span></span>
                            : <span className="muted">Pand algemeen</span>}
                  </td>
                  <td className="muted">{fmtDateShort(d.date)}</td>
                  <td className="amount muted">{d.size}</td>
                  <td onClick={e => e.stopPropagation()}>
                    <div className="row" style={{ gap: 4, justifyContent: 'flex-end' }}>
                      <button className="btn btn-sm btn-ghost btn-icon" title="Bekijken" onClick={() => openDoc(d)}><Icons.Eye /></button>
                      <button className="btn btn-sm btn-ghost btn-icon" title="Downloaden" onClick={() => openDoc(d)}><Icons.Download /></button>
                    </div>
                  </td>
                </tr>
              );
            })}
            {rows.length === 0 && (
              <tr><td colSpan={6} style={{ textAlign: 'center', padding: 40, color: 'var(--muted)' }}>Geen documenten gevonden.</td></tr>
            )}
          </tbody>
        </table>
      </Card>

      {uploadOpen && (
        <DocumentUploadModal onClose={() => setUploadOpen(false)}
          onSaved={async () => { await reload(); setUploadOpen(false); }} />
      )}
    </div>
  );
}

function DocumentUploadModal({ onderhoudId, onClose, onSaved }) {
  const { Modal } = window.UI;
  const { TENANTS } = window.SW_DATA;
  const [bestand, setBestand] = React.useState(null);
  const [naam, setNaam] = React.useState('');
  const [categorie, setCategorie] = React.useState('Overig');
  const [huurderId, setHuurderId] = React.useState('');
  const [datum, setDatum] = React.useState(new Date().toISOString().slice(0, 10));
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState('');

  const kiesBestand = (file) => {
    setBestand(file);
    if (file && !naam) setNaam(file.name);
  };

  const uploaden = async () => {
    if (!bestand) return;
    setBusy(true); setError('');
    try {
      const fd = new FormData();
      fd.append('bestand', bestand);
      fd.append('naam', naam || bestand.name);
      fd.append('categorie', categorie);
      fd.append('datum', datum);
      if (huurderId) fd.append('huurderId', huurderId);
      if (onderhoudId) fd.append('onderhoudId', onderhoudId);
      await window.API.uploadDocument(fd);
      await onSaved();
    } catch (e) { setError(e.message); setBusy(false); }
  };

  return (
    <Modal title="Document uploaden"
           sub="Voeg een bestand toe aan het centrale archief."
           onClose={onClose}
           footer={<>
             <button className="btn" onClick={onClose} disabled={busy}>Annuleren</button>
             <button className="btn btn-accent" disabled={!bestand || busy}
                     onClick={uploaden} style={{ opacity: (bestand && !busy) ? 1 : 0.4 }}>
               <Icons.Upload />{busy ? 'Bezig…' : 'Uploaden'}
             </button>
           </>}>
      <div className="stack">
        {error && <div className="banner banner-warning" style={{ fontSize: 12.5 }}>{error}</div>}
        <div>
          <label className="field-label">Bestand</label>
          <input type="file" onChange={e => kiesBestand(e.target.files[0])} />
        </div>
        <div>
          <label className="field-label">Naam</label>
          <input className="input" value={naam} onChange={e => setNaam(e.target.value)} placeholder="Documentnaam" />
        </div>
        <div className="form-grid">
          <div>
            <label className="field-label">Categorie</label>
            <select className="select" value={categorie} onChange={e => setCategorie(e.target.value)}>
              {['Taxaties','Verzekeringspolissen','Huurcontracten','Aanslagen','Offertes','Overig']
                .map(c => <option key={c} value={c}>{c}</option>)}
            </select>
          </div>
          <div>
            <label className="field-label">Datum</label>
            <input className="input" type="date" value={datum} onChange={e => setDatum(e.target.value)} />
          </div>
          {!onderhoudId && (
            <div className="full">
              <label className="field-label">Gekoppeld aan</label>
              <select className="select" value={huurderId} onChange={e => setHuurderId(e.target.value)}>
                <option value="">Pand algemeen</option>
                {TENANTS.map(t => <option key={t.id} value={t.id}>{t.name} — unit {t.unit}</option>)}
              </select>
            </div>
          )}
        </div>
      </div>
    </Modal>
  );
}

Object.assign(window.Screens, {
  Dashboard, TenantsList, TenantDetail,
  InvoicesList, InvoiceDetail, DocumentsScreen,
  KV, TenantFormModal, DocumentUploadModal,
});

})();
