/* global React, API, useApp */
const { useState, useEffect, useCallback } = React;

const SEVERITY       = { low: 'Low', medium: 'Medium', high: 'High', critical: 'Critical' };
const SEVERITY_COLOR = { low: '#059669', medium: '#d97706', high: '#dc2626', critical: '#7c3aed' };
const STATUS_LABEL   = { open: 'Open', investigating: 'Investigating', resolved: 'Resolved', closed: 'Closed' };
const STATUS_COLOR   = { open: '#dc2626', investigating: '#d97706', resolved: '#059669', closed: '#6b7280' };

const SOP = [
  {
    n: '01', title: 'Contain the breach',
    body: 'Determine what was exposed: which systems, which data, which time window. Limit further damage immediately — change credentials, revoke access, take the affected system offline if needed.',
  },
  {
    n: '02', title: 'Assess the risk',
    body: 'Is personal data involved? How many individuals? Is the data encrypted or pseudonymised? Estimate the risk of harm: identity theft, discrimination, financial loss, reputational damage.',
  },
  {
    n: '03', title: 'Notify the AP within 72 hours',
    body: 'If the breach involves personal data and poses a risk to individuals\' rights and freedoms, report to the Autoriteit Persoonsgegevens within 72 hours of discovery via meldloket.autoriteitpersoonsgegevens.nl. AP: 070 888 8500.',
  },
  {
    n: '04', title: 'Notify affected individuals (if high risk)',
    body: 'If the breach presents a high risk to individuals, inform them without undue delay. Describe what was exposed, potential consequences, and the measures taken.',
  },
  {
    n: '05', title: 'Document in this log',
    body: 'Record: discovery date/time, nature of the breach, data involved, number of individuals affected, measures taken, AP notification date, and whether individuals were informed. Required by AVG Art. 33(5) regardless of whether you notify the AP.',
  },
];

const EMPTY = {
  discovered_at: new Date().toISOString().slice(0, 16),
  description: '',
  data_affected: '',
  individuals_affected: '',
  severity: 'low',
  reported_to_ap: false,
  ap_reported_at: '',
  individuals_notified: false,
  resolution: '',
  status: 'open',
};

function printBreachLog(incidents) {
  const w = window.open('', '_blank');
  const date = new Date().toLocaleDateString('nl-NL', { day: '2-digit', month: 'long', year: 'numeric' });
  const rows = incidents.map(i => `
    <tr>
      <td style="white-space:nowrap;font-family:monospace;font-size:7.5pt">${(i.discovered_at||'').slice(0,16).replace('T',' ')}</td>
      <td>${i.description}</td>
      <td style="font-weight:600;color:${SEVERITY_COLOR[i.severity]||'#333'}">${SEVERITY[i.severity] || i.severity}</td>
      <td>${i.data_affected || '—'}</td>
      <td style="text-align:center">${i.individuals_affected != null ? i.individuals_affected : '—'}</td>
      <td>${i.reported_to_ap ? `Yes${i.ap_reported_at ? `<br><span style="font-size:7pt;color:#555">${i.ap_reported_at.slice(0,16).replace('T',' ')}</span>` : ''}` : 'No'}</td>
      <td>${i.individuals_notified ? 'Yes' : 'No'}</td>
      <td style="font-weight:600;color:${STATUS_COLOR[i.status]||'#333'}">${STATUS_LABEL[i.status] || i.status}</td>
    </tr>`).join('');

  w.document.write(`<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="utf-8">
<title>Data Breach Log — Lake-Project</title>
<style>
@page { size: A4 landscape; margin: 12mm 15mm; }
*, *::before, *::after { box-sizing: border-box; }
body { font-family: system-ui,-apple-system,sans-serif; font-size: 8.5pt; color: #1a1a1a; margin: 0; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.header { display: flex; justify-content: space-between; align-items: flex-end; border-bottom: 2pt solid #0B1117; padding-bottom: 10px; margin-bottom: 14px; }
h1 { font-size: 14pt; margin: 0 0 3px; color: #0B1117; }
.sub { font-size: 7.5pt; color: #555; font-family: monospace; }
.meta { text-align: right; font-size: 7.5pt; color: #777; font-family: monospace; line-height: 1.7; }
table { width: 100%; border-collapse: collapse; }
th { background: #0B1117; color: #6FE3D1; padding: 5px 8px; text-align: left; font-size: 7pt; letter-spacing: 0.05em; text-transform: uppercase; border-right: 1px solid #1a2535; }
th:last-child { border-right: none; }
td { padding: 7px 8px; border-bottom: 1px solid #e8eaf0; border-right: 1px solid #f0f0f4; vertical-align: top; line-height: 1.45; font-size: 8pt; }
td:last-child { border-right: none; }
tr:nth-child(even) td { background: #f8f9fc; }
.footer { margin-top: 12px; padding-top: 8px; border-top: 1px solid #dde; font-size: 7pt; color: #888; font-family: monospace; display: flex; justify-content: space-between; }
.print-btn { 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 { .print-btn { display: none; } }
</style>
</head>
<body>
<button class="print-btn" onclick="window.print()">Print / Save as PDF (A4 landscape)</button>
<div class="header">
  <div>
    <div class="sub">Lake Project · KvK 29816688 · Rotterdam, Netherlands · hello@lake-project.com</div>
    <h1>Data Breach Log — GDPR Art. 33/34 / AVG Meldplicht Datalekken</h1>
    <div class="sub">Data controller: Alexander van der Plas · lake-project.com</div>
  </div>
  <div class="meta">
    <div>Version: ${date}</div>
    <div>${incidents.length} incident${incidents.length === 1 ? '' : 's'}</div>
    <div>Internal document — confidential</div>
  </div>
</div>
<table>
<thead>
  <tr>
    <th>Discovered at</th>
    <th>Description</th>
    <th>Severity</th>
    <th>Data affected</th>
    <th># Individuals</th>
    <th>AP notified</th>
    <th>Individuals notified</th>
    <th>Status</th>
  </tr>
</thead>
<tbody>${rows || '<tr><td colspan="8" style="text-align:center;padding:20px;color:#aaa;font-style:italic">No incidents recorded</td></tr>'}</tbody>
</table>
<div class="footer">
  <span>Data Breach Log — Lake-Project · GDPR Art. 33/34</span>
  <span>Generated ${date} · Confidential</span>
</div>
</body></html>`);
  w.document.close();
}

function SopCard() {
  const [open, setOpen] = useState(false);
  return (
    <div className="card" style={{ margin: '0 0 16px' }}>
      <div
        onClick={() => setOpen(p => !p)}
        style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 20px', cursor: 'pointer', userSelect: 'none', borderBottom: open ? '1px solid var(--border)' : 'none' }}
      >
        <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--signal)', letterSpacing: '0.12em', textTransform: 'uppercase' }}>72-hr SOP</span>
        <span style={{ flex: 1, fontSize: 13, fontWeight: 500, color: 'var(--fg)' }}>Data breach response procedure</span>
        <span style={{ fontSize: 12, color: 'var(--fg-subtle)' }}>{open ? '▾' : '▸'}</span>
      </div>
      {open && (
        <div style={{ padding: '12px 20px 20px' }}>
          <p style={{ fontSize: 12, color: 'var(--fg-muted)', marginBottom: 16, lineHeight: 1.65 }}>
            When a personal data breach is discovered, follow these steps in order. Under GDPR Art. 33, you must notify the Autoriteit Persoonsgegevens <strong style={{ color: 'var(--danger)' }}>within 72 hours</strong> of discovery if the breach poses a risk to individuals' rights and freedoms.
          </p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {SOP.map(s => (
              <div key={s.n} style={{ display: 'flex', gap: 14, padding: '12px 14px', background: 'var(--night-elev-1)', borderRadius: 4, border: '1px solid var(--border)' }}>
                <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--signal)', flexShrink: 0, paddingTop: 1, minWidth: 20 }}>{s.n}</div>
                <div>
                  <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--fg)', marginBottom: 4 }}>{s.title}</div>
                  <div style={{ fontSize: 12, color: 'var(--fg-muted)', lineHeight: 1.6 }}>{s.body}</div>
                </div>
              </div>
            ))}
          </div>
          <div style={{ marginTop: 16, padding: '10px 14px', background: 'rgba(220,38,38,0.07)', border: '1px solid rgba(220,38,38,0.3)', borderRadius: 4, fontSize: 12, color: 'var(--fg-muted)', lineHeight: 1.6 }}>
            <strong style={{ color: 'var(--danger)' }}>AP reporting portal:</strong>{' '}
            <a href="https://meldloket.autoriteitpersoonsgegevens.nl" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--signal)' }}>meldloket.autoriteitpersoonsgegevens.nl</a>
            {' '}· Tel: 070 888 8500 · Mon–Fri 09:00–17:00
          </div>
        </div>
      )}
    </div>
  );
}

function IncidentModal({ incident, onSave, onClose }) {
  const [form, setForm] = useState(incident
    ? { ...incident, reported_to_ap: !!incident.reported_to_ap, individuals_notified: !!incident.individuals_notified }
    : { ...EMPTY });
  const [busy, setBusy] = useState(false);
  const { toast } = useApp();
  const f    = k => e => setForm(p => ({ ...p, [k]: e.target.value }));
  const fBool = k => e => setForm(p => ({ ...p, [k]: e.target.checked }));

  async function save(e) {
    e.preventDefault(); setBusy(true);
    try {
      incident?.id
        ? await API.put(`/breaches/${incident.id}`, form)
        : await API.post('/breaches', form);
      onSave();
    } catch (ex) { toast(ex?.error || 'Error saving', 'error'); }
    finally { setBusy(false); }
  }

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal" style={{ maxWidth: 580, width: '90%', maxHeight: '88vh', overflowY: 'auto' }}>
        <div className="modal-head">
          <span className="modal-title">{incident?.id ? 'Edit incident' : 'Log data breach incident'}</span>
          <button className="modal-close" onClick={onClose}>✕</button>
        </div>
        <form onSubmit={save}>
          <div className="modal-body" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '0 16px' }}>
            <div className="field">
              <label className="field-label">Discovered at *</label>
              <input className="field-input" type="datetime-local" required value={form.discovered_at} onChange={f('discovered_at')} />
            </div>
            <div className="field">
              <label className="field-label">Severity</label>
              <select className="field-select" value={form.severity} onChange={f('severity')}>
                {Object.entries(SEVERITY).map(([v, l]) => <option key={v} value={v}>{l}</option>)}
              </select>
            </div>
            <div className="field" style={{ gridColumn: '1/-1' }}>
              <label className="field-label">Description *</label>
              <textarea className="field-input" rows={3} required value={form.description} onChange={f('description')} placeholder="What happened? How was the breach discovered?" style={{ resize: 'vertical' }} />
            </div>
            <div className="field" style={{ gridColumn: '1/-1' }}>
              <label className="field-label">Personal data affected</label>
              <textarea className="field-input" rows={2} value={form.data_affected} onChange={f('data_affected')} placeholder="Which categories of personal data were involved?" style={{ resize: 'vertical' }} />
            </div>
            <div className="field">
              <label className="field-label">Individuals affected (approx.)</label>
              <input className="field-input" type="number" min="0" value={form.individuals_affected} onChange={f('individuals_affected')} placeholder="0" />
            </div>
            <div className="field">
              <label className="field-label">Status</label>
              <select className="field-select" value={form.status} onChange={f('status')}>
                {Object.entries(STATUS_LABEL).map(([v, l]) => <option key={v} value={v}>{l}</option>)}
              </select>
            </div>
            <div className="field" style={{ gridColumn: '1/-1' }}>
              <label style={{ display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer', fontSize: 13, color: 'var(--fg-muted)' }}>
                <input type="checkbox" checked={form.reported_to_ap} onChange={fBool('reported_to_ap')} />
                Reported to Autoriteit Persoonsgegevens (AP)
              </label>
            </div>
            {form.reported_to_ap && (
              <div className="field" style={{ gridColumn: '1/-1' }}>
                <label className="field-label">AP notification date/time</label>
                <input className="field-input" type="datetime-local" value={form.ap_reported_at || ''} onChange={f('ap_reported_at')} />
              </div>
            )}
            <div className="field" style={{ gridColumn: '1/-1' }}>
              <label style={{ display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer', fontSize: 13, color: 'var(--fg-muted)' }}>
                <input type="checkbox" checked={form.individuals_notified} onChange={fBool('individuals_notified')} />
                Affected individuals notified directly
              </label>
            </div>
            <div className="field" style={{ gridColumn: '1/-1' }}>
              <label className="field-label">Resolution &amp; follow-up</label>
              <textarea className="field-input" rows={3} value={form.resolution} onChange={f('resolution')} placeholder="What was done to contain the breach, remediate, and prevent recurrence?" style={{ resize: 'vertical' }} />
            </div>
          </div>
          <div style={{ padding: '12px 20px', borderTop: '1px solid var(--border)', display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
            <button type="button" className="btn btn--ghost" onClick={onClose}>Cancel</button>
            <button type="submit" className="btn btn--primary" disabled={busy}>{busy ? 'Saving…' : 'Save'}</button>
          </div>
        </form>
      </div>
    </div>
  );
}

function Breaches() {
  const [incidents, setIncidents] = useState([]);
  const [modal, setModal]         = useState(null);
  const [loading, setLoading]     = useState(true);
  const { toast } = useApp();

  const load = useCallback(() => {
    setLoading(true);
    API.get('/breaches')
      .then(r => { setIncidents(r || []); setLoading(false); })
      .catch(() => setLoading(false));
  }, []);

  useEffect(() => { load(); }, [load]);

  function handleSave() { setModal(null); load(); toast('Incident saved'); }

  async function handleDelete(i) {
    if (!confirm(`Delete this incident? This cannot be undone.`)) return;
    try {
      await API.del(`/breaches/${i.id}`);
      setIncidents(prev => prev.filter(x => x.id !== i.id));
      toast('Deleted');
    } catch (ex) { toast(ex?.error || 'Error', 'error'); }
  }

  const fmtDt = d => d ? d.slice(0, 16).replace('T', ' ') : '—';

  const open        = incidents.filter(i => i.status === 'open').length;
  const investigating = incidents.filter(i => i.status === 'investigating').length;

  return (
    <div className="page">
      <div className="page-header">
        <div>
          <h1 className="page-title">Breach log</h1>
          <div className="page-subtitle">GDPR Art. 33/34 — data breach incident register</div>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="btn btn--ghost" onClick={() => printBreachLog(incidents)}>
            <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 A4
          </button>
          <button className="btn btn--primary" onClick={() => setModal('add')}>+ Log incident</button>
        </div>
      </div>

      <SopCard />

      {(open > 0 || investigating > 0) && (
        <div style={{ display: 'flex', gap: 8, marginBottom: 16 }}>
          {open > 0 && <div style={{ padding: '8px 14px', background: 'rgba(220,38,38,0.08)', border: '1px solid rgba(220,38,38,0.3)', borderRadius: 4, fontSize: 12, color: '#dc2626' }}>{open} open incident{open > 1 ? 's' : ''}</div>}
          {investigating > 0 && <div style={{ padding: '8px 14px', background: 'rgba(217,119,6,0.08)', border: '1px solid rgba(217,119,6,0.3)', borderRadius: 4, fontSize: 12, color: '#d97706' }}>{investigating} under investigation</div>}
        </div>
      )}

      {loading ? (
        <div style={{ color: 'var(--fg-subtle)', padding: 24, fontSize: 13 }}>Loading…</div>
      ) : incidents.length === 0 ? (
        <div className="card">
          <div style={{ padding: 32, textAlign: 'center' }}>
            <div style={{ fontSize: 14, fontWeight: 500, color: 'var(--fg)', marginBottom: 8 }}>No incidents logged</div>
            <div style={{ fontSize: 12, color: 'var(--fg-muted)', marginBottom: 20, maxWidth: 440, margin: '0 auto 20px', lineHeight: 1.6 }}>
              GDPR Art. 33(5) requires maintaining a log of all data breach incidents — including those not reported to the AP.
            </div>
            <button className="btn btn--primary" onClick={() => setModal('add')}>Log first incident</button>
          </div>
        </div>
      ) : (
        <div className="card" style={{ margin: 0 }}>
          <div className="table-wrap">
            <table className="data-table">
              <thead>
                <tr>
                  <th>Discovered</th>
                  <th>Description</th>
                  <th>Severity</th>
                  <th>AP notified</th>
                  <th>Individuals</th>
                  <th>Status</th>
                  <th style={{ width: 64 }}></th>
                </tr>
              </thead>
              <tbody>
                {incidents.map(i => (
                  <tr key={i.id} onClick={() => setModal(i)} style={{ cursor: 'pointer' }}>
                    <td className="mono" style={{ fontSize: 11, whiteSpace: 'nowrap' }}>{fmtDt(i.discovered_at)}</td>
                    <td style={{ fontSize: 12 }}>{i.description}</td>
                    <td>
                      <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', fontWeight: 600, color: SEVERITY_COLOR[i.severity], background: `${SEVERITY_COLOR[i.severity]}18`, padding: '2px 6px', borderRadius: 2 }}>
                        {SEVERITY[i.severity] || i.severity}
                      </span>
                    </td>
                    <td>
                      {i.reported_to_ap
                        ? <span style={{ fontSize: 11, color: 'var(--ok)', fontFamily: 'var(--font-mono)' }}>✓ {i.ap_reported_at?.slice(0, 10) || ''}</span>
                        : <span style={{ fontSize: 11, color: 'var(--fg-faint)' }}>—</span>
                      }
                    </td>
                    <td className="mono" style={{ fontSize: 11 }}>{i.individuals_affected ?? '—'}</td>
                    <td>
                      <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', fontWeight: 600, color: STATUS_COLOR[i.status], background: `${STATUS_COLOR[i.status]}18`, padding: '2px 6px', borderRadius: 2 }}>
                        {STATUS_LABEL[i.status] || i.status}
                      </span>
                    </td>
                    <td onClick={e => e.stopPropagation()}>
                      <button className="btn btn--danger btn--sm" onClick={() => handleDelete(i)}>Del</button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <div style={{ padding: '10px 20px', borderTop: '1px solid var(--border)', fontSize: 11, color: 'var(--fg-subtle)', fontFamily: 'var(--font-mono)' }}>
            {incidents.length} incident{incidents.length === 1 ? '' : 's'} · GDPR Art. 33/34 · Internal register
          </div>
        </div>
      )}

      {(modal === 'add' || (modal && typeof modal === 'object')) && (
        <IncidentModal
          incident={modal === 'add' ? null : modal}
          onSave={handleSave}
          onClose={() => setModal(null)}
        />
      )}
    </div>
  );
}
window.Breaches = Breaches;
