/* SECUNDAIRE SCHERMEN: Contracten, Onderhoud, Exploitatie, Instellingen, Login */

(function () {
const { Icons } = window;

// Data wordt per render uit window.SW_DATA gelezen (pas geladen na inloggen).

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

const KV = (props) => window.Screens.KV(props);

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

  const today = new Date();

  const rows = TENANTS.filter(t => !q || (t.name + t.unit).toLowerCase().includes(q.toLowerCase()))
    .map(t => {
      // Geen einddatum = doorlopend contract; dan is er niets af te tellen.
      const end = t.endDate ? new Date(t.endDate) : null;
      const monthsToEnd = end ? Math.round((end - today) / (1000 * 60 * 60 * 24 * 30.4)) : null;
      const nextIndex = new Date(today.getFullYear(), t.indexMonthIdx - 1, 1);
      if (nextIndex < today) nextIndex.setFullYear(today.getFullYear() + 1);
      const monthsToIndex = Math.round((nextIndex - today) / (1000 * 60 * 60 * 24 * 30.4));
      let signal = null;
      if (monthsToEnd !== null && monthsToEnd <= 6 && monthsToEnd >= 0) signal = 'danger';
      else if (monthsToIndex <= 2) signal = 'warn';
      return { ...t, monthsToEnd, monthsToIndex, signal };
    });

  return (
    <div className="stack-lg">
      <div className="row-between">
        <div className="row">
          <Search value={q} onChange={setQ} placeholder="Zoek huurder of unit…" />
          <span className="legend">
            <span className="legend-item"><span className="tag-dot" style={{ background: 'var(--danger)' }}></span>einddatum ≤ 6 mnd</span>
            <span className="legend-item"><span className="tag-dot" style={{ background: 'var(--warning)' }}></span>indexatie ≤ 2 mnd</span>
          </span>
        </div>
        <button className="btn btn-primary" onClick={() => setFormOpen(true)}><Icons.Plus />Nieuw contract</button>
      </div>

      <Card flush>
        <table className="table">
          <thead>
            <tr>
              <th>Huurder</th>
              <th>Unit</th>
              <th>Ingangsdatum</th>
              <th>Einddatum</th>
              <th>Looptijd</th>
              <th>Opzegtermijn</th>
              <th className="right">Huur ex btw</th>
              <th>BTW</th>
              <th>Indexatie</th>
            </tr>
          </thead>
          <tbody>
            {rows.map(t => (
              <tr key={t.id}
                  className={'clickable ' + (t.signal === 'danger' ? 'signal-danger' : t.signal === 'warn' ? 'signal-warn' : '')}
                  onClick={() => navigate('contracts/' + t.id)}>
                <td style={{ fontWeight: 550 }}>{t.name}</td>
                <td><Unit>{t.unit}</Unit></td>
                <td className="muted">{fmtDateShort(t.startDate)}</td>
                <td>
                  <div>{t.endDate ? fmtDateShort(t.endDate) : 'doorlopend'}</div>
                  {t.signal === 'danger' &&
                    <div style={{ fontSize: 11.5, color: 'var(--danger)', marginTop: 2 }}>over {t.monthsToEnd} mnd</div>}
                </td>
                <td className="muted">{t.termYears ? `${Math.round(t.termYears)} jaar` : '—'}</td>
                <td className="muted">{t.noticeMonths} mnd</td>
                <td className="amount" style={{ fontWeight: 550 }}>{fmtEUR(t.rentNet)}</td>
                <td>{t.vatApplicable
                  ? <window.UI.YesNo yes={true} />
                  : <window.UI.YesNo yes={false} noLabel="Nee" />}</td>
                <td>
                  <div>{t.indexMonth}</div>
                  {t.signal === 'warn' &&
                    <div style={{ fontSize: 11.5, color: 'var(--warning)', marginTop: 2 }}>over {t.monthsToIndex} mnd</div>}
                </td>
              </tr>
            ))}
            {rows.length === 0 && (
              <tr><td colSpan={9} style={{ textAlign: 'center', padding: 40, color: 'var(--muted)' }}>Geen contracten gevonden.</td></tr>
            )}
          </tbody>
        </table>
      </Card>

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

/* ============================================================
   CONTRACT — DETAIL
   ============================================================ */
function ContractDetail({ id, navigate, reload }) {
  const { Card, Breadcrumb, Unit } = window.UI;
  const { TENANTS, DOCUMENTS, PROPERTY, fmtEUR, fmtDate } = window.SW_DATA;
  const [editOpen, setEditOpen] = React.useState(false);

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

  const bestemming = /crossfit/i.test(t.name) ? 'Sportschool / fitness'
    : /storage|loods/i.test(t.name) ? 'Self-storage' : 'Bedrijfsmatig';
  const contractDoc = DOCUMENTS.find(d => d.tenantId === t.id && d.category === 'Huurcontracten' && d.hasFile);

  const openContractPdf = () => {
    if (contractDoc) window.open(window.API.documentUrl(contractDoc.id), '_blank');
    else alert('Er is nog geen contract-PDF gekoppeld. Upload het huurcontract via Documenten.');
  };

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

      <div className="row-between">
        <div>
          <div className="h1">Contract — {t.name}</div>
          <div className="muted" style={{ marginTop: 6 }}>Unit <span className="unit">{t.unit}</span> · {t.surface} m²</div>
        </div>
        <div className="row">
          <button className="btn" onClick={openContractPdf}><Icons.Download />Contract-PDF</button>
          <button className="btn btn-primary" onClick={() => setEditOpen(true)}><Icons.Edit />Bewerken</button>
        </div>
      </div>

      <div className="split-2-3">
        <Card title="Hoofdvoorwaarden">
          <div className="form-grid">
            <KV label="Huurder" value={t.name} />
            <KV label="KvK" value={t.kvk || '—'} />
            <KV label="Unit" value={<Unit>{t.unit}</Unit>} />
            <KV label="Oppervlakte" value={`${t.surface} m²`} />
            <KV label="Ingangsdatum" value={fmtDate(t.startDate)} />
            <KV label="Einddatum" value={t.endDate ? fmtDate(t.endDate) : 'doorlopend'} />
            <KV label="Looptijd" value={t.termYears ? `${Math.round(t.termYears)} jaar` : 'onbepaalde tijd'} />
            <KV label="Opzegtermijn" value={`${t.noticeMonths} maanden`} />
            <KV label="Huurprijs ex btw" value={<strong>{fmtEUR(t.rentNet)}</strong>} />
            <KV label="BTW-belast" value={t.vatApplicable ? 'Ja (21%)' : 'Nee — vrijgesteld'} />
            <KV label="Indexatie" value={`Jaarlijks per 1 ${t.indexMonth}`} />
            <KV label="Indexatiemethode" value="CBS CPI alle huishoudens" />
          </div>
        </Card>

        <Card title="Notities & bepalingen">
          <div className="stack-sm">
            <div style={{ fontSize: 13, lineHeight: 1.6 }}>
              Huurder huurt unit {t.unit} (gebouw {PROPERTY.name}, {PROPERTY.address}) {t.termYears ? `voor een vaste periode van ${Math.round(t.termYears)} jaar` : 'voor onbepaalde tijd'}.
              Na afloop wordt het contract stilzwijgend verlengd met telkens 5 jaar, tenzij één van partijen het opzegt
              met inachtneming van een termijn van {t.noticeMonths} maanden.
            </div>
            <hr className="hr" />
            <KV label="Borgsom (indicatie, 3 mnd huur)" value={fmtEUR(t.rentNet * 3)} />
            <KV label="Servicekosten" value="Geen — alles inbegrepen" />
            <KV label="Bestemming" value={bestemming} />
          </div>
        </Card>
      </div>

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

function ContractEditModal({ tenant, onClose, onSaved }) {
  const { Modal } = window.UI;
  const [f, setF] = React.useState({
    startDate: tenant.startDate, endDate: tenant.endDate,
    noticeMonths: tenant.noticeMonths, rentNet: tenant.rentNet,
    vatApplicable: tenant.vatApplicable, indexMonthIdx: tenant.indexMonthIdx,
    status: tenant.status || 'actief',
  });
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState('');
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));

  const opslaan = async () => {
    setBusy(true); setError('');
    try {
      await window.API.wijzigContract(tenant.contractId, {
        startDate: f.startDate, endDate: f.endDate,
        noticeMonths: Number(f.noticeMonths), rentNet: Number(f.rentNet),
        vatApplicable: f.vatApplicable, indexMonthIdx: Number(f.indexMonthIdx),
        status: f.status,
      });
      await onSaved();
    } catch (e) { setError(e.message); setBusy(false); }
  };

  return (
    <Modal title="Contract bewerken" sub={tenant.name} onClose={onClose}
           footer={<>
             <button className="btn" onClick={onClose} disabled={busy}>Annuleren</button>
             <button className="btn btn-accent" disabled={busy} onClick={opslaan}
                     style={{ opacity: busy ? 0.4 : 1 }}>
               <Icons.Check />{busy ? 'Bezig…' : 'Opslaan'}
             </button>
           </>}>
      <div className="stack">
        {error && <div className="banner banner-warning" style={{ fontSize: 12.5 }}>{error}</div>}
        <div style={{ fontSize: 12.5, color: 'var(--muted)' }}>
          Pas hier de huurprijs aan bij een jaarlijkse indexering, of wijzig de looptijd.
        </div>
        <div className="form-grid">
          <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">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">Opzegtermijn (maanden)</label>
            <input className="input" type="number" value={f.noticeMonths} onChange={e => set('noticeMonths', 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">Status</label>
            <select className="select" value={f.status} onChange={e => set('status', e.target.value)}>
              <option value="actief">Actief</option>
              <option value="beeindigd">Beëindigd</option>
            </select>
          </div>
        </div>
      </div>
    </Modal>
  );
}

/* ============================================================
   ONDERHOUD — LIJST
   ============================================================ */
function MaintenanceList({ navigate, reload }) {
  const { Card, Tabs, Unit, MaintenanceStatus } = window.UI;
  const { MAINTENANCE, fmtEUR, fmtEURnoCents, fmtDateShort } = window.SW_DATA;
  const [filter, setFilter] = React.useState('all');
  const [newOpen, setNewOpen] = React.useState(false);

  const counts = {
    open: MAINTENANCE.filter(m => m.status === 'open').length,
    in_behandeling: MAINTENANCE.filter(m => m.status === 'in_behandeling').length,
    afgerond: MAINTENANCE.filter(m => m.status === 'afgerond').length,
    all: MAINTENANCE.length,
  };
  let rows = MAINTENANCE;
  if (filter !== 'all') rows = rows.filter(m => m.status === filter);

  return (
    <div className="stack-lg">
      <div className="row-between">
        <Tabs value={filter} onChange={setFilter}
              options={[
                { value: 'open',           label: 'Open',           count: counts.open },
                { value: 'in_behandeling', label: 'In behandeling', count: counts.in_behandeling },
                { value: 'afgerond',       label: 'Afgerond',       count: counts.afgerond },
                { value: 'all',            label: 'Alles',          count: counts.all },
              ]} />
        <button className="btn btn-primary" onClick={() => setNewOpen(true)}><Icons.Plus />Nieuwe melding</button>
      </div>

      <Card flush>
        <table className="table">
          <thead>
            <tr>
              <th style={{ width: 120 }}>ID</th>
              <th>Onderwerp</th>
              <th>Unit</th>
              <th>Gemeld</th>
              <th>Datum</th>
              <th>Status</th>
              <th className="right">Kosten</th>
            </tr>
          </thead>
          <tbody>
            {rows.map(m => (
              <tr key={m.id} className="clickable" onClick={() => navigate('maintenance/' + m.id)}>
                <td className="mono" style={{ color: 'var(--muted)' }}>{m.id}</td>
                <td style={{ fontWeight: 500 }}>{m.title}</td>
                <td>{m.unit === 'algemeen' ? <span className="muted">algemeen</span> : <Unit>{m.unit}</Unit>}</td>
                <td className="muted">{m.reportedBy}</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">{m.estimate ? `(offerte ${fmtEURnoCents(m.estimate)})` : '—'}</span>}</td>
              </tr>
            ))}
            {rows.length === 0 && (
              <tr><td colSpan={7} style={{ textAlign: 'center', padding: 40, color: 'var(--muted)' }}>Geen meldingen in deze weergave.</td></tr>
            )}
          </tbody>
        </table>
      </Card>

      {newOpen && <NewMaintenanceModal onClose={() => setNewOpen(false)}
        onCreated={async () => { await reload(); setNewOpen(false); }} />}
    </div>
  );
}

function NewMaintenanceModal({ onClose, onCreated }) {
  const { Modal } = window.UI;
  const { TENANTS } = window.SW_DATA;
  const [title, setTitle] = React.useState('');
  const [unit, setUnit] = React.useState('algemeen');
  const [datum, setDatum] = React.useState(new Date().toISOString().slice(0, 10));
  const [desc, setDesc] = React.useState('');
  const [estimate, setEstimate] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState('');

  const valid = title.trim().length > 3;

  const aanmaken = async () => {
    setBusy(true); setError('');
    try {
      await window.API.nieuwOnderhoud({
        title: title.trim(), unit, datum, description: desc,
        estimate: Number(estimate) || 0,
      });
      await onCreated();
    } catch (e) { setError(e.message); setBusy(false); }
  };

  return (
    <Modal title="Nieuwe onderhoudsmelding"
           sub="Een melding krijgt automatisch een eigen ID en wordt gekoppeld aan de unit."
           onClose={onClose} size="lg"
           footer={<>
             <button className="btn" onClick={onClose} disabled={busy}>Annuleren</button>
             <button className="btn btn-accent" disabled={!valid || busy}
               onClick={aanmaken}
               style={{ opacity: (valid && !busy) ? 1 : 0.4 }}>
               <Icons.Plus />{busy ? 'Bezig…' : 'Melding aanmaken'}
             </button>
           </>}>
      <div className="stack">
        {error && <div className="banner banner-warning" style={{ fontSize: 12.5 }}>{error}</div>}
        <div>
          <label className="field-label">Onderwerp</label>
          <input className="input" value={title} onChange={e => setTitle(e.target.value)} placeholder="Bijv. Lekkage dakkoepel boven unit 1b" autoFocus />
        </div>
        <div className="form-grid">
          <div>
            <label className="field-label">Unit</label>
            <select className="select" value={unit} onChange={e => setUnit(e.target.value)}>
              <option value="algemeen">Algemeen / pand</option>
              {TENANTS.map(t => <option key={t.id} value={t.unit}>{t.unit} — {t.name}</option>)}
            </select>
          </div>
          <div>
            <label className="field-label">Datum melding</label>
            <input className="input" type="date" value={datum} onChange={e => setDatum(e.target.value)} />
          </div>
          <div className="full">
            <label className="field-label">Offerte / raming (optioneel)</label>
            <input className="input" type="number" step="0.01" value={estimate}
                   onChange={e => setEstimate(e.target.value)} placeholder="0,00" />
          </div>
        </div>
        <div>
          <label className="field-label">Omschrijving</label>
          <textarea className="textarea" value={desc} onChange={e => setDesc(e.target.value)}
                    placeholder="Beschrijf wat er aan de hand is, eventuele eerdere observaties, en wat de huurder gemeld heeft." />
        </div>
      </div>
    </Modal>
  );
}

/* ============================================================
   ONDERHOUD — DETAIL
   ============================================================ */
function MaintenanceDetail({ id, navigate, reload }) {
  const { Card, Breadcrumb, Unit, MaintenanceStatus } = window.UI;
  const { MAINTENANCE, fmtEUR, fmtDate, fmtDateShort } = window.SW_DATA;
  const [editOpen, setEditOpen] = React.useState(false);
  const [uploadOpen, setUploadOpen] = React.useState(false);

  const m = MAINTENANCE.find(x => x.id === id);
  if (!m) return <div>Melding niet gevonden</div>;

  const docs = m.documents || [];

  const markeerAfgerond = async () => {
    if (!confirm('Deze melding markeren als afgerond?')) return;
    try {
      await window.API.wijzigOnderhoud(m.id, { status: 'afgerond' });
      await reload();
    } catch (e) { alert('Mislukt: ' + e.message); }
  };

  return (
    <div className="stack-lg">
      <Breadcrumb navigate={navigate} items={[
        { label: 'Onderhoud', to: 'maintenance' },
        { label: m.id },
      ]} />
      <div className="row-between">
        <div>
          <div className="row" style={{ gap: 12 }}>
            <div className="h1">{m.title}</div>
            <MaintenanceStatus status={m.status} />
          </div>
          <div className="muted" style={{ marginTop: 6 }}>
            <span className="mono">{m.id}</span> · {m.unit === 'algemeen' ? 'Pand algemeen' : <>Unit <Unit>{m.unit}</Unit></>} · gemeld {fmtDate(m.date)}
          </div>
        </div>
        <div className="row">
          <button className="btn" onClick={() => setEditOpen(true)}><Icons.Edit />Bewerken</button>
          {m.status !== 'afgerond' && <button className="btn btn-accent" onClick={markeerAfgerond}><Icons.Check />Markeer afgerond</button>}
        </div>
      </div>

      <div className="split-2-3">
        <div className="stack">
          <Card title="Omschrijving">
            <div style={{ fontSize: 13.5, lineHeight: 1.7 }}>{m.description || <span className="muted">Geen omschrijving.</span>}</div>
          </Card>

          <Card title="Offertes & documenten" flush
                action={<button className="btn btn-sm" onClick={() => setUploadOpen(true)}><Icons.Upload />Toevoegen</button>}>
            <table className="table">
              <tbody>
                {docs.map(d => (
                  <tr key={d.id} className={d.hasFile ? 'clickable' : ''}
                      onClick={() => d.hasFile && window.open(window.API.documentUrl(d.id), '_blank')}>
                    <td><div className="row" style={{ gap: 10 }}><Icons.File size={14} />{d.name}</div></td>
                    <td className="muted">{d.category}</td>
                    <td className="muted">{fmtDateShort(d.date)}</td>
                    <td className="right">{d.hasFile
                      ? <button className="btn btn-sm btn-ghost btn-icon"><Icons.Download /></button>
                      : <span className="muted" style={{ fontSize: 11.5 }}>—</span>}</td>
                  </tr>
                ))}
                {docs.length === 0 && (
                  <tr><td colSpan={4} style={{ textAlign: 'center', padding: 28, color: 'var(--muted)' }}>
                    Nog geen offertes of documenten gekoppeld.
                  </td></tr>
                )}
              </tbody>
            </table>
          </Card>
        </div>

        <div className="stack">
          <Card title="Kosten">
            <div className="stack-sm">
              <KV label="Offerte / raming" value={m.estimate ? fmtEUR(m.estimate) : <span className="muted">—</span>} />
              <KV label="Werkelijke kosten" value={m.cost ? <strong>{fmtEUR(m.cost)}</strong> : <span className="muted">Nog niet bekend</span>} />
              {m.estimate && m.cost ? (
                <KV label="Verschil" value={
                  <span style={{ color: m.cost > m.estimate ? 'var(--danger)' : 'var(--success)' }}>
                    {m.cost > m.estimate ? '+' : '−'} {fmtEUR(Math.abs(m.cost - m.estimate))}
                  </span>
                } />
              ) : null}
            </div>
          </Card>

          <Card title="Statusverloop">
            <div className="timeline">
              {m.history.map((h, i) => (
                <div key={i} className={'timeline-item ' + (i < m.history.length - 1 || m.status === 'afgerond' ? 'done' : 'now')}>
                  <div className="timeline-dot"></div>
                  <div>
                    <div className="timeline-title">{h.label}</div>
                    <div className="timeline-meta">{fmtDateShort(h.date)}{h.detail ? ' · ' + h.detail : ''}</div>
                  </div>
                </div>
              ))}
            </div>
          </Card>
        </div>
      </div>

      {editOpen && <MaintenanceEditModal melding={m} onClose={() => setEditOpen(false)}
        onSaved={async () => { await reload(); setEditOpen(false); }} />}
      {uploadOpen && <window.Screens.DocumentUploadModal onderhoudId={m.id}
        onClose={() => setUploadOpen(false)}
        onSaved={async () => { await reload(); setUploadOpen(false); }} />}
    </div>
  );
}

function MaintenanceEditModal({ melding, onClose, onSaved }) {
  const { Modal } = window.UI;
  const [f, setF] = React.useState({
    title: melding.title, description: melding.description,
    status: melding.status, estimate: melding.estimate, cost: melding.cost,
  });
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState('');
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));

  const opslaan = async () => {
    setBusy(true); setError('');
    try {
      await window.API.wijzigOnderhoud(melding.id, {
        title: f.title, description: f.description, status: f.status,
        estimate: Number(f.estimate) || 0, cost: Number(f.cost) || 0,
      });
      await onSaved();
    } catch (e) { setError(e.message); setBusy(false); }
  };

  return (
    <Modal title="Melding bewerken" sub={melding.id} onClose={onClose} size="lg"
           footer={<>
             <button className="btn" onClick={onClose} disabled={busy}>Annuleren</button>
             <button className="btn btn-accent" disabled={busy} onClick={opslaan}
                     style={{ opacity: busy ? 0.4 : 1 }}>
               <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">Onderwerp</label>
          <input className="input" value={f.title} onChange={e => set('title', e.target.value)} />
        </div>
        <div>
          <label className="field-label">Omschrijving</label>
          <textarea className="textarea" value={f.description} onChange={e => set('description', e.target.value)} />
        </div>
        <div className="form-grid">
          <div>
            <label className="field-label">Status</label>
            <select className="select" value={f.status} onChange={e => set('status', e.target.value)}>
              <option value="open">Open</option>
              <option value="in_behandeling">In behandeling</option>
              <option value="afgerond">Afgerond</option>
            </select>
          </div>
          <div></div>
          <div>
            <label className="field-label">Offerte / raming</label>
            <input className="input" type="number" step="0.01" value={f.estimate} onChange={e => set('estimate', e.target.value)} />
          </div>
          <div>
            <label className="field-label">Werkelijke kosten</label>
            <input className="input" type="number" step="0.01" value={f.cost} onChange={e => set('cost', e.target.value)} />
          </div>
        </div>
      </div>
    </Modal>
  );
}

/* ============================================================
   EXPLOITATIE
   ============================================================ */
function Operations() {
  const { Card } = window.UI;
  const { OPERATIONS, fmtEURnoCents } = window.SW_DATA;
  const years = OPERATIONS.years;
  if (!years.length) return <div className="muted">Nog geen exploitatiegegevens.</div>;

  const current = years[years.length - 1];
  const prev = years[years.length - 2] || current;

  const maxBar = Math.max(...years.map(y => Math.max(y.income, y.totalCosts)), 1);

  const incomeDelta = prev.income ? ((current.income / prev.income) - 1) * 100 : 0;
  const costDelta = prev.totalCosts ? ((current.totalCosts / prev.totalCosts) - 1) * 100 : 0;
  const fmtPct = (v) => `${v >= 0 ? '+' : '−'}${Math.abs(v).toFixed(1)}%`;

  const COLOR_CYCLE = ['blue', 'yellow', 'green', 'purple', 'pink'];
  const colorFor = (i) => COLOR_CYCLE[i % COLOR_CYCLE.length];

  // Zonder vastgelegde lasten is 'resultaat' gelijk aan de omzet, en dan
  // zeggen marge en cashflow niets. Dat moet op het scherm staan.
  const geenLasten = !years.some(y => y.totalCosts > 0);

  return (
    <div className="stack-lg">
      {geenLasten && (
        <div className="banner banner-warning">
          <span className="banner-icoon"><Icons.Alert size={18} stroke={2} /></span>
          <div style={{ flex: 1, minWidth: 0 }}>
            <strong>Er zijn nog geen lasten vastgelegd</strong>
            <div className="muted">
              Hypotheek, gemeentelijke heffingen, verzekering en onderhoud staan nog nergens in.
              Zolang dat zo is, is het resultaat hieronder gelijk aan de omzet en zeggen de marge
              en de cashflow niets.
            </div>
          </div>
        </div>
      )}
      <div className="stat-grid">
        <window.UI.Stat
          label={`Inkomsten ${current.y}${current.projected ? ' (proj.)' : ''}`}
          value={fmtEURnoCents(current.income)}
          color="green"
          delta={{ value: fmtPct(incomeDelta), sign: incomeDelta >= 0 ? 'pos' : 'neg' }}
          foot={<span className="muted">t.o.v. {prev.y}</span>}
          pct={100}
        />
        <window.UI.Stat
          label={`Lasten ${current.y}${current.projected ? ' (proj.)' : ''}`}
          value={fmtEURnoCents(current.totalCosts)}
          color="blue"
          delta={{ value: fmtPct(costDelta), sign: costDelta <= 0 ? 'pos' : 'neg' }}
          foot={<span className="muted">t.o.v. {prev.y}</span>}
          pct={current.income ? Math.round((current.totalCosts / current.income) * 100) : 0}
        />
        <window.UI.Stat
          label="Resultaat"
          value={fmtEURnoCents(current.result)}
          color="yellow"
          delta={geenLasten
            ? { value: 'geen lasten bekend', sign: 'neutral' }
            : { value: `marge ${current.income ? ((current.result / current.income) * 100).toFixed(0) : 0}%`, sign: current.result >= 0 ? 'pos' : 'neg' }}
          foot={<span className="muted">inkomsten − lasten</span>}
          pct={current.income ? Math.round((current.result / current.income) * 100) : 0}
        />
        <window.UI.Stat
          label="Cashflow per maand (gem.)"
          value={fmtEURnoCents(current.result / 12)}
          color="purple"
          delta={{ value: geenLasten ? 'vóór lasten' : 'na hypotheek', sign: 'neutral' }}
          foot={<span className="muted">12-maands gemiddelde</span>}
        />
      </div>

      <Card title="Inkomsten vs lasten per jaar"
            action={
              <div className="legend">
                <span className="legend-item"><span className="legend-swatch"></span>Inkomsten</span>
                <span className="legend-item"><span className="legend-swatch striped"></span>Lasten</span>
              </div>
            }>
        <div className="chart" style={{ '--cols': years.length }}>
          <div className="chart-gridlines">
            <div className="line" style={{ top: '0%' }}>{fmtEURnoCents(maxBar)}</div>
            <div className="line" style={{ top: '25%' }}>{fmtEURnoCents(maxBar * 0.75)}</div>
            <div className="line" style={{ top: '50%' }}>{fmtEURnoCents(maxBar * 0.5)}</div>
            <div className="line" style={{ top: '75%' }}>{fmtEURnoCents(maxBar * 0.25)}</div>
          </div>
          {years.map((y, i) => (
            <div className={'chart-col' + (y === current ? ' current' : '')}
                 data-c={colorFor(i)} key={y.y}>
              <div className="chart-bars">
                <div className={'bar income' + (y === current ? ' current' : '')}
                     style={{ height: `${(y.income / maxBar) * 100}%` }}
                     title={`Inkomsten ${y.y}: ${fmtEURnoCents(y.income)}`}>
                </div>
                <div className={'bar costs' + (y === current ? ' current' : '')}
                     style={{ height: `${(y.totalCosts / maxBar) * 100}%` }}
                     title={`Lasten ${y.y}: ${fmtEURnoCents(y.totalCosts)}`}>
                </div>
              </div>
              <div className="chart-label">{y.y}{y.projected ? '*' : ''}</div>
            </div>
          ))}
        </div>
        {current.projected && (
          <div className="muted" style={{ fontSize: 11.5, marginTop: 14 }}>
            * {current.y} is een projectie op basis van de facturen tot nu toe.
          </div>
        )}
      </Card>

      <Card title="Jaarvergelijking" flush>
        <table className="table">
          <thead>
            <tr>
              <th>Jaar</th>
              <th className="right">Inkomsten</th>
              <th className="right">Hypotheek</th>
              <th className="right">Gem. heffingen</th>
              <th className="right">Verzekering</th>
              <th className="right">Onderhoud</th>
              <th className="right">Overig</th>
              <th className="right">Totaal lasten</th>
              <th className="right">Resultaat</th>
            </tr>
          </thead>
          <tbody>
            {years.map(y => (
              <tr key={y.y} className={y === current ? 'row-strong' : ''}>
                <td>{y.y}{y.projected ? <span className="muted" style={{ fontSize: 11 }}> (proj.)</span> : ''}</td>
                <td className="amount">{fmtEURnoCents(y.income)}</td>
                <td className="amount muted">{fmtEURnoCents(y.costs.hypotheek)}</td>
                <td className="amount muted">{fmtEURnoCents(y.costs.ozb + y.costs.riool + y.costs.water)}</td>
                <td className="amount muted">{fmtEURnoCents(y.costs.verzekering)}</td>
                <td className="amount muted">{fmtEURnoCents(y.costs.onderhoud)}</td>
                <td className="amount muted">{fmtEURnoCents(y.costs.overig)}</td>
                <td className="amount">{fmtEURnoCents(y.totalCosts)}</td>
                <td className="amount" style={{ color: 'var(--accent)', fontWeight: 600 }}>
                  {fmtEURnoCents(y.result)}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </Card>
    </div>
  );
}

/* ============================================================
   INSTELLINGEN
   ============================================================ */
function FieldRow({ label, value, onChange, hint, type, disabled }) {
  return (
    <div>
      <label className="field-label">{label}</label>
      <input className="input" type={type || 'text'} value={value == null ? '' : value}
             onChange={onChange ? (e => onChange(e.target.value)) : undefined}
             disabled={disabled} />
      {hint && <div className="muted" style={{ fontSize: 11.5, marginTop: 6 }}>{hint}</div>}
    </div>
  );
}

function Settings({ reload }) {
  const { Card } = window.UI;
  const S = window.SW_DATA.SETTINGS;
  const P = window.SW_DATA.PROPERTY;

  const [f, setF] = React.useState({
    pandNaam: S.pandNaam, pandAdres: S.pandAdres,
    pandOppervlakte: S.pandOppervlakte, pandBouwjaar: S.pandBouwjaar || '',
    bedrijfsnaam: S.bedrijfsnaam, kvk: S.kvk, btwNummer: S.btwNummer, iban: S.iban,
    factuurAfzender: S.factuurAfzender, factuurCC: S.factuurCC,
    factuurVolgnummer: S.factuurVolgnummer, verzenddag: S.verzenddag,
    betalingstermijnDagen: S.betalingstermijnDagen, btwPercentage: S.btwPercentage,
    factuurVoetnoot: S.factuurVoetnoot,
  });
  const [busy, setBusy] = React.useState(false);
  const [bericht, setBericht] = React.useState('');
  const set = (k, v) => setF(s => ({ ...s, [k]: v }));

  const opslaan = async () => {
    setBusy(true); setBericht('');
    try {
      await window.API.bewaarInstellingen({
        pandNaam: f.pandNaam, pandAdres: f.pandAdres,
        pandOppervlakte: Number(f.pandOppervlakte) || 0,
        pandBouwjaar: f.pandBouwjaar === '' ? null : Number(f.pandBouwjaar) || null,
        bedrijfsnaam: f.bedrijfsnaam, kvk: f.kvk, btwNummer: f.btwNummer, iban: f.iban,
        factuurAfzender: f.factuurAfzender, factuurCC: f.factuurCC,
        factuurVolgnummer: Number(f.factuurVolgnummer) || 1,
        verzenddag: Number(f.verzenddag) || 20,
        betalingstermijnDagen: Number(f.betalingstermijnDagen) || 14,
        btwPercentage: Number(f.btwPercentage) || 21,
        factuurVoetnoot: f.factuurVoetnoot,
      });
      await reload();
      setBericht('Wijzigingen opgeslagen.');
    } catch (e) { setBericht('Fout: ' + e.message); }
    setBusy(false);
  };

  return (
    <div className="stack-lg">
      <Card title="Pand">
        <div className="form-grid">
          <FieldRow label="Pandnaam" value={f.pandNaam} onChange={v => set('pandNaam', v)} />
          <FieldRow label="Adres" value={f.pandAdres} onChange={v => set('pandAdres', v)} />
          <FieldRow label="Aantal units" value={P.units} disabled hint="Volgt automatisch uit de huurders." />
          <FieldRow label="Totale oppervlakte (m²)" type="number" value={f.pandOppervlakte} onChange={v => set('pandOppervlakte', v)} />
          <FieldRow label="Bouwjaar" type="number" value={f.pandBouwjaar || ''} onChange={v => set('pandBouwjaar', v)} />
        </div>
      </Card>

      <Card title="Bedrijfsgegevens">
        <div className="form-grid">
          <FieldRow label="Bedrijfsnaam" value={f.bedrijfsnaam} onChange={v => set('bedrijfsnaam', v)} />
          <FieldRow label="KvK-nummer" value={f.kvk} onChange={v => set('kvk', v)} />
          <FieldRow label="BTW-nummer" value={f.btwNummer} onChange={v => set('btwNummer', v)} />
          <FieldRow label="IBAN" value={f.iban} onChange={v => set('iban', v)} />
        </div>
      </Card>

      <Card title="Facturatie">
        <div className="form-grid">
          <FieldRow label="Afzenderadres" value={f.factuurAfzender} onChange={v => set('factuurAfzender', v)} />
          <FieldRow label="Kopie in bcc (administratie, boekhouder — meerdere adressen met komma)" value={f.factuurCC} onChange={v => set('factuurCC', v)} />
          <FieldRow label="Volgnummer eerstvolgende factuur" type="number" value={f.factuurVolgnummer}
                    onChange={v => set('factuurVolgnummer', v)}
                    hint={`Factuurnummer = jaartal + dit nummer. Eerstvolgende: ${new Date().getFullYear()}${String(f.factuurVolgnummer).padStart(4, '0')}.`} />
          <FieldRow label="Verzenddag van de maand" type="number" value={f.verzenddag} onChange={v => set('verzenddag', v)} />
          <FieldRow label="Betalingstermijn (dagen)" type="number" value={f.betalingstermijnDagen} onChange={v => set('betalingstermijnDagen', v)} />
          <FieldRow label="Standaard btw-percentage" type="number" value={f.btwPercentage} onChange={v => set('btwPercentage', v)} />
          <div className="full">
            <label className="field-label">Factuurvoetnoot</label>
            <textarea className="textarea" value={f.factuurVoetnoot}
                      onChange={e => set('factuurVoetnoot', e.target.value)} />
          </div>
        </div>
      </Card>

      <SecurityCard />

      <div className="row" style={{ justifyContent: 'flex-end' }}>
        {bericht && <span className="muted" style={{ fontSize: 12.5 }}>{bericht}</span>}
        <button className="btn btn-primary" disabled={busy} onClick={opslaan}>
          {busy ? 'Bezig…' : 'Wijzigingen opslaan'}
        </button>
      </div>
    </div>
  );
}

function SecurityCard() {
  const { Card } = window.UI;
  const [totpActief, setTotpActief] = React.useState(null);
  const [pw, setPw] = React.useState({ huidig: '', nieuw: '', herhaal: '' });
  const [pwBericht, setPwBericht] = React.useState('');
  const [twoFAModal, setTwoFAModal] = React.useState(null); // 'setup' | 'disable'

  React.useEffect(() => {
    window.API.me().then(r => setTotpActief(r.totpActief)).catch(() => {});
  }, []);

  const wijzigWachtwoord = async () => {
    setPwBericht('');
    if (pw.nieuw.length < 8) { setPwBericht('Nieuw wachtwoord moet minstens 8 tekens zijn.'); return; }
    if (pw.nieuw !== pw.herhaal) { setPwBericht('De wachtwoorden komen niet overeen.'); return; }
    try {
      await window.API.wijzigWachtwoord(pw.huidig, pw.nieuw);
      setPw({ huidig: '', nieuw: '', herhaal: '' });
      setPwBericht('Wachtwoord gewijzigd.');
    } catch (e) { setPwBericht('Fout: ' + e.message); }
  };

  return (
    <Card title="Beveiliging">
      <div className="stack">
        <div>
          <div className="h3" style={{ marginBottom: 12 }}>Wachtwoord wijzigen</div>
          <div className="form-grid">
            <div>
              <label className="field-label">Huidig wachtwoord</label>
              <input className="input" type="password" value={pw.huidig}
                     onChange={e => setPw({ ...pw, huidig: e.target.value })} />
            </div>
            <div></div>
            <div>
              <label className="field-label">Nieuw wachtwoord</label>
              <input className="input" type="password" value={pw.nieuw}
                     onChange={e => setPw({ ...pw, nieuw: e.target.value })} />
            </div>
            <div>
              <label className="field-label">Herhaal nieuw wachtwoord</label>
              <input className="input" type="password" value={pw.herhaal}
                     onChange={e => setPw({ ...pw, herhaal: e.target.value })} />
            </div>
          </div>
          <div className="row" style={{ justifyContent: 'flex-end', marginTop: 12 }}>
            {pwBericht && <span className="muted" style={{ fontSize: 12.5 }}>{pwBericht}</span>}
            <button className="btn btn-sm" onClick={wijzigWachtwoord}
                    disabled={!pw.huidig || !pw.nieuw}>Wachtwoord wijzigen</button>
          </div>
        </div>
        <hr className="hr" />
        <div className="row-between">
          <div>
            <div className="h3">Tweefactor-authenticatie</div>
            <div className="muted" style={{ fontSize: 12.5, marginTop: 4 }}>
              {totpActief == null ? 'Status laden…'
                : totpActief ? 'Ingeschakeld — bij het inloggen is een code uit je authenticator-app nodig.'
                : 'Uitgeschakeld. Aanbevolen: er staat financiële data in het systeem.'}
            </div>
          </div>
          {totpActief != null && (
            totpActief
              ? <button className="btn btn-sm" onClick={() => setTwoFAModal('disable')}>Uitschakelen</button>
              : <button className="btn btn-sm btn-primary" onClick={() => setTwoFAModal('setup')}>Inschakelen</button>
          )}
        </div>
      </div>

      {twoFAModal === 'setup' && (
        <TwoFactorSetupModal onClose={() => setTwoFAModal(null)}
          onDone={() => { setTotpActief(true); setTwoFAModal(null); }} />
      )}
      {twoFAModal === 'disable' && (
        <TwoFactorDisableModal onClose={() => setTwoFAModal(null)}
          onDone={() => { setTotpActief(false); setTwoFAModal(null); }} />
      )}
    </Card>
  );
}

function TwoFactorSetupModal({ onClose, onDone }) {
  const { Modal } = window.UI;
  const [data, setData] = React.useState(null);
  const [code, setCode] = React.useState('');
  const [error, setError] = React.useState('');
  const [busy, setBusy] = React.useState(false);

  React.useEffect(() => {
    window.API.twoFASetup().then(setData).catch(e => setError(e.message));
  }, []);

  const activeer = async () => {
    setBusy(true); setError('');
    try {
      await window.API.twoFAActiveer(data.secret, code);
      onDone();
    } catch (e) { setError(e.message); setBusy(false); }
  };

  return (
    <Modal title="Tweefactor-authenticatie instellen"
           sub="Scan de QR-code met een authenticator-app (bijv. Google Authenticator of 1Password)."
           onClose={onClose}
           footer={<>
             <button className="btn" onClick={onClose} disabled={busy}>Annuleren</button>
             <button className="btn btn-accent" disabled={!data || code.length < 6 || busy}
                     onClick={activeer} style={{ opacity: (data && code.length >= 6 && !busy) ? 1 : 0.4 }}>
               <Icons.Check />Activeren
             </button>
           </>}>
      <div className="stack">
        {error && <div className="banner banner-warning" style={{ fontSize: 12.5 }}>{error}</div>}
        {!data && !error && <div className="muted">QR-code laden…</div>}
        {data && (
          <>
            <div style={{ textAlign: 'center' }}>
              <img src={data.qr} alt="QR-code" style={{ width: 180, height: 180, borderRadius: 12, border: '1px solid var(--border)' }} />
            </div>
            <div className="muted" style={{ fontSize: 12, textAlign: 'center' }}>
              Werkt scannen niet? Voer deze sleutel handmatig in:<br />
              <span className="mono" style={{ fontSize: 11.5 }}>{data.secret}</span>
            </div>
            <div>
              <label className="field-label">Verificatiecode uit de app</label>
              <input className="input" value={code} onChange={e => setCode(e.target.value)}
                     placeholder="6 cijfers" autoFocus />
            </div>
          </>
        )}
      </div>
    </Modal>
  );
}

function TwoFactorDisableModal({ onClose, onDone }) {
  const { Modal } = window.UI;
  const [wachtwoord, setWachtwoord] = React.useState('');
  const [error, setError] = React.useState('');
  const [busy, setBusy] = React.useState(false);

  const uitschakelen = async () => {
    setBusy(true); setError('');
    try {
      await window.API.twoFAUit(wachtwoord);
      onDone();
    } catch (e) { setError(e.message); setBusy(false); }
  };

  return (
    <Modal title="Tweefactor-authenticatie uitschakelen"
           sub="Bevestig met je wachtwoord." onClose={onClose}
           footer={<>
             <button className="btn" onClick={onClose} disabled={busy}>Annuleren</button>
             <button className="btn btn-accent" disabled={!wachtwoord || busy}
                     onClick={uitschakelen} style={{ opacity: (wachtwoord && !busy) ? 1 : 0.4 }}>
               Uitschakelen
             </button>
           </>}>
      <div className="stack">
        {error && <div className="banner banner-warning" style={{ fontSize: 12.5 }}>{error}</div>}
        <div>
          <label className="field-label">Wachtwoord</label>
          <input className="input" type="password" value={wachtwoord}
                 onChange={e => setWachtwoord(e.target.value)} autoFocus />
        </div>
      </div>
    </Modal>
  );
}

/* ============================================================
   INLOGGEN
   ============================================================ */
function Login({ onLogin }) {
  // Alleen een wachtwoord: er is één gebruiker (besluit Ralph, 6 okt 2026).
  const [pw, setPw] = React.useState('');
  const [code, setCode] = React.useState('');
  const [need2fa, setNeed2fa] = React.useState(false);
  const [error, setError] = React.useState('');
  const [busy, setBusy] = React.useState(false);

  const submit = async (e) => {
    e.preventDefault();
    setBusy(true); setError('');
    try {
      const r = await window.API.login(undefined, pw, need2fa ? code : undefined);
      if (r && r.need2fa) { setNeed2fa(true); setBusy(false); return; }
      await onLogin();
    } catch (err) {
      setError(err.message);
      if (/code/i.test(err.message)) setNeed2fa(true);
      setBusy(false);
    }
  };

  return (
    <div style={{ minHeight: '100vh', display: 'grid', placeItems: 'center', background: 'var(--bg)', padding: 20 }}>
      <div style={{ width: '100%', maxWidth: 380 }}>
        <div style={{ textAlign: 'center', marginBottom: 36 }}>
          <div style={{ fontSize: 22, fontWeight: 800, letterSpacing: '-0.01em' }}>
            SCHOENERWEG<span style={{ color: 'var(--accent)' }}>.</span>
          </div>
          <div className="muted" style={{ marginTop: 8, fontSize: 13 }}>Vastgoedbeheer · RD Vastgoed B.V.</div>
        </div>
        <div style={{
          background: 'var(--surface)',
          border: '1px solid var(--border)',
          borderRadius: 'var(--radius-lg)',
          padding: '28px 28px 24px',
        }}>
          <div className="h2" style={{ marginBottom: 4 }}>Inloggen</div>
          <div className="muted" style={{ fontSize: 12.5, marginBottom: 20 }}>Welkom terug.</div>
          <form onSubmit={submit} className="stack">
            {error && <div className="banner banner-warning" style={{ fontSize: 12.5 }}>{error}</div>}
            {/* Verborgen gebruikersnaam: alleen voor de wachtwoordmanager, die
                anders niet weet onder welke naam hij het wachtwoord bewaart. */}
            <input type="text" name="username" autoComplete="username" value="beheer"
                   readOnly hidden />
            <div>
              <label className="field-label">Wachtwoord</label>
              <input className="input" type="password" value={pw} autoFocus
                     autoComplete="current-password" name="password"
                     onChange={e => setPw(e.target.value)} placeholder="••••••••" disabled={need2fa} />
            </div>
            {need2fa && (
              <div>
                <label className="field-label">Verificatiecode (authenticator-app)</label>
                <input className="input" value={code} onChange={e => setCode(e.target.value)}
                       placeholder="6 cijfers" autoFocus />
              </div>
            )}
            <button className="btn btn-primary" style={{ width: '100%', justifyContent: 'center', height: 38 }}
                    type="submit" disabled={busy}>
              {busy ? 'Bezig…' : need2fa ? 'Verifiëren' : 'Inloggen'}
            </button>
            <div style={{ fontSize: 12, textAlign: 'right' }}>
              <a className="muted" style={{ cursor: 'pointer' }}
                 onClick={() => alert('Wachtwoord vergeten? Op de server: npm run wachtwoord-herstellen — dat zet het gelijk aan ADMIN_PASSWORD uit de .env.')}>
                Wachtwoord vergeten?
              </a>
            </div>
          </form>
        </div>
        <div className="muted" style={{ fontSize: 11.5, textAlign: 'center', marginTop: 24 }}>
          © {new Date().getFullYear()} RD Vastgoed B.V. · Schoenerweg 1, Zwolle
        </div>
      </div>
    </div>
  );
}

window.Screens = window.Screens || {};
Object.assign(window.Screens, {
  Contracts, ContractDetail,
  MaintenanceList, MaintenanceDetail,
  Operations, Settings, Login,
});

})();
