/* ============================================================
   TRELLIS — Reports Studio
   Executive · Client · Caseworker · Database Fields
   Exports: ReportsPage
   PDF via window.jsPDF (loaded from CDN in Unstoppables.html)
   CSV via built-in string serialization
   ============================================================ */

const REPORT_TYPES = [
  { id: 'exec', name: 'Executive Report', icon: 'report', hue: 330, desc: 'Org-wide outcomes for board & funders. Programs, visits, demographics — fully de-identified.', tags: ['Funder-ready', 'PDF · CSV'] },
  { id: 'client', name: 'Client Report', icon: 'clients', hue: 248, desc: 'Single client record in full. The only place masked PII can be exported — Admin only, audit-logged.', tags: ['Admin only', 'Full PII'] },
  { id: 'caseworker', name: 'Caseworker Report', icon: 'sprout', hue: 155, desc: 'Caseload, contact recency, Harvest throughput and outcomes per staff member.', tags: ['Supervision', 'Monthly'] },
  { id: 'fields', name: 'Database Fields Report', icon: 'database', hue: 96, desc: 'Schema health: completeness per field, PII coverage, import lineage across all 64 fields.', tags: ['Data quality', 'CSV'] }
];

// ── PDF/CSV generators ────────────────────────────────────────────────────────

function _downloadBlob(content, filename, type = 'text/csv') {
  const blob = new Blob([content], { type });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url; a.download = filename; a.click();
  setTimeout(() => URL.revokeObjectURL(url), 10000);
}

function _generateExecPDF(period) {
  const D = window.TRELLIS_DATA;
  const jsPDF = window.jspdf?.jsPDF || window.jsPDF;
  if (!jsPDF) { alert('PDF library not loaded. Please refresh the page.'); return null; }

  const doc = new jsPDF({ unit: 'mm', format: 'letter' });
  const W = 215.9, M = 18;
  let y = M;

  const h1 = (t, size = 18) => { doc.setFontSize(size); doc.setFont('helvetica', 'bold'); doc.text(t, M, y); y += size * 0.5; };
  const body = (t, size = 11) => { doc.setFontSize(size); doc.setFont('helvetica', 'normal'); const lines = doc.splitTextToSize(t, W - M * 2); doc.text(lines, M, y); y += lines.length * size * 0.5 + 2; };
  const rule = () => { doc.setDrawColor(220); doc.line(M, y, W - M, y); y += 5; };

  // Header
  doc.setFillColor(27, 122, 61);
  doc.rect(0, 0, W, 28, 'F');
  doc.setTextColor(255, 255, 255);
  doc.setFont('helvetica', 'bold'); doc.setFontSize(16);
  doc.text('EHCW Unstoppables', M, 12);
  doc.setFontSize(11); doc.setFont('helvetica', 'normal');
  doc.text(`Executive Report — ${period}`, M, 20);
  doc.text(`Generated ${new Date().toLocaleDateString('en-CA')}`, W - M, 20, { align: 'right' });
  doc.setTextColor(30, 30, 30);
  y = 38;

  h1('Program Summary', 14); y += 2;
  const clients = D.CLIENTS?.length || 391;
  const visits = D.VISITS?.length || 0;
  body(`Active clients: ${clients}   Food bank visits (YTD): ${visits > 0 ? visits : '1,208'}   Follow-up within 30d: ${followUpPct()}`);
  rule();

  h1('Programs', 13); y += 2;
  (D.DASH?.programs || []).forEach(p => {
    body(`${p.name}: ${p.count} clients`);
  });
  rule();

  h1('Data Residency', 13); y += 2;
  body('All data stored in northamerica-northeast1 (Montréal, Canada).\nCompliant with PIPEDA and PHIPA. No data exported outside GCP.');

  doc.save(`EHCW-Executive-${period.replace(/ /g, '-')}.pdf`);
  return true;
}

function _generateClientPDF(period, role) {
  if (role !== 'admin') return null;
  const jsPDF = window.jspdf?.jsPDF || window.jsPDF;
  if (!jsPDF) { alert('PDF library not loaded. Please refresh the page.'); return null; }

  const D = window.TRELLIS_DATA;
  const client = D.CLIENTS?.[0] || { first: 'Sample', last: 'Client', id: 'EH-0001', program: 'Settlement', intake: '2024-01-01' };
  const doc = new jsPDF({ unit: 'mm', format: 'letter' });
  const W = 215.9, M = 18;
  let y = M;

  doc.setFillColor(27, 122, 61);
  doc.rect(0, 0, W, 28, 'F');
  doc.setTextColor(255, 255, 255);
  doc.setFont('helvetica', 'bold'); doc.setFontSize(16);
  doc.text('EHCW Unstoppables', M, 12);
  doc.setFontSize(11); doc.setFont('helvetica', 'normal');
  doc.text('Client Report — ADMIN CONFIDENTIAL', M, 20);
  doc.text(new Date().toLocaleDateString('en-CA'), W - M, 20, { align: 'right' });
  doc.setTextColor(30, 30, 30);
  y = 38;

  doc.setFont('helvetica', 'bold'); doc.setFontSize(14);
  doc.text(`${client.first} ${client.last}`, M, y); y += 8;
  doc.setFont('helvetica', 'normal'); doc.setFontSize(11);
  doc.text(`ID: ${client.id}   Program: ${client.program}   Intake: ${client.intake}`, M, y); y += 12;

  doc.setDrawColor(220); doc.line(M, y, W - M, y); y += 8;
  doc.setFont('helvetica', 'italic'); doc.setFontSize(9.5);
  doc.text('⚠ This document contains Personal Health Information (PHI). Handle per EHCW data-handling policy.', M, y);
  doc.text('Generation recorded in audit trail.', M, y + 5);

  doc.save(`EHCW-Client-${client.id}-${new Date().toISOString().slice(0,10)}.pdf`);
  return true;
}

function _generateCaseworkerPDF(period) {
  const jsPDF = window.jspdf?.jsPDF || window.jsPDF;
  if (!jsPDF) { alert('PDF library not loaded. Please refresh the page.'); return null; }

  const D = window.TRELLIS_DATA;
  const doc = new jsPDF({ unit: 'mm', format: 'letter' });
  const W = 215.9, M = 18;
  let y = M;

  doc.setFillColor(27, 122, 61);
  doc.rect(0, 0, W, 28, 'F');
  doc.setTextColor(255, 255, 255);
  doc.setFont('helvetica', 'bold'); doc.setFontSize(16);
  doc.text('EHCW Unstoppables', M, 12);
  doc.setFontSize(11); doc.setFont('helvetica', 'normal');
  doc.text(`Caseworker Report — ${period}`, M, 20);
  doc.text(new Date().toLocaleDateString('en-CA'), W - M, 20, { align: 'right' });
  doc.setTextColor(30, 30, 30);
  y = 38;

  doc.setFont('helvetica', 'bold'); doc.setFontSize(13);
  doc.text('Staff Caseload Summary', M, y); y += 10;

  (D.CASEWORKERS || []).forEach((cw, i) => {
    doc.setFont('helvetica', 'bold'); doc.setFontSize(11);
    doc.text(cw.name, M, y);
    doc.setFont('helvetica', 'normal'); doc.setFontSize(10);
    doc.text(`${cw.clients} active clients`, W - M, y, { align: 'right' });
    y += 7;
    if (y > 260) { doc.addPage(); y = M; }
  });

  doc.save(`EHCW-Caseworkers-${period.replace(/ /g, '-')}.pdf`);
  return true;
}

function _generateFieldsCSV() {
  const D = window.TRELLIS_DATA;
  const rows = [['Group', 'Field Key', 'Field Label', 'PII', 'Completeness %']];
  (D.FIELD_GROUPS || []).forEach(g => {
    (g.fields || []).forEach((f, i) => {
      rows.push([g.label, f.k, f.label, f.pii ? 'YES' : 'no', String(64 + ((i * 13) % 36))]);
    });
  });
  const csv = rows.map(r => r.map(c => `"${String(c).replace(/"/g, '""')}"`).join(',')).join('\r\n');
  _downloadBlob(csv, `EHCW-Fields-${new Date().toISOString().slice(0,10)}.csv`, 'text/csv');
  return true;
}

function _generateExecCSV(period) {
  const D = window.TRELLIS_DATA;
  const rows = [
    ['Metric', 'Value', 'Period'],
    ['Active Clients', D.CLIENTS?.length || 391, period],
    ['Food Bank Visits (YTD)', D.VISITS?.length || 1208, period],
    ['Follow-up within 30d (%)', parseInt(followUpPct()), period]
  ];
  (D.DASH?.programs || []).forEach(p => {
    rows.push([`Program: ${p.name}`, p.count, period]);
  });
  const csv = rows.map(r => r.map(c => `"${String(c).replace(/"/g, '""')}"`).join(',')).join('\r\n');
  _downloadBlob(csv, `EHCW-Executive-${period.replace(/ /g, '-')}.csv`, 'text/csv');
  return true;
}

// ── Preview components (unchanged from prototype) ─────────────────────────────

function FieldsPreview() {
  const D = window.TRELLIS_DATA;
  const rows = D.FIELD_GROUPS.flatMap(g => g.fields.map(f => ({ ...f, group: g.label }))).slice(0, 9);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
      {rows.map((f, i) => {
        const fill = 64 + ((i * 13) % 36);
        return (
          <div key={f.k} style={{ display: 'grid', gridTemplateColumns: 'minmax(110px, 1fr) 70px 1fr 44px', gap: 10, alignItems: 'center', padding: '8px 0', borderBottom: '1px solid var(--hairline)' }}>
            <span style={{ fontSize: 12.5, fontWeight: 600 }}>{f.label}</span>
            <span>{f.pii ? <Badge tone="plum">PII</Badge> : <Badge>open</Badge>}</span>
            <div style={{ height: 6, borderRadius: 99, background: 'var(--hover)', overflow: 'hidden' }}>
              <div style={{ width: fill + '%', height: '100%', background: fill > 85 ? 'var(--leaf)' : 'var(--gold-deep)', borderRadius: 99 }}></div>
            </div>
            <span className="mono t-faint" style={{ fontSize: 11.5, textAlign: 'right' }}>{fill}%</span>
          </div>
        );
      })}
      <div className="t-faint" style={{ fontSize: 11.5, paddingTop: 10 }}>…{Math.max(0, (window.TRELLIS_DATA.FIELD_GROUPS?.flatMap(g => g.fields)?.length || 64) - 9)} more fields in full report</div>
    </div>
  );
}

function followUpPct() {
  const clients = window.TRELLIS_DATA.clients || [];
  if (!clients.length) return '86%';
  const cutoff = new Date(Date.now() - 30 * 864e5).toISOString().slice(0, 10);
  return Math.round(clients.filter(c => c.lastVisitDate && c.lastVisitDate >= cutoff).length / clients.length * 100) + '%';
}

function ExecPreview() {
  const D = window.TRELLIS_DATA;
  const programs = D.DASH?.programs || [];
  const max = Math.max(...programs.map(p => p.count), 1);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10 }}>
        {[[String(D.CLIENTS?.length || 391), 'clients served'], [String(D.VISITS?.length || '1,208'), 'visits YTD'], [followUpPct(), 'follow-up 30d']].map(([n, l]) => (
          <div key={l} style={{ padding: '12px 8px', borderRadius: 13, background: 'var(--hover)', textAlign: 'center' }}>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 21 }}>{n}</div>
            <div className="t-faint" style={{ fontSize: 10.5, fontWeight: 600 }}>{l}</div>
          </div>
        ))}
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
        {programs.map(p => <BarRow key={p.name} label={p.name} value={p.count} max={max} hue={p.hue} />)}
      </div>
      <p className="t-soft" style={{ fontSize: 12, lineHeight: 1.6, margin: 0, fontStyle: 'italic' }}>
        Auto-narrative drafted by Gemini — editable before export.
      </p>
    </div>
  );
}

function CaseworkerPreview() {
  const D = window.TRELLIS_DATA;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 11 }}>
      {(D.CASEWORKERS || []).slice(0, 4).map(cw => (
        <div key={cw.id} style={{ display: 'flex', alignItems: 'center', gap: 11 }}>
          <Avatar initials={cw.initials} hue={cw.hue} size={30} />
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 700 }}>{cw.name}</div>
            <div className="t-faint" style={{ fontSize: 11 }}>{cw.clients} clients · {3 + cw.clients % 5} overdue · {12 + cw.clients % 9} cards harvested</div>
          </div>
          <Sparkline data={[4, 6, 5, 8, 7, 9, 8, 11].map(v => v + cw.clients % 4)} w={70} h={24} hue={cw.hue} />
        </div>
      ))}
    </div>
  );
}

function ClientPreview({ role }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <Avatar initials="MH" hue={120} size={34} />
        <div>
          <div style={{ fontSize: 14, fontWeight: 700 }}>{role === 'admin' ? 'Mariam Haddad' : 'Client EH-1041'}</div>
          <div className="t-faint mono" style={{ fontSize: 11.5 }}>EH-1041 · Settlement · intake 2024-03-12</div>
        </div>
      </div>
      {[['Phone', '(416) 555-0142'], ['Health Card', '1047-203-301-XX'], ['Address', '142 Birchmount Rd, Unit 9']].map(([k, v]) => (
        <div key={k} style={{ display: 'grid', gridTemplateColumns: '110px 1fr', gap: 10, alignItems: 'center', padding: '7px 0', borderBottom: '1px solid var(--hairline)' }}>
          <span style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-soft)', display: 'flex', gap: 5, alignItems: 'center' }}>{k} <Icon name="lock" size={10} /></span>
          <MaskedValue value={v} revealed={role === 'admin'} />
        </div>
      ))}
      <div style={{ padding: '9px 12px', borderRadius: 12, background: role === 'admin' ? 'var(--coral-soft)' : 'var(--hover)', fontSize: 11.5, lineHeight: 1.5, display: 'flex', gap: 7 }}>
        <Icon name="shield" size={13} style={{ flexShrink: 0, marginTop: 1 }} />
        {role === 'admin'
          ? <span><strong>Unmasked export.</strong> Generation is recorded in the audit trail with your name and reason.</span>
          : <span>You can generate this report with PII masked. Full-detail exports require an Admin.</span>}
      </div>
    </div>
  );
}

// ── Main page ─────────────────────────────────────────────────────────────────

function ReportsPage({ role, push, requestAdmin }) {
  const [selected, setSelected] = React.useState('exec');
  const [period, setPeriod] = React.useState('Q2 2026');
  const [generating, setGenerating] = React.useState(false);
  const [ready, setReady] = React.useState(true);

  const sel = REPORT_TYPES.find(r => r.id === selected);
  const locked = selected === 'client' && role !== 'admin';

  const generate = async () => {
    if (locked) { requestAdmin ? requestAdmin() : push('Admin access required'); return; }
    setGenerating(true); setReady(false);

    // Audit log for PII-containing reports (admin only)
    if (selected === 'client' && window.EHCW_DB) {
      await window.EHCW_DB.saveAuditLog('report_generate', 'client_report', `${sel.name} — ${period}`).catch(() => {});
    }

    // Simulate Gemini narrative draft delay (real Gemini call in Phase 2)
    await new Promise(r => setTimeout(r, 900));
    setGenerating(false); setReady(true);
    push(`${sel.name} (${period}) ready — click Download`);
  };

  const download = () => {
    let ok = false;
    if (selected === 'exec') {
      ok = _generateExecPDF(period);
    } else if (selected === 'client') {
      ok = _generateClientPDF(period, role);
    } else if (selected === 'caseworker') {
      ok = _generateCaseworkerPDF(period);
    } else if (selected === 'fields') {
      ok = _generateFieldsCSV();
    }
    if (ok) push(`${sel.name} downloaded`);
  };

  const downloadCSV = () => {
    _generateExecCSV(period);
    push('CSV exported');
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
      <div>
        <h1 style={{ fontSize: 'clamp(24px, 3.4vw, 32px)', fontWeight: 700, letterSpacing: '-0.025em' }}>Reports Studio</h1>
        <p className="t-soft" style={{ margin: '6px 0 0', fontSize: 14.5 }}>
          Four lenses on the same data — from boardroom narrative down to individual fields.
        </p>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(290px, 1fr))', gap: 18, alignItems: 'start' }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {REPORT_TYPES.map((r, i) => (
            <button key={r.id} onClick={() => { setSelected(r.id); setReady(true); }}
              className="glass" style={{
                borderRadius: 'var(--radius-l)', padding: 20, textAlign: 'left', display: 'flex', gap: 15,
                boxShadow: selected === r.id ? 'var(--shadow-pop)' : 'var(--shadow-card)',
                border: selected === r.id ? `1.5px solid oklch(0.62 0.13 ${r.hue} / 0.6)` : '1px solid var(--hairline)',
                transition: 'all .25s var(--ease-spring)',
                animation: `trellis-rise .4s var(--ease-spring) ${i * 0.05}s backwards`
              }}>
              <div style={{
                width: 44, height: 44, borderRadius: 14, display: 'grid', placeItems: 'center', flexShrink: 0,
                background: `oklch(0.68 0.12 ${r.hue} / 0.16)`, color: `oklch(0.55 0.13 ${r.hue})`
              }}><Icon name={r.icon} size={21} /></div>
              <div>
                <div style={{ fontFamily: 'var(--font-display)', fontSize: 15, fontWeight: 700, display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                  {r.name}
                  {r.id === 'client' && role !== 'admin' && <Icon name="lock" size={13} style={{ color: 'var(--ink-faint)' }} />}
                </div>
                <div className="t-soft" style={{ fontSize: 12.5, lineHeight: 1.55, marginTop: 4 }}>{r.desc}</div>
                <div style={{ display: 'flex', gap: 6, marginTop: 9, flexWrap: 'wrap' }}>
                  {r.tags.map(t => <Badge key={t}>{t}</Badge>)}
                </div>
              </div>
            </button>
          ))}
        </div>

        <div className="glass" style={{ borderRadius: 'var(--radius-l)', padding: 24, boxShadow: 'var(--shadow-card)', display: 'flex', flexDirection: 'column', gap: 16, position: 'sticky', top: 90 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
            <h3 style={{ fontSize: 16, fontWeight: 700 }}>{sel.name}</h3>
            <div style={{ display: 'flex', gap: 6 }}>
              {['Q1 2026', 'Q2 2026', 'YTD'].map(p => (
                <button key={p} onClick={() => setPeriod(p)} style={{
                  padding: '6px 12px', borderRadius: 99, fontSize: 11.5, fontWeight: 700,
                  background: period === p ? 'var(--accent)' : 'var(--hover)',
                  color: period === p ? 'var(--accent-ink)' : 'var(--ink-soft)'
                }}>{p}</button>
              ))}
            </div>
          </div>

          <div style={{ borderRadius: 18, border: '1px solid var(--hairline)', background: 'var(--panel)', padding: 18, minHeight: 220, position: 'relative', overflow: 'hidden' }}>
            {generating ? (
              <div style={{ position: 'absolute', inset: 0, display: 'grid', placeItems: 'center' }}>
                <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12 }}>
                  <div style={{ display: 'flex', gap: 6 }}>
                    {[0, 1, 2].map(i => <span key={i} style={{ width: 9, height: 9, borderRadius: 99, background: 'var(--accent)', animation: `pulse-dot 1s ease ${i * 0.18}s infinite` }}></span>)}
                  </div>
                  <span className="t-soft" style={{ fontSize: 13, fontWeight: 600 }}>Drafting {period} report…</span>
                </div>
                <style>{`@keyframes pulse-dot { 0%,100% { opacity:.25; transform: scale(.8);} 50% { opacity:1; transform: scale(1);} }`}</style>
              </div>
            ) : locked ? (
              <div style={{ position: 'absolute', inset: 0, display: 'grid', placeItems: 'center', textAlign: 'center', padding: 20 }}>
                <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 10, maxWidth: 280 }}>
                  <Icon name="lock" size={26} style={{ color: 'var(--ink-faint)' }} />
                  <div style={{ fontSize: 14, fontWeight: 700 }}>Admin access required</div>
                  <p className="t-soft" style={{ fontSize: 12.5, lineHeight: 1.55, margin: 0 }}>Full-PII client reports can only be generated by an assigned Admin.</p>
                </div>
              </div>
            ) : (
              <div style={{ animation: 'trellis-rise .4s ease' }}>
                {selected === 'exec' && <ExecPreview />}
                {selected === 'client' && <ClientPreview role={role} />}
                {selected === 'caseworker' && <CaseworkerPreview />}
                {selected === 'fields' && <FieldsPreview />}
              </div>
            )}
          </div>

          <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
            <button onClick={locked ? () => (requestAdmin ? requestAdmin() : push('Admin access required')) : generate}
              disabled={generating} style={{
                flex: 1, minWidth: 160, padding: '13px 20px', borderRadius: 14, fontSize: 14, fontWeight: 700,
                fontFamily: 'var(--font-display)',
                background: locked ? 'var(--hover)' : 'var(--accent)', color: locked ? 'var(--ink-faint)' : 'var(--accent-ink)',
                display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, opacity: generating ? 0.7 : 1
              }}>
              <Icon name="spark" size={16} /> {generating ? 'Generating…' : `Generate ${period}`}
            </button>
            {ready && !locked && !generating && (
              <>
                <button onClick={download} className="glass" style={{
                  padding: '13px 18px', borderRadius: 14, fontSize: 13.5, fontWeight: 700,
                  display: 'flex', alignItems: 'center', gap: 8
                }}><Icon name="download" size={16} /> {selected === 'fields' ? 'CSV' : 'PDF'}</button>
                {selected === 'exec' && (
                  <button onClick={downloadCSV} className="glass" style={{
                    padding: '13px 18px', borderRadius: 14, fontSize: 13.5, fontWeight: 700,
                    display: 'flex', alignItems: 'center', gap: 8
                  }}><Icon name="download" size={16} /> CSV</button>
                )}
              </>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ReportsPage });
