/* global React, PORTAL */
const { useState, useEffect } = React;

const VOK_VERSION = '2026-07-16';
const AV_VERSION  = '2026-07-16';

/* ─── VOK article data ───────────────────────────────────────────────────── */
const VOK_ARTICLES = [
  { title: 'Artikel 1 — Definities', body: 'Begrippen die in de AVG zijn gedefinieerd hebben in deze VOK dezelfde betekenis. "Betrokkene" is de natuurlijke persoon op wie de persoonsgegevens betrekking hebben. "Datalek" is een inbreuk als bedoeld in art. 4 lid 12 AVG.' },
  { title: 'Artikel 2 — Reikwijdte en doel', items: ['Lake-Project verwerkt persoonsgegevens uitsluitend ten behoeve van de overeengekomen diensten.','Lake-Project verwerkt de persoonsgegevens niet voor eigen doeleinden.','Lake-Project verwerkt primair in de EER. Voor sub-verwerkers buiten de EER zijn EU SCCs van kracht.'] },
  { title: 'Artikel 3 — Instructies', items: ['Lake-Project handelt uitsluitend op basis van gedocumenteerde instructies, tenzij een wettelijke verplichting anders vereist.','Lake-Project deelt Verwerkingsverantwoordelijke onverwijld mede als een instructie inbreuk maakt op de AVG.'] },
  { title: 'Artikel 4 — Vertrouwelijkheid', body: 'Lake-Project waarborgt dat personen die gemachtigd zijn persoonsgegevens te verwerken, zijn gehouden door een geheimhoudingsplicht. Toegang wordt beperkt tot het strikt noodzakelijke.' },
  { title: 'Artikel 5 — Beveiliging', body: 'Passende maatregelen: (i) versleuteling in rust en transport (TLS 1.2+); (ii) toegangscontrole op minimale rechten; (iii) verplichte MFA; (iv) patchbeheer binnen 30 dagen voor kritieke updates.' },
  { title: 'Artikel 6 — Sub-verwerkers', items: ['Cloudflare, Inc. (hosting/Amsterdam) en Resend/WorkOS, Inc. (e-mail) zijn toegestane sub-verwerkers. EU SCCs + DPA van kracht.','Minimaal 30 dagen vooraankondiging bij nieuwe sub-verwerkers.'] },
  { title: 'Artikel 7 — Rechten van betrokkenen', body: 'Lake-Project assisteert bij verzoeken van betrokkenen (art. 15–22 AVG) en stuurt rechtstreeks ingediende verzoeken onverwijld door.' },
  { title: 'Artikel 8 — Meldplicht datalekken', items: ['Melding uiterlijk 24 uur na ontdekking van een (vermoedelijk) datalek.','Volledige medewerking bij AP-melding (art. 33 AVG) en kennisgeving betrokkenen (art. 34 AVG).'] },
  { title: 'Artikel 9 — Audit', body: 'Lake-Project stelt alle informatie beschikbaar om naleving aan te tonen. Audits mogelijk met 30 dagen aankondiging.' },
  { title: 'Artikel 10 — Teruggave en verwijdering', body: 'Na beëindiging verwijdert of retourneert Lake-Project alle persoonsgegevens binnen 30 dagen.' },
  { title: 'Artikel 11 — Duur', body: 'Van kracht zolang Lake-Project persoonsgegevens verwerkt namens Verwerkingsverantwoordelijke in het kader van de dienstverlening.' },
  { title: 'Artikel 12 — Aansprakelijkheid', body: 'Aansprakelijkheidsregeling uit de onderliggende overeenkomst is van toepassing. Aansprakelijkheid jegens betrokkenen wordt niet beperkt.' },
  { title: 'Artikel 13 — Toepasselijk recht', body: 'Nederlands recht. Bevoegde rechter te Rotterdam.' },
];

const VOK_KEY_TERMS = [
  { art: 'Art. 2', title: 'Doel van verwerking', body: 'Uitsluitend voor de uitvoering van de overeengekomen diensten — nooit voor eigen doeleinden.' },
  { art: 'Art. 5', title: 'Beveiliging', body: 'Versleuteling, MFA verplicht, toegangscontrole op minimale rechten, patchbeheer binnen 30 dagen.' },
  { art: 'Art. 6', title: 'Sub-verwerkers', body: 'Alleen Cloudflare (hosting) en Resend (e-mail). EU SCCs van kracht. 30 dagen vooraankondiging bij nieuwe sub-verwerkers.' },
  { art: 'Art. 8', title: 'Datalekken binnen 24 uur', body: 'Melding aan u uiterlijk 24 uur na ontdekking + volledige medewerking bij AP-melding.' },
  { art: 'Art. 10', title: 'Verwijdering na beëindiging', body: 'Verwijdering of retournering binnen 30 dagen na afloop van de dienstverlening.' },
];

/* ─── AV article data ────────────────────────────────────────────────────── */
const AV_KEY_TERMS = [
  { art: 'Art. 2', title: 'Offerte geldig 30 dagen', body: 'Offertes zijn vrijblijvend en vervallen na 30 dagen, tenzij anders vermeld.' },
  { art: 'Art. 5', title: 'IE-overdracht na volledige betaling', body: 'Intellectuele eigendomsrechten gaan over na algehele voldoening. Open-sourcecomponenten worden niet overgedragen.' },
  { art: 'Art. 7', title: 'Betaling binnen 30 dagen', body: 'Facturen zijn verschuldigd binnen 30 dagen. Bij overschrijding geldt wettelijke handelsrente (art. 6:119a BW) van rechtswege.' },
  { art: 'Art. 8', title: 'Aansprakelijkheid beperkt', body: 'Beperkt tot het factuurbedrag van de laatste 3 maanden, max. EUR 10.000. Geen gevolgschade.' },
  { art: 'Art. 12', title: 'Nederlands recht, Rotterdam', body: 'Nederlands recht van toepassing. Bevoegde rechter: arrondissement Rotterdam.' },
];

const AV_ARTICLES = [
  { title: 'Artikel 1 — Toepasselijkheid', items: ['Deze AV zijn van toepassing op alle aanbiedingen, offertes en overeenkomsten van Lake-Project (KvK 29816688, Rotterdam).','Afwijkingen zijn slechts geldig indien uitdrukkelijk en schriftelijk overeengekomen. Inkoop- of andere voorwaarden van opdrachtgever worden van de hand gewezen.','Indien enige bepaling nietig is, blijven de overige onverminderd van kracht.'] },
  { title: 'Artikel 2 — Aanbod en aanvaarding', items: ['Offertes zijn vrijblijvend en geldig gedurende 30 dagen.','Overeenkomst komt tot stand op het moment van schriftelijke opdrachtbevestiging of aanvang van de uitvoering.','Mondelinge afspraken binden Lake-Project slechts na schriftelijke bevestiging.'] },
  { title: 'Artikel 3 — Uitvoering van de opdracht', items: ['Lake-Project voert de opdracht naar beste inzicht en vermogen uit (inspanningsverplichting, tenzij uitdrukkelijk anders overeengekomen).','Opdrachtgever draagt zorg voor tijdige aanlevering van benodigde informatie. Vertraging hieruit komt voor rekening en risico van opdrachtgever.','Lake-Project mag werkzaamheden door derden laten uitvoeren mits dit geen afbreuk doet aan kwaliteit en vertrouwelijkheid.'] },
  { title: 'Artikel 4 — Wijzigingen en meerwerk', items: ['Wijzigingen dienen schriftelijk te worden overeengekomen.','Aanvullende werkzaamheden buiten de opdracht worden als meerwerk in rekening gebracht.','Lake-Project informeert opdrachtgever zo spoedig mogelijk over financiële en planningsgevolgen.'] },
  { title: 'Artikel 5 — Intellectueel eigendom', items: ['IE-rechten berusten bij Lake-Project totdat alle betalingsverplichtingen zijn voldaan.','Na volledige betaling worden IE-rechten op specifiek voor opdrachtgever ontwikkelde werken overgedragen, voor zover de wet dit toelaat. Open-source- en standaardcomponenten worden niet overgedragen.','Lake-Project behoudt het recht werkzaamheden voor promotiedoeleinden te gebruiken, tenzij opdrachtgever schriftelijk bezwaar maakt.','Opdrachtgever vrijwaart Lake-Project voor IE-aanspraken op door hem aangeleverde materialen.'] },
  { title: 'Artikel 6 — Vertrouwelijkheid', items: ['Beide partijen behandelen vertrouwelijke informatie als strikt vertrouwelijk.','Uitzondering: rechtmatig openbare informatie of wettelijk verplichte verstrekking.','De vertrouwelijkheidsplicht geldt ook na beëindiging van de overeenkomst.'] },
  { title: 'Artikel 7 — Betaling', items: ['Facturen zijn verschuldigd binnen 30 dagen na factuurdatum.','Bij overschrijding is wettelijke handelsrente (art. 6:119a BW) verschuldigd van rechtswege.','Buitengerechtelijke incassokosten komen voor rekening van opdrachtgever.','Lake-Project mag werkzaamheden opschorten zolang een openstaand bedrag niet is voldaan.','Verrekening door opdrachtgever is niet toegestaan tenzij rechterlijk vastgesteld of schriftelijk erkend.'] },
  { title: 'Artikel 8 — Aansprakelijkheid', items: ['Lake-Project is slechts aansprakelijk voor directe schade door een toerekenbare tekortkoming.','Totale aansprakelijkheid beperkt tot het factuurbedrag van de laatste 3 maanden, max. EUR 10.000 per gebeurtenis.','Geen aansprakelijkheid voor indirecte schade, gevolgschade, gederfde winst, reputatieschade of bedrijfsstagnatie.','Beperkingen gelden niet bij opzet of bewuste roekeloosheid.','Opdrachtgever vrijwaart Lake-Project voor aanspraken van derden voor zover niet aan Lake-Project toe te rekenen.'] },
  { title: 'Artikel 9 — Overmacht', items: ['Lake-Project is niet gehouden tot nakoming bij overmacht (storingen bij toeleveranciers, ziekte, overheidsmaatregelen).','Bij overmacht langer dan 30 dagen mogen beide partijen de overeenkomst ontbinden zonder schadevergoeding. Lake-Project ontvangt betaling voor reeds verrichte werkzaamheden.'] },
  { title: 'Artikel 10 — Opzegging en ontbinding', items: ['Beide partijen kunnen de overeenkomst schriftelijk beëindigen met 30 dagen opzegtermijn.','Bij tussentijdse opzegging door opdrachtgever is Lake-Project gerechtigd vergoeding te vorderen voor verrichte werkzaamheden en gederfde omzet.','Lake-Project mag de overeenkomst met onmiddellijke ingang ontbinden bij faillissement of surseance van opdrachtgever.'] },
  { title: 'Artikel 11 — Klachten', items: ['Klachten dienen schriftelijk te worden gemeld binnen 14 dagen na constatering, uiterlijk 30 dagen na oplevering.','Klachten buiten deze termijn worden niet in behandeling genomen.','Gegrond bevonden klachten leiden tot herstel of creditering; de betalingsverplichting wordt niet opgeschort.'] },
  { title: 'Artikel 12 — Toepasselijk recht en geschillen', items: ['Op alle overeenkomsten is uitsluitend Nederlands recht van toepassing.','Geschillen worden voorgelegd aan de bevoegde rechter te Rotterdam.','Partijen streven ernaar geschillen eerst via overleg op te lossen.'] },
];

/* ─── helpers ────────────────────────────────────────────────────────────── */
function fmtDate(d) {
  if (!d) return '—';
  return new Date(d).toLocaleString('nl-NL', { day: '2-digit', month: 'long', year: 'numeric', hour: '2-digit', minute: '2-digit' });
}

/* ─── print: VOK ─────────────────────────────────────────────────────────── */
function printVOK(acc) {
  const w = window.open('', '_blank');
  const arts = VOK_ARTICLES.map(a => `<h2>${a.title}</h2>${a.body?`<p>${a.body}</p>`:''}${a.items?`<ol>${a.items.map(i=>`<li>${i}</li>`).join('')}</ol>`:''}`).join('');
  w.document.write(`<!DOCTYPE html><html lang="nl"><head><meta charset="utf-8"><title>VOK — ${acc.client_company_name} × Lake-Project</title>
<style>@page{size:A4;margin:20mm 22mm 18mm 22mm}*{box-sizing:border-box}body{font-family:system-ui,-apple-system,sans-serif;font-size:9pt;color:#1a1a1a;margin:0;-webkit-print-color-adjust:exact;print-color-adjust:exact}
.dh{border-bottom:2pt solid #0B1117;padding-bottom:12px;margin-bottom:18px;display:flex;justify-content:space-between;align-items:flex-end}h1{font-size:15pt;margin:0 0 3px;color:#0B1117}.sub{font-size:7pt;color:#555;font-family:monospace}.meta{text-align:right;font-size:7pt;font-family:monospace;color:#777;line-height:1.7}
.parties{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:16px}.party{background:#f8f9fc;border:1px solid #dde;border-radius:3px;padding:12px}.pr{font-size:6.5pt;letter-spacing:.12em;text-transform:uppercase;color:#777;font-family:monospace;margin-bottom:5px}.pn{font-size:10pt;font-weight:700;color:#0B1117;margin-bottom:3px}.pd{font-size:8pt;color:#444;line-height:1.65}
h2{font-size:8.5pt;font-weight:700;color:#0B1117;margin:12px 0 4px;border-bottom:1px solid #e8eaf0;padding-bottom:3px}p{font-size:8.5pt;color:#333;line-height:1.65;margin:0 0 6px}ol{padding-left:16px;margin:0 0 6px}li{font-size:8.5pt;color:#333;line-height:1.6;margin-bottom:3px}
.sl{font-size:6.5pt;letter-spacing:.18em;text-transform:uppercase;color:#2d7a6a;font-family:monospace;margin:16px 0 8px;border-top:1px solid #dde;padding-top:8px}
.ab{margin-top:20px;padding:14px;background:#f0faf7;border:1pt solid #2d7a6a;border-radius:3px;break-inside:avoid}.ab h3{font-size:9pt;color:#0B1117;margin:0 0 10px}.ag{display:grid;grid-template-columns:140px 1fr;gap:2px 10px}.al{color:#777;font-family:monospace;font-size:6.5pt;letter-spacing:.08em;text-transform:uppercase;padding:3px 0}.av{color:#222;padding:3px 0;font-size:8pt;font-weight:500}
.ln{margin-top:10px;padding-top:8px;border-top:1px solid #c0ddd6;font-size:7pt;color:#666;line-height:1.6}.ft{margin-top:14px;font-size:6.5pt;color:#aaa;font-family:monospace;text-align:center}
.pb{display:block;margin-bottom:14px;padding:8px 18px;background:#0B1117;color:#6FE3D1;border:1px solid #6FE3D1;border-radius:3px;cursor:pointer;font-size:10pt}@media print{.pb{display:none}}</style></head><body>
<button class="pb" onclick="window.print()">Print / Opslaan als PDF (A4)</button>
<div class="dh"><div><div class="sub">Lake Project · KvK 29816688 · Rotterdam · lake-project.com</div><h1>Verwerkersovereenkomst</h1><div class="sub">Art. 28 lid 3 AVG/GDPR</div></div>
<div class="meta"><div>VOK versie: ${acc.vok_version||VOK_VERSION}</div><div>Geaccepteerd: ${fmtDate(acc.accepted_at)}</div></div></div>
<div class="parties">
<div class="party"><div class="pr">Verwerkingsverantwoordelijke</div><div class="pn">${acc.client_company_name}</div>
<div class="pd">${acc.client_kvk?`KvK: ${acc.client_kvk}<br>`:''}${acc.client_address?`${acc.client_address}<br>`:''}Vertegenwoordigd door: <strong>${acc.authorized_rep_name}</strong>${acc.authorized_rep_function?` &mdash; ${acc.authorized_rep_function}`:''}</div></div>
<div class="party"><div class="pr">Verwerker</div><div class="pn">Lake Project (Lake-Project)</div><div class="pd">KvK: 29816688 · Rotterdam, NL<br>Vertegenwoordigd door: <strong>Alexander van der Plas</strong></div></div></div>
<div class="sl">Overwegingen</div><p>In het kader van de uitvoering van de overeengekomen diensten verwerkt Lake-Project persoonsgegevens namens Verwerkingsverantwoordelijke als bedoeld in art. 4 lid 8 AVG.</p>
<div class="sl">Artikelen</div>${arts}
<div class="sl">Bijlage B — Sub-verwerkers</div><p>Cloudflare, Inc. (VS/EU-West Amsterdam) — hosting, database, opslag · EU SCCs + DPA<br>Resend (WorkOS, Inc., VS) — transactionele e-mail · EU SCCs + DPA</p>
<div class="sl">Acceptatie</div>
<div class="ab"><h3>&#10003; Digitale acceptatie geregistreerd</h3><div class="ag">
<span class="al">Verwerkingsverantwoordelijke</span><span class="av">${acc.client_company_name}${acc.client_kvk?` &middot; KvK ${acc.client_kvk}`:''}</span>
<span class="al">Geaccepteerd door</span><span class="av">${acc.authorized_rep_name}${acc.authorized_rep_function?`, ${acc.authorized_rep_function}`:''}</span>
<span class="al">Tijdstip (UTC)</span><span class="av">${fmtDate(acc.accepted_at)}</span>
<span class="al">IP-adres</span><span class="av">${acc.ip_address||'—'}</span>
<span class="al">VOK versie</span><span class="av">${acc.vok_version||VOK_VERSION}</span>
<span class="al">Methode</span><span class="av">Elektronische acceptatie via geverifieerd klantportaal (eIDAS Art. 25)</span>
</div><div class="ln"><strong>Verwerker:</strong> Lake Project · KvK 29816688 · Rotterdam · Alexander van der Plas · hello@lake-project.com<br>Elektronische acceptatie via geverifieerd klantportaal vormt een rechtsgeldige overeenkomst onder Nederlands recht en eIDAS.</div></div>
<div class="ft">Lake-Project · VOK versie ${VOK_VERSION} · lake-project.com/trust/vok · ${new Date().toLocaleDateString('nl-NL',{day:'2-digit',month:'long',year:'numeric'})}</div>
</body></html>`);
  w.document.close();
}

/* ─── print: AV ──────────────────────────────────────────────────────────── */
function printAV(acc, companyName, contactName) {
  const w = window.open('', '_blank');
  const arts = AV_ARTICLES.map(a => `<h2>${a.title}</h2>${a.body?`<p>${a.body}</p>`:''}${a.items?`<ol>${a.items.map(i=>`<li>${i}</li>`).join('')}</ol>`:''}`).join('');
  w.document.write(`<!DOCTYPE html><html lang="nl"><head><meta charset="utf-8"><title>AV geaccepteerd — Lake-Project</title>
<style>@page{size:A4;margin:20mm 22mm 18mm 22mm}*{box-sizing:border-box}body{font-family:system-ui,-apple-system,sans-serif;font-size:9pt;color:#1a1a1a;margin:0;-webkit-print-color-adjust:exact;print-color-adjust:exact}
.dh{border-bottom:2pt solid #0B1117;padding-bottom:12px;margin-bottom:18px;display:flex;justify-content:space-between;align-items:flex-end}h1{font-size:15pt;margin:0 0 3px;color:#0B1117}.sub{font-size:7pt;color:#555;font-family:monospace}.meta{text-align:right;font-size:7pt;font-family:monospace;color:#777;line-height:1.7}
h2{font-size:8.5pt;font-weight:700;color:#0B1117;margin:12px 0 4px;border-bottom:1px solid #e8eaf0;padding-bottom:3px}p{font-size:8.5pt;color:#333;line-height:1.65;margin:0 0 6px}ol{padding-left:16px;margin:0 0 6px}li{font-size:8.5pt;color:#333;line-height:1.6;margin-bottom:3px}
.ab{margin-top:20px;padding:14px;background:#f0faf7;border:1pt solid #2d7a6a;border-radius:3px;break-inside:avoid}.ab h3{font-size:9pt;color:#0B1117;margin:0 0 10px}.ag{display:grid;grid-template-columns:140px 1fr;gap:2px 10px}.al{color:#777;font-family:monospace;font-size:6.5pt;letter-spacing:.08em;text-transform:uppercase;padding:3px 0}.av{color:#222;padding:3px 0;font-size:8pt;font-weight:500}
.ln{margin-top:10px;padding-top:8px;border-top:1px solid #c0ddd6;font-size:7pt;color:#666;line-height:1.6}.ft{margin-top:14px;font-size:6.5pt;color:#aaa;font-family:monospace;text-align:center}
.pb{display:block;margin-bottom:14px;padding:8px 18px;background:#0B1117;color:#6FE3D1;border:1px solid #6FE3D1;border-radius:3px;cursor:pointer;font-size:10pt}@media print{.pb{display:none}}</style></head><body>
<button class="pb" onclick="window.print()">Print / Opslaan als PDF (A4)</button>
<div class="dh"><div><div class="sub">Lake Project · KvK 29816688 · Rotterdam · lake-project.com</div><h1>Algemene Voorwaarden</h1><div class="sub">Versie ${acc.av_version||AV_VERSION} · Geaccepteerd exemplaar</div></div>
<div class="meta"><div>AV versie: ${acc.av_version||AV_VERSION}</div><div>Geaccepteerd: ${fmtDate(acc.accepted_at)}</div></div></div>
${arts}
<div class="ab"><h3>&#10003; Digitale acceptatie geregistreerd</h3><div class="ag">
<span class="al">Opdrachtgever</span><span class="av">${companyName||'—'}</span>
<span class="al">Geaccepteerd door</span><span class="av">${contactName||'—'}</span>
<span class="al">Tijdstip (UTC)</span><span class="av">${fmtDate(acc.accepted_at)}</span>
<span class="al">IP-adres</span><span class="av">${acc.ip_address||'—'}</span>
<span class="al">AV versie</span><span class="av">${acc.av_version||AV_VERSION}</span>
<span class="al">Methode</span><span class="av">Elektronische acceptatie via geverifieerd klantportaal (eIDAS Art. 25)</span>
</div><div class="ln"><strong>Lake Project (Lake-Project)</strong> · KvK 29816688 · Rotterdam · Alexander van der Plas · hello@lake-project.com<br>Elektronische acceptatie via geverifieerd klantportaal vormt een rechtsgeldige overeenkomst onder Nederlands recht en eIDAS.</div></div>
<div class="ft">Lake-Project · AV versie ${AV_VERSION} · lake-project.com/algemene-voorwaarden · ${new Date().toLocaleDateString('nl-NL',{day:'2-digit',month:'long',year:'numeric'})}</div>
</body></html>`);
  w.document.close();
}

/* ─── step indicator (VOK only) ──────────────────────────────────────────── */
function StepIndicator({ step }) {
  const steps = ['Your details', 'Review & accept'];
  return (
    <div style={{ display: 'flex', gap: 0, marginBottom: 28 }}>
      {steps.map((label, i) => {
        const n = i + 1;
        const active = n === step;
        const done = n < step;
        return (
          <div key={n} style={{ display: 'flex', alignItems: 'center', gap: 8, flex: 1 }}>
            <div style={{
              width: 24, height: 24, borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
              fontFamily: 'var(--font-mono)', fontSize: 11, fontWeight: 700,
              background: done ? 'var(--ok)' : active ? 'var(--signal)' : 'var(--night-elev-1)',
              color: (done || active) ? 'var(--abyss)' : 'var(--fg-subtle)',
              border: active || done ? 'none' : '1px solid var(--border)',
            }}>
              {done ? '✓' : n}
            </div>
            <span style={{ fontSize: 12, color: active ? 'var(--fg)' : 'var(--fg-subtle)', fontWeight: active ? 500 : 400 }}>{label}</span>
            {i < steps.length - 1 && <div style={{ flex: 1, height: 1, background: 'var(--border)', marginLeft: 8 }} />}
          </div>
        );
      })}
    </div>
  );
}

function ArticleViewer({ articles }) {
  return (
    <div style={{ maxHeight: 420, overflowY: 'auto', padding: '2px 0' }}>
      {articles.map(a => (
        <div key={a.title} style={{ marginBottom: 14 }}>
          <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--fg)', marginBottom: 5, paddingBottom: 4, borderBottom: '1px solid var(--border-hairline)' }}>{a.title}</div>
          {a.body && <p style={{ fontSize: 12, color: 'var(--fg-muted)', lineHeight: 1.65, margin: '0 0 4px' }}>{a.body}</p>}
          {a.items && (
            <ol style={{ margin: '0 0 0 16px', padding: 0 }}>
              {a.items.map((item, i) => (
                <li key={i} style={{ fontSize: 12, color: 'var(--fg-muted)', lineHeight: 1.65, marginBottom: 4 }}>{item}</li>
              ))}
            </ol>
          )}
        </div>
      ))}
    </div>
  );
}

function SectionHeader({ label }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 }}>
      <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--fg-subtle)', flexShrink: 0 }}>{label}</span>
      <div style={{ flex: 1, height: 1, background: 'var(--border)' }} />
    </div>
  );
}

function OnFileCard({ label, subtitle, rows, onPrint }) {
  return (
    <div className="card" style={{ maxWidth: 580, margin: '0 0 8px' }}>
      <div style={{ padding: '14px 20px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 12 }}>
        <div style={{ width: 32, height: 32, borderRadius: '50%', background: 'rgba(5,150,105,0.15)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--ok)" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12" /></svg>
        </div>
        <div>
          <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--fg)' }}>{label}</div>
          <div style={{ fontSize: 11, color: 'var(--fg-subtle)', fontFamily: 'var(--font-mono)' }}>{subtitle}</div>
        </div>
      </div>
      <div className="card-body">
        <div style={{ display: 'grid', gridTemplateColumns: '140px 1fr', gap: '4px 12px', fontSize: 13 }}>
          {rows.map(([lbl, val]) => (
            <React.Fragment key={lbl}>
              <span style={{ color: 'var(--fg-subtle)', fontFamily: 'var(--font-mono)', fontSize: 11, padding: '5px 0', borderBottom: '1px solid var(--border-hairline)' }}>{lbl}</span>
              <span style={{ color: 'var(--fg-muted)', padding: '5px 0', borderBottom: '1px solid var(--border-hairline)' }}>{val}</span>
            </React.Fragment>
          ))}
        </div>
      </div>
      <div style={{ padding: '12px 20px', borderTop: '1px solid var(--border)' }}>
        <button className="btn btn--ghost" onClick={onPrint}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" style={{ marginRight: 4 }}>
            <polyline points="6 9 6 2 18 2 18 9" /><path d="M6 18H4a2 2 0 01-2-2v-5a2 2 0 012-2h16a2 2 0 012 2v5a2 2 0 01-2 2h-2" /><rect x="6" y="14" width="12" height="8" />
          </svg>
          Print / Save as PDF
        </button>
      </div>
    </div>
  );
}

function Agreements() {
  /* VOK state */
  const [acceptance,   setAcceptance]  = useState(undefined);
  const [vokStep,      setVokStep]     = useState(1);
  const [vokAgreed,    setVokAgreed]   = useState(false);
  const [vokBusy,      setVokBusy]     = useState(false);
  const [vokError,     setVokError]    = useState('');
  const [vokShowFull,  setVokShowFull] = useState(false);
  const [form, setForm] = useState({ client_company_name: '', client_kvk: '', client_address: '', authorized_rep_name: '', authorized_rep_function: '' });

  /* AV state */
  const [avAcceptance, setAvAcceptance] = useState(undefined);
  const [avShowFull,   setAvShowFull]   = useState(false);
  const [avAgreed,     setAvAgreed]     = useState(false);
  const [avBusy,       setAvBusy]       = useState(false);
  const [avError,      setAvError]      = useState('');
  const [sessionInfo,  setSessionInfo]  = useState({ company: '', contact: '' });

  useEffect(() => {
    PORTAL.get('/agreements').then(setAcceptance).catch(() => setAcceptance(null));
    PORTAL.get('/av').then(setAvAcceptance).catch(() => setAvAcceptance(null));
    Promise.all([
      PORTAL.get('/company').catch(() => ({})),
      PORTAL.get('/profile').catch(() => ({})),
    ]).then(([co, ct]) => {
      setSessionInfo({ company: co?.name || '', contact: ct?.name || '' });
      setForm(prev => ({
        ...prev,
        client_company_name: co?.name || '',
        client_address: [co?.address_street, co?.address_postcode, co?.address_city].filter(Boolean).join(', '),
        authorized_rep_name: ct?.name || '',
      }));
    });
  }, []);

  const f = k => e => setForm(p => ({ ...p, [k]: e.target.value }));

  async function acceptVOK() {
    if (!vokAgreed) return;
    setVokBusy(true); setVokError('');
    try {
      const result = await PORTAL.post('/agreements', { ...form, vok_version: VOK_VERSION });
      setAcceptance(result);
    } catch (ex) {
      setVokError(ex?.error || 'Something went wrong. Please try again.');
    } finally { setVokBusy(false); }
  }

  async function acceptAV() {
    if (!avAgreed) return;
    setAvBusy(true); setAvError('');
    try {
      const result = await PORTAL.post('/av', { av_version: AV_VERSION });
      setAvAcceptance(result);
    } catch (ex) {
      setAvError(ex?.error || 'Something went wrong. Please try again.');
    } finally { setAvBusy(false); }
  }

  if (acceptance === undefined || avAcceptance === undefined) {
    return <div style={{ padding: 24, color: 'var(--fg-subtle)', fontSize: 13 }}>Loading…</div>;
  }

  return (
    <div>
      <h1 className="page-title">Legal documents</h1>
      <div className="page-subtitle">Active agreements between you and Lake-Project</div>

      {/* ── AV ───────────────────────────────────────────────────────────── */}
      <div style={{ marginTop: 24, marginBottom: 32 }}>
        <SectionHeader label="General terms & conditions" />

        {avAcceptance ? (
          <OnFileCard
            label="Terms on file"
            subtitle={`Accepted ${fmtDate(avAcceptance.accepted_at)}`}
            rows={[
              ['Company',     sessionInfo.company || '—'],
              ['Accepted by', sessionInfo.contact || '—'],
              ['AV version',  avAcceptance.av_version],
            ]}
            onPrint={() => printAV(avAcceptance, sessionInfo.company, sessionInfo.contact)}
          />
        ) : (
          <div className="card" style={{ maxWidth: 600 }}>
            <div className="card-head">
              <span className="card-title">Algemene Voorwaarden — Lake-Project</span>
              <a href="/algemene-voorwaarden" target="_blank" rel="noopener noreferrer"
                style={{ fontSize: 11, fontFamily: 'var(--font-mono)', color: 'var(--signal)' }}>
                View full AV ↗
              </a>
            </div>
            <div style={{ padding: '4px 20px 12px' }}>
              {AV_KEY_TERMS.map(t => (
                <div key={t.art} style={{ display: 'flex', gap: 14, padding: '9px 0', borderBottom: '1px solid var(--border-hairline)' }}>
                  <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--signal)', flexShrink: 0, paddingTop: 1, minWidth: 44 }}>{t.art}</span>
                  <div>
                    <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--fg)', marginBottom: 1 }}>{t.title}</div>
                    <div style={{ fontSize: 12, color: 'var(--fg-muted)', lineHeight: 1.6 }}>{t.body}</div>
                  </div>
                </div>
              ))}
            </div>
            <div onClick={() => setAvShowFull(p => !p)}
              style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '10px 20px', cursor: 'pointer', borderTop: '1px solid var(--border)', borderBottom: avShowFull ? '1px solid var(--border)' : 'none', userSelect: 'none' }}>
              <span style={{ fontSize: 12, color: 'var(--fg-subtle)' }}>Full terms text (12 articles)</span>
              <span style={{ fontSize: 11, color: 'var(--fg-subtle)' }}>{avShowFull ? '▾' : '▸'}</span>
            </div>
            {avShowFull && (
              <div style={{ padding: '16px 20px', borderBottom: '1px solid var(--border)' }}>
                <ArticleViewer articles={AV_ARTICLES} />
              </div>
            )}
            <div className="card-body">
              <label style={{ display: 'flex', alignItems: 'flex-start', gap: 12, cursor: 'pointer' }}>
                <input type="checkbox" checked={avAgreed} onChange={e => setAvAgreed(e.target.checked)} style={{ marginTop: 2, flexShrink: 0 }} />
                <span style={{ fontSize: 13, color: 'var(--fg-muted)', lineHeight: 1.65 }}>
                  I have read and agree to the Algemene Voorwaarden of Lake-Project, and I am authorised to accept these terms on behalf of{' '}
                  {sessionInfo.company ? <strong style={{ color: 'var(--fg)' }}>{sessionInfo.company}</strong> : 'my organisation'}.
                </span>
              </label>
              {avError && (
                <div style={{ marginTop: 10, padding: '8px 12px', background: 'rgba(220,38,38,0.08)', border: '1px solid rgba(220,38,38,0.3)', borderRadius: 3, fontSize: 12, color: 'var(--danger)' }}>
                  {avError}
                </div>
              )}
            </div>
            <div style={{ padding: '12px 20px', borderTop: '1px solid var(--border)', display: 'flex', justifyContent: 'flex-end' }}>
              <button className="btn btn--primary" disabled={!avAgreed || avBusy} onClick={acceptAV}>
                {avBusy ? 'Processing…' : 'Accept general terms'}
              </button>
            </div>
          </div>
        )}
      </div>

      {/* ── VOK ──────────────────────────────────────────────────────────── */}
      <div style={{ marginBottom: 24 }}>
        <SectionHeader label="Data processing agreement · Art. 28 AVG/GDPR" />

        {acceptance ? (
          <OnFileCard
            label="Agreement on file"
            subtitle={`Accepted ${fmtDate(acceptance.accepted_at)}`}
            rows={[
              ['Company',    acceptance.client_company_name],
              ['KvK',        acceptance.client_kvk || '—'],
              ['Signed by',  `${acceptance.authorized_rep_name}${acceptance.authorized_rep_function ? `, ${acceptance.authorized_rep_function}` : ''}`],
              ['VOK version',acceptance.vok_version],
            ]}
            onPrint={() => printVOK(acceptance)}
          />
        ) : (
          <div style={{ maxWidth: 600 }}>
            <div style={{ padding: '12px 16px', background: 'rgba(37,99,235,0.07)', border: '1px solid rgba(37,99,235,0.22)', borderRadius: 4, fontSize: 12, color: 'var(--fg-muted)', lineHeight: 1.65, marginBottom: 20 }}>
              <strong style={{ color: 'var(--fg)' }}>GDPR Art. 28</strong> requires a signed data processing agreement when we handle personal data on your behalf. Takes about 2 minutes.
            </div>
            <StepIndicator step={vokStep} />

            {vokStep === 1 && (
              <div className="card">
                <div className="card-head"><span className="card-title">Your details</span></div>
                <div className="card-body" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '0 16px' }}>
                  <div className="field" style={{ gridColumn: '1/-1' }}>
                    <label className="field-label">Company name *</label>
                    <input className="field-input" required value={form.client_company_name} onChange={f('client_company_name')} placeholder="Your legal entity name" />
                  </div>
                  <div className="field">
                    <label className="field-label">KvK number</label>
                    <input className="field-input" value={form.client_kvk} onChange={f('client_kvk')} placeholder="e.g. 12345678" />
                  </div>
                  <div className="field">
                    <label className="field-label">Authorized representative *</label>
                    <input className="field-input" required value={form.authorized_rep_name} onChange={f('authorized_rep_name')} placeholder="Full name" />
                  </div>
                  <div className="field" style={{ gridColumn: '1/-1' }}>
                    <label className="field-label">Address</label>
                    <input className="field-input" value={form.client_address} onChange={f('client_address')} placeholder="Street, postcode, city" />
                  </div>
                  <div className="field" style={{ gridColumn: '1/-1' }}>
                    <label className="field-label">Function / title</label>
                    <input className="field-input" value={form.authorized_rep_function} onChange={f('authorized_rep_function')} placeholder="e.g. Director, CEO" />
                  </div>
                </div>
                <div style={{ padding: '12px 20px', borderTop: '1px solid var(--border)', display: 'flex', justifyContent: 'flex-end' }}>
                  <button className="btn btn--primary" disabled={!form.client_company_name.trim() || !form.authorized_rep_name.trim()} onClick={() => setVokStep(2)}>
                    Continue to review →
                  </button>
                </div>
              </div>
            )}

            {vokStep === 2 && (
              <div>
                <div className="card" style={{ margin: '0 0 16px' }}>
                  <div className="card-head"><span className="card-title">Key terms</span></div>
                  <div style={{ padding: '4px 20px 12px' }}>
                    {VOK_KEY_TERMS.map(t => (
                      <div key={t.art} style={{ display: 'flex', gap: 14, padding: '9px 0', borderBottom: '1px solid var(--border-hairline)' }}>
                        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--signal)', flexShrink: 0, paddingTop: 1, minWidth: 44 }}>{t.art}</span>
                        <div>
                          <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--fg)', marginBottom: 1 }}>{t.title}</div>
                          <div style={{ fontSize: 12, color: 'var(--fg-muted)', lineHeight: 1.6 }}>{t.body}</div>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
                <div className="card" style={{ margin: '0 0 16px' }}>
                  <div onClick={() => setVokShowFull(p => !p)} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '12px 20px', cursor: 'pointer', userSelect: 'none', borderBottom: vokShowFull ? '1px solid var(--border)' : 'none' }}>
                    <span style={{ fontSize: 13, fontWeight: 500 }}>Full verwerkersovereenkomst (13 articles)</span>
                    <span style={{ fontSize: 11, color: 'var(--fg-subtle)' }}>{vokShowFull ? '▾' : '▸'}</span>
                  </div>
                  {vokShowFull && (
                    <div style={{ padding: '16px 20px' }}>
                      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginBottom: 16 }}>
                        {[
                          { role: 'Verwerkingsverantwoordelijke', name: form.client_company_name, detail: `${form.client_kvk?`KvK: ${form.client_kvk} · `:''}${form.client_address||''}\nVertegenwoordigd door: ${form.authorized_rep_name}${form.authorized_rep_function?` (${form.authorized_rep_function})`:''}` },
                          { role: 'Verwerker', name: 'Lake Project (Lake-Project)', detail: 'KvK: 29816688 · Rotterdam, NL\nVertegenwoordigd door: Alexander van der Plas' },
                        ].map(p => (
                          <div key={p.role} style={{ background: 'var(--abyss)', border: '1px solid var(--border)', borderRadius: 3, padding: 12 }}>
                            <div style={{ fontSize: 10, fontFamily: 'var(--font-mono)', letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--fg-subtle)', marginBottom: 4 }}>{p.role}</div>
                            <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--fg)', marginBottom: 4 }}>{p.name}</div>
                            <div style={{ fontSize: 11, color: 'var(--fg-muted)', lineHeight: 1.65, whiteSpace: 'pre-line' }}>{p.detail}</div>
                          </div>
                        ))}
                      </div>
                      <ArticleViewer articles={VOK_ARTICLES} />
                    </div>
                  )}
                </div>
                <div className="card" style={{ margin: '0 0 16px' }}>
                  <div className="card-body">
                    <label style={{ display: 'flex', alignItems: 'flex-start', gap: 12, cursor: 'pointer' }}>
                      <input type="checkbox" checked={vokAgreed} onChange={e => setVokAgreed(e.target.checked)} style={{ marginTop: 2, flexShrink: 0 }} />
                      <span style={{ fontSize: 13, color: 'var(--fg-muted)', lineHeight: 1.65 }}>
                        I have read and agree to this verwerkersovereenkomst on behalf of{' '}
                        <strong style={{ color: 'var(--fg)' }}>{form.client_company_name}</strong>, and I am authorised to enter into this agreement.
                      </span>
                    </label>
                    {vokError && (
                      <div style={{ marginTop: 10, padding: '8px 12px', background: 'rgba(220,38,38,0.08)', border: '1px solid rgba(220,38,38,0.3)', borderRadius: 3, fontSize: 12, color: 'var(--danger)' }}>
                        {vokError}
                      </div>
                    )}
                  </div>
                  <div style={{ padding: '12px 20px', borderTop: '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                    <button className="btn btn--ghost" onClick={() => setVokStep(1)}>← Back</button>
                    <button className="btn btn--primary" disabled={!vokAgreed || vokBusy} onClick={acceptVOK}>
                      {vokBusy ? 'Processing…' : 'Sign & accept agreement'}
                    </button>
                  </div>
                </div>
                <div style={{ fontSize: 11, color: 'var(--fg-faint)', fontFamily: 'var(--font-mono)', lineHeight: 1.6 }}>
                  Acceptance is recorded with timestamp and IP. Legally binding under Dutch law and eIDAS Art. 25.
                </div>
              </div>
            )}
          </div>
        )}
      </div>

      <div style={{ fontSize: 12, color: 'var(--fg-faint)', fontFamily: 'var(--font-mono)', lineHeight: 1.6, marginTop: 8 }}>
        Questions? <a href="mailto:hello@lake-project.com" style={{ color: 'var(--signal)' }}>hello@lake-project.com</a>
      </div>
    </div>
  );
}
window.Agreements = Agreements;
