// PracticeDNA.jsx — Practice Suite status analysis (financial, compliance, operational, VPS).
const { useState, useMemo, useEffect, useRef } = React;
const PDE = () => window.PracticeDNAEngine;

const DNA_ICON_PATHS = {
  money: '<rect x="3" y="6" width="18" height="12" rx="2.5"/><circle cx="12" cy="12" r="2.6"/>',
  shield: '<path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6z"/>',
  calendar: '<rect x="3.5" y="5" width="17" height="15.5" rx="2.2"/><path d="M3.5 9.5h17"/>',
  gauge: '<path d="M4 18a8 8 0 1 1 16 0"/><path d="M12 18l4.5-4.5"/>',
  search: '<circle cx="11" cy="11" r="6.5"/><path d="M20 20l-3.8-3.8"/>',
  spark: '<path d="M12 3l1.9 5.3L19 10l-5.1 1.7L12 17l-1.9-5.3L5 10l5.1-1.7z"/>',
  upload: '<path d="M12 16.5V5"/><path d="M7.5 9.5L12 5l4.5 4.5"/><path d="M5 19.5h14"/>',
  check: '<path d="M5 12.5l4.5 4.5L19 7"/>',
  alert: '<path d="M12 4l8.5 15H3.5z"/><path d="M12 10v4.5M12 17.4v.1"/>',
  pulse: '<path d="M3 12h4l2.5-6 4 13 2.5-7H21"/>',
  doc: '<path d="M7 3h7l5 5v13H7z"/><path d="M14 3v5h5"/>',
};
function Icon({ id, size = 18, color = 'currentColor' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"
      dangerouslySetInnerHTML={{ __html: DNA_ICON_PATHS[id] || '' }} />
  );
}
const AB3030 =
  'AI-assisted practice analysis — information and advisory only, not diagnosis or legal advice. ' +
  'California AB 3030 disclosure applies. Clinical and billing outputs require human review (SB 1120).';

const LS_FIN = 'td_practice_dna_financial';
const LS_OPS = 'td_practice_dna_operational';
const LS_COMP = 'td_practice_dna_compliance';

function AB3030Banner() {
  return (
    <div className="banner info" style={{ marginBottom: 14 }}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--blue)" strokeWidth="1.8">
        <path d="M12 4l8.5 15H3.5z" />
        <path d="M12 10v4.5M12 17.4v.1" />
      </svg>
      <div>{AB3030}</div>
    </div>
  );
}

function bandClass(status) {
  if (status === 'good') return 'badge-green';
  if (status === 'watch') return 'badge-gold';
  if (status === 'risk') return 'badge-light';
  return 'badge-gray';
}

function loadJson(key, fallback) {
  try {
    const raw = localStorage.getItem(key);
    return raw ? JSON.parse(raw) : fallback;
  } catch {
    return fallback;
  }
}

function PillarCard({ pillar, expanded, onExpand, onAdvisory }) {
  const b = pillar.band || {};
  return (
    <div className="card">
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 10 }}>
        <div>
          <h3>
            <Icon id={pillar.key === 'financial' ? 'money' : pillar.key === 'compliance' ? 'shield' : pillar.key === 'operational' ? 'calendar' : 'gauge'} size={15} color="var(--sage)" />
            {pillar.title}
          </h3>
          <div className="hint" style={{ marginTop: 4 }}>{pillar.summary}</div>
        </div>
        <span className={'badge ' + bandClass(b.status)}>{b.label || '—'}</span>
      </div>
      {b.score != null && (
        <div style={{ marginTop: 10 }}>
          <div className="bar">
            <div className="bar-fill" style={{ width: Math.min(100, b.score) + '%', background: b.status === 'good' ? 'var(--green)' : b.status === 'watch' ? 'var(--gold)' : 'var(--seal)' }} />
          </div>
        </div>
      )}
      <div style={{ display: 'flex', gap: 8, marginTop: 14, flexWrap: 'wrap' }}>
        <button type="button" className="btn btn-sm" onClick={() => onExpand(pillar.key)}>
          <Icon id="search" size={13} /> {expanded === pillar.key ? 'Collapse' : 'Expand analysis'}
        </button>
        <button type="button" className="btn btn-sm btn-primary" onClick={() => onAdvisory(pillar.key)}>
          <Icon id="spark" size={13} /> Generate advisory path
        </button>
      </div>
      {expanded === pillar.key && (
        <div style={{ marginTop: 14, paddingTop: 14, borderTop: '1px solid var(--border)' }}>
          <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--muted)', marginBottom: 8 }}>Elaboration</div>
          <ul style={{ margin: 0, paddingLeft: 18, fontSize: 12.5, color: 'var(--text)' }}>
            {(pillar.elaboration || []).map((line, i) => (
              <li key={i} style={{ marginBottom: 6 }}>{line}</li>
            ))}
          </ul>
          {(pillar.tracks || []).length > 0 && (
            <div style={{ marginTop: 12 }}>
              <div style={{ fontSize: 11, color: 'var(--muted2)', marginBottom: 6 }}>Suggested tracks</div>
              <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                {pillar.tracks.map((t) => (
                  <span key={t} className="chip tone">{t}</span>
                ))}
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function AdvisoryWizard({ state, pillars, onPick, onClose, result }) {
  const eng = PDE();
  const node = eng && state ? eng.advisoryNode(state) : null;
  if (result) {
    return (
      <div className="card" style={{ marginTop: 16 }}>
        <h3><Icon id="spark" size={15} color="var(--gold)" /> Advisory path — {result.pillar}</h3>
        <div className="hint">Router entry: <code>{result.router_entry}</code> · depth: {result.depth}</div>
        <div className="banner warn" style={{ marginTop: 12 }}>
          <Icon id="alert" size={16} color="var(--seal)" />
          <div>{result.disclaimer}</div>
        </div>
        <ul style={{ margin: '12px 0', paddingLeft: 18, fontSize: 12.5 }}>
          {result.bullets.slice(0, 4).map((b, i) => (
            <li key={i} style={{ marginBottom: 6 }}>{b}</li>
          ))}
        </ul>
        <div style={{ fontSize: 11, color: 'var(--muted2)', marginBottom: 10 }}>Recommended tracks</div>
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 12 }}>
          {result.recommended_tracks.map((t) => (
            <span key={t} className="tag tag-platform">{t}</span>
          ))}
        </div>
        <button type="button" className="btn btn-sm" onClick={onClose}>Close</button>
      </div>
    );
  }
  if (!node) return null;
  return (
    <div className="card" style={{ marginTop: 16 }}>
      <h3><Icon id="spark" size={15} color="var(--gold)" /> Practice DNA advisory</h3>
      <div style={{ fontSize: 14, fontWeight: 600, marginTop: 8 }}>{node.prompt}</div>
      {node.sub && <div className="hint">{node.sub}</div>}
      {node.chips && (
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 14 }}>
          {node.chips.map((c) => (
            <button key={c.slug} type="button" className="btn btn-sm" onClick={() => onPick(c.slug)}>
              {c.label}
            </button>
          ))}
        </div>
      )}
      <button type="button" className="btn btn-sm btn-ghost" style={{ marginTop: 12 }} onClick={onClose}>Cancel</button>
    </div>
  );
}

function PracticeDNA({ vps, inputs }) {
  const eng = PDE();
  const [financial, setFinancial] = useState(() => loadJson(LS_FIN, eng ? eng.sampleFinancial() : {}));
  const [operational, setOperational] = useState(() => loadJson(LS_OPS, eng ? eng.sampleOperational() : {}));
  const [compliance, setCompliance] = useState(() => loadJson(LS_COMP, eng ? eng.defaultCompliance() : {}));
  const [mode, setMode] = useState('template');
  const [expanded, setExpanded] = useState(null);
  const [advisory, setAdvisory] = useState(null);
  const [advisoryResult, setAdvisoryResult] = useState(null);
  const [apiNote, setApiNote] = useState('');
  const [copied, setCopied] = useState(false);
  const tmplRef = useRef();

  useEffect(() => {
    try {
      localStorage.setItem(LS_FIN, JSON.stringify(financial));
      localStorage.setItem(LS_OPS, JSON.stringify(operational));
      localStorage.setItem(LS_COMP, JSON.stringify(compliance));
    } catch (_) { /* ignore */ }
  }, [financial, operational, compliance]);

  const vpsSnapshot = useMemo(() => {
    if (vps && vps.score != null) return vps;
    try {
      const E = window.VPSEngine;
      const raw = localStorage.getItem('td_suite_vps_inputs');
      if (E && raw) return E.computeVPS(JSON.parse(raw));
    } catch (_) { /* ignore */ }
    return vps || { score: null, tier: { label: '—' } };
  }, [vps, inputs]);

  const pillars = useMemo(() => {
    if (!eng) return {};
    return eng.computePillars(financial, compliance, operational, vpsSnapshot);
  }, [financial, compliance, operational, vpsSnapshot]);

  function parseFinancialCSV(text) {
    const lines = text.replace(/\r/g, '').split('\n').filter((l) => l.trim());
    if (lines.length < 2 || !eng) return false;
    const head = lines[0].split(',').map((s) => s.trim());
    const vals = lines[1].split(',').map((s) => s.trim());
    const o = {};
    head.forEach((h, i) => {
      if (eng.FINANCIAL_FIELDS.indexOf(h) >= 0) o[h] = Number(vals[i]) || 0;
    });
    setFinancial((prev) => ({ ...prev, ...o }));
    if (o.chair_hours_booked && o.chair_hours_available) {
      setOperational({ schedule_utilization: o.chair_hours_booked / o.chair_hours_available });
    }
    if (o.recall_completed && o.recall_due) {
      setOperational((p) => ({ ...p, recall_rate: o.recall_completed / o.recall_due }));
    }
    return true;
  }

  function toggleCompliance(id) {
    setCompliance((p) => ({ ...p, [id]: !p[id] }));
  }

  function startAdvisory(pillarKey) {
    if (!eng) return;
    setAdvisoryResult(null);
    setAdvisory(eng.advisoryStart(pillarKey));
  }

  function advisoryPick(slug) {
    if (!eng || !advisory) return;
    const next = eng.advisoryApplyPick(advisory, slug);
    if (!next.nodeId) {
      setAdvisoryResult(eng.advisoryComplete(next, pillars));
      setAdvisory(null);
    } else {
      setAdvisory(next);
    }
  }

  async function callAnalyzeApi() {
    setApiNote('Calling /api/practice-dna/analyze…');
    try {
      const res = await fetch('/api/practice-dna/analyze', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          source: 'practice-suite',
          metrics: { financial, operational, compliance_summary: Object.keys(compliance).filter((k) => compliance[k]).length },
          vps_score: vpsSnapshot.score,
        }),
      });
      const data = await res.json();
      setApiNote(data.ok ? 'Server analysis accepted · router: ' + (data.router_entry || 'practice-dna-advisory') : (data.error || 'Request failed'));
    } catch (e) {
      setApiNote('API unavailable offline — client analysis still valid.');
    }
  }

  function copyExport() {
    if (!eng) return;
    const text = eng.formatAnalysisExport(pillars);
    navigator.clipboard.writeText(text).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  }

  if (!eng) {
    return (
      <div className="wrap">
        <div className="banner warn">
          <Icon id="alert" size={16} color="var(--seal)" />
          <div>Practice DNA engine not loaded. Ensure <code>practice-dna-engine.js</code> is deployed beside this page.</div>
        </div>
      </div>
    );
  }

  const pillarList = ['financial', 'compliance', 'operational', 'recognition'];

  return (
    <div className="wrap">
      <AB3030Banner />

      <div className="banner info">
        <Icon id="pulse" size={16} color="var(--blue)" />
        <div>
          <b>Practice DNA</b> synthesizes de-identified financial, compliance, operational, and VPS signals into
          measurable pillars — starting points for improvement tracks and decision-tree routing. Demo data only; no PHI on public paths.
        </div>
      </div>

      <div className="sectiontitle">Status pillars</div>
      <div className="grid g2">
        {pillarList.map((k) => (
          <PillarCard
            key={k}
            pillar={pillars[k]}
            expanded={expanded}
            onExpand={(key) => setExpanded(expanded === key ? null : key)}
            onAdvisory={startAdvisory}
          />
        ))}
      </div>

      <div className="sectiontitle">Financial metrics input</div>
      <div className="card">
        <div style={{ display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 10, marginBottom: 14 }}>
          <div className="seg">
            <button type="button" className={mode === 'template' ? 'on' : ''} onClick={() => setMode('template')}>Template CSV</button>
            <button type="button" className={mode === 'manual' ? 'on' : ''} onClick={() => setMode('manual')}>Manual entry</button>
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            <button type="button" className="btn btn-sm" onClick={() => { setFinancial(eng.sampleFinancial()); setOperational(eng.sampleOperational()); }}>
              <Icon id="spark" size={14} /> Load sample
            </button>
            <button type="button" className="btn btn-sm" onClick={() => location.hash = '#practice'}>
              <Icon id="gauge" size={14} /> VPS Score Center
            </button>
          </div>
        </div>

        {mode === 'template' && (
          <div className="dropzone" onClick={() => tmplRef.current && tmplRef.current.click()}>
            <Icon id="upload" size={24} color="var(--accent)" />
            <div style={{ marginTop: 8, fontWeight: 600, color: 'var(--text)' }}>Upload practice-dna-data-template.csv</div>
            <input ref={tmplRef} type="file" accept=".csv" style={{ display: 'none' }} onChange={(e) => {
              const f = e.target.files && e.target.files[0];
              if (!f) return;
              const reader = new FileReader();
              reader.onload = () => parseFinancialCSV(String(reader.result));
              reader.readAsText(f);
            }} />
          </div>
        )}

        {mode === 'manual' && (
          <div className="num-grid">
            {eng.FINANCIAL_FIELDS.map((key) => (
              <div className="field" key={key}>
                <label>{key.replace(/_/g, ' ')}</label>
                <input
                  type="number"
                  value={financial[key] ?? ''}
                  onChange={(e) => setFinancial((p) => ({ ...p, [key]: e.target.value === '' ? '' : Number(e.target.value) }))}
                />
              </div>
            ))}
          </div>
        )}
      </div>

      <div className="sectiontitle">Compliance checklist (informational)</div>
      <div className="card">
        {eng.COMPLIANCE_ITEMS.map((c) => (
          <div className="checkitem" key={c.id}>
            <div className={'cbox' + (compliance[c.id] ? ' done' : '')} onClick={() => toggleCompliance(c.id)}>
              {compliance[c.id] && <Icon id="check" size={13} color="#fff" />}
            </div>
            <div style={{ flex: 1, fontSize: 13 }}>{c.label}</div>
          </div>
        ))}
      </div>

      {(advisory || advisoryResult) && (
        <AdvisoryWizard
          state={advisory}
          pillars={pillars}
          onPick={advisoryPick}
          onClose={() => { setAdvisory(null); setAdvisoryResult(null); }}
          result={advisoryResult}
        />
      )}

      <div className="sectiontitle">Analysis tools</div>
      <div className="card" style={{ display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>
        <button type="button" className="btn btn-primary" onClick={callAnalyzeApi}>
          <Icon id="pulse" size={14} /> Run server analysis
        </button>
        <button type="button" className="btn" onClick={copyExport}>
          <Icon id="doc" size={14} /> {copied ? 'Copied' : 'Copy summary'}
        </button>
        {apiNote && <span style={{ fontSize: 12, color: 'var(--muted)' }}>{apiNote}</span>}
      </div>

      <div className="banner ok" style={{ marginTop: 16 }}>
        <Icon id="shield" size={16} color="var(--green)" />
        <div>
          VPS inputs from Practice Management sync via <code>td_suite_vps_inputs</code> localStorage.
          Future: FHIRFLY payer networks and PMS sync (Synchronizer.io / NexHealth) feed financial pillars without PHI on public paths.
        </div>
      </div>
    </div>
  );
}

window.PracticeDNA = PracticeDNA;
