// silo-panel.jsx — zone 3. Renders whatever silo-engine derived; decides nothing.
//
// The panel opens at REST. Landing a doctor in front of eight findings is the
// same wall of text v0 is being criticised for, just better organised. Instead
// they ask a question and Silo answers it, one section at a time.
//
// Palette is v1's Silo tokens (teal #0B7A8C, surface #F0F9FA, border #B2E0E8)
// so this reads as the same product family, sitting on v0's maroon Epic chrome.
// Exports on window: SiloPanel

const SILO_TEAL = '#0B7A8C';

// Each ask maps to one group of derived findings. Counts are deliberately NOT
// shown before the doctor asks — announcing "3 problems" pre-empts the question.
const ASKS = [
  { id: 'decision', label: 'What needs a decision?',    reads: ['Results Review', 'MAR', 'progress notes'] },
  { id: 'watch',    label: "What's being missed?",      reads: ['problem list', 'active orders', 'consult notes'] },
  { id: 'update',   label: 'What changed overnight?',   reads: ['results filed since 06:00'] },
  { id: 'digest',   label: "Condense yesterday's note", reads: ['1,890-word progress note'] },
];

const GROUP_LABEL = {
  decision: 'Needs a decision',
  watch: 'Watching',
  update: 'Since you last looked',
};

const KIND_STYLE = {
  'Contradiction':        { fg: '#B91C1C', bg: '#FFF5F5' },
  'Unaddressed':          { fg: '#92400E', bg: '#FEF9C3' },
  'Open thread':          { fg: '#6B7280', bg: '#F1F5F9' },
  'Care gap':             { fg: '#6B7280', bg: '#F1F5F9' },
  'Trajectory':           { fg: SILO_TEAL, bg: '#F0F9FA' },
  'Since you last looked':{ fg: SILO_TEAL, bg: '#F0F9FA' },
};

function SiloPanel({ findings, digest, onSource, onInsert, onDraftOrder, insertedIds }) {
  const [revealed, setRevealed] = React.useState([]);
  const [dismissed, setDismissed] = React.useState([]);
  const [working, setWorking] = React.useState(null);   // { id, line }
  const timers = React.useRef([]);
  const ctx = window.SILO_CONTEXT();

  React.useEffect(() => () => timers.current.forEach(clearTimeout), []);
  const later = (fn, ms) => { timers.current.push(setTimeout(fn, ms)); };

  // A short, honest working beat: it names the panes it is reading, then answers.
  const ask = React.useCallback((id) => {
    if (revealed.includes(id) || working) return;
    const a = ASKS.find(x => x.id === id);
    setWorking({ id, line: `Reading ${a.reads[0]}…` });
    if (a.reads[1]) later(() => setWorking({ id, line: `Reading ${a.reads[1]}…` }), 420);
    later(() => { setWorking(null); setRevealed(r => [...r, id]); }, 820);
  }, [revealed, working]);

  const askAll = React.useCallback(() => {
    if (working) return;
    const pending = ASKS.map(a => a.id).filter(id => !revealed.includes(id));
    pending.forEach((id, i) => later(() => {
      setWorking({ id, line: `Reading ${ASKS.find(x => x.id === id).reads[0]}…` });
      later(() => { setWorking(null); setRevealed(r => [...r, id]); }, 420);
    }, i * 620));
  }, [revealed, working]);

  const visible = findings.filter(f => !dismissed.includes(f.id));
  const remaining = ASKS.filter(a => !revealed.includes(a.id));
  const atRest = revealed.length === 0;

  return (
    <div style={sp.root}>
      <div style={sp.header}>
        <div style={sp.brandRow}>
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke={SILO_TEAL}
               strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M12 2a10 10 0 100 20A10 10 0 0012 2z" /><path d="M12 8v4l3 3" />
          </svg>
          <span style={sp.brand}>Silo</span>
          <span style={sp.role}>synthetic resident</span>
        </div>
        <div style={sp.ctxLine}>
          Read {ctx.results} result types across {ctx.days} days, {ctx.notes} notes,
          {' '}{ctx.consults} consult notes and {ctx.orders} active orders since {ctx.since}.
        </div>
      </div>

      <div style={sp.scroll}>
        {atRest && !working && (
          <div style={sp.restIntro}>
            I've read this chart. Ask me what you want to know.
          </div>
        )}

        {revealed.includes('digest') && <NoteDigest digest={digest} />}

        {['decision', 'watch', 'update'].map(g => {
          if (!revealed.includes(g)) return null;
          const items = visible.filter(f => f.group === g);
          if (!items.length) return null;
          return (
            <div key={g} style={sp.group}>
              <div style={sp.groupLabel}>
                {GROUP_LABEL[g]}<span style={sp.groupCount}>{items.length}</span>
              </div>
              {items.map(f => (
                <Card key={f.id} f={f}
                  inserted={insertedIds.includes(f.id)}
                  onSource={onSource} onInsert={onInsert} onDraftOrder={onDraftOrder}
                  onDismiss={() => setDismissed(d => [...d, f.id])} />
              ))}
            </div>
          );
        })}

        {working && (
          <div style={sp.working}>
            <span style={sp.spinner} />
            <span>{working.line}</span>
          </div>
        )}

        {remaining.length > 0 && (
          <div style={atRest ? sp.askBoxRest : sp.askBox}>
            {!atRest && <div style={sp.askBoxLabel}>Ask Silo</div>}
            {remaining.map(a => (
              <button key={a.id} style={sp.askBtn} data-gc={`silo-ask-${a.id}`}
                disabled={!!working} onClick={() => ask(a.id)}>
                <span>{a.label}</span><span style={sp.askArrow}>›</span>
              </button>
            ))}
            {remaining.length > 1 && (
              <button style={sp.askAll} data-gc="silo-ask-all"
                disabled={!!working} onClick={askAll}>Run the full review</button>
            )}
          </div>
        )}

        {!atRest && (
          <div style={sp.foot}>
            Every statement above is derived from this chart. Tap a source to open it.
          </div>
        )}
      </div>
    </div>
  );
}

function Card({ f, inserted, onSource, onInsert, onDraftOrder, onDismiss }) {
  const k = KIND_STYLE[f.kind] || KIND_STYLE['Open thread'];
  return (
    <div style={sp.card} data-gc={`silo-card-${f.id}`}>
      <div style={sp.cardHead}>
        <span style={{ ...sp.kind, color: k.fg, background: k.bg }}>{f.kind}</span>
        <span style={sp.dismiss} data-gc={`silo-dismiss-${f.id}`} onClick={onDismiss}>✕</span>
      </div>
      <div style={sp.title}>{f.title}</div>
      <div style={sp.body}>{f.body}</div>

      <div style={sp.sources}>
        {f.sources.map((s, i) => (
          <span key={i} style={sp.chip} data-gc={`silo-source-${f.id}-${i}`}
            onClick={() => onSource(s.pane)}>{s.label}</span>
        ))}
      </div>

      {(f.actions.includes('insert') || f.actions.includes('order')) && (
        <div style={sp.actions}>
          {f.actions.includes('insert') && (
            <button
              style={inserted ? sp.btnDone : sp.btnPrimary}
              data-gc={`silo-insert-${f.id}`}
              onClick={() => !inserted && onInsert(f)}>
              {inserted ? '✓ In note' : 'Insert into note'}
            </button>
          )}
          {f.actions.includes('order') && (
            <button style={sp.btnGhost} data-gc={`silo-order-${f.id}`}
              onClick={() => onDraftOrder(f)}>Draft order</button>
          )}
        </div>
      )}
    </div>
  );
}

function NoteDigest({ digest }) {
  const [open, setOpen] = React.useState(true);
  return (
    <div style={sp.digest}>
      <div style={sp.digestHead} data-gc="silo-digest-toggle" onClick={() => setOpen(o => !o)}>
        <span style={sp.digestTitle}>Yesterday's note, condensed</span>
        <span style={sp.digestMeta}>{open ? '▾' : '▸'}</span>
      </div>
      {open && (
        <>
          {digest.prior.map((line, i) => (
            <div key={i} style={sp.digestLine}><span style={sp.bullet}>—</span>{line}</div>
          ))}
          <div style={sp.digestSplit}>
            {digest.carried.toLocaleString()} of {digest.total.toLocaleString()} words carried
            forward unchanged · {digest.newWords} words were new
          </div>
        </>
      )}
    </div>
  );
}

const sp = {
  root: { width:'100%', height:'100%', display:'flex', flexDirection:'column', background:'#FAFAFA', borderLeft:`2px solid ${SILO_TEAL}`, overflow:'hidden', fontFamily:'"Inter", system-ui, sans-serif' },
  header: { padding:'9px 11px 10px', background:'white', borderBottom:'1px solid #E5E7EB', flexShrink:0 },
  brandRow: { display:'flex', alignItems:'center', gap:6 },
  brand: { fontSize:14, fontWeight:700, color:SILO_TEAL, letterSpacing:-0.2 },
  role: { fontSize:10.5, color:'#9CA3AF', borderLeft:'1px solid #E5E7EB', paddingLeft:7, marginLeft:1 },
  ctxLine: { fontSize:10, color:'#6B7280', lineHeight:1.5, marginTop:5 },
  scroll: { flex:1, overflowY:'auto', padding:'9px 10px 14px' },
  restIntro: { fontSize:11.5, color:'#4B5563', lineHeight:1.6, padding:'14px 2px 4px' },
  askBoxRest: { display:'flex', flexDirection:'column', gap:6, marginTop:6 },
  askBox: { display:'flex', flexDirection:'column', gap:6, marginTop:4, paddingTop:10, borderTop:'1px solid #E5E7EB' },
  askBoxLabel: { fontSize:9.5, fontWeight:800, letterSpacing:0.7, color:'#9CA3AF', textTransform:'uppercase', marginBottom:1 },
  askBtn: { display:'flex', alignItems:'center', justifyContent:'space-between', gap:8, width:'100%', textAlign:'left', fontSize:11, fontWeight:600, color:'#111827', background:'white', border:'1px solid #B2E0E8', borderRadius:5, padding:'9px 11px', cursor:'pointer' },
  askArrow: { color:SILO_TEAL, fontSize:13, flexShrink:0 },
  askAll: { fontSize:10.5, fontWeight:600, color:'white', background:SILO_TEAL, border:'none', borderRadius:5, padding:'8px 11px', cursor:'pointer', marginTop:2 },
  working: { display:'flex', alignItems:'center', gap:8, fontSize:11, color:SILO_TEAL, padding:'11px 2px' },
  spinner: { width:11, height:11, border:`2px solid #B2E0E8`, borderTopColor:SILO_TEAL, borderRadius:'50%', display:'inline-block', animation:'ezSpin 700ms linear infinite' },
  group: { marginBottom:12 },
  groupLabel: { display:'flex', alignItems:'center', gap:6, fontSize:9.5, fontWeight:800, letterSpacing:0.7, color:'#6B7280', textTransform:'uppercase', marginBottom:6 },
  groupCount: { fontSize:9, fontWeight:700, color:'#fff', background:'#9CA3AF', borderRadius:8, padding:'0 5px', minWidth:15, textAlign:'center' },
  card: { background:'white', border:'1px solid #E5E7EB', borderRadius:5, padding:'9px 10px 10px', marginBottom:7 },
  cardHead: { display:'flex', alignItems:'center', marginBottom:5 },
  kind: { fontSize:8.5, fontWeight:800, letterSpacing:0.5, textTransform:'uppercase', padding:'2px 6px', borderRadius:2 },
  dismiss: { marginLeft:'auto', fontSize:11, color:'#D1D5DB', cursor:'pointer', lineHeight:1 },
  title: { fontSize:11.5, fontWeight:700, color:'#111827', lineHeight:1.35, marginBottom:5 },
  body: { fontSize:10.5, color:'#4B5563', lineHeight:1.55, marginBottom:7 },
  sources: { display:'flex', flexWrap:'wrap', gap:4, marginBottom:7 },
  chip: { fontSize:9, color:SILO_TEAL, background:'#F0F9FA', border:'1px solid #B2E0E8', borderRadius:3, padding:'2px 6px', cursor:'pointer', whiteSpace:'nowrap' },
  actions: { display:'flex', gap:5 },
  btnPrimary: { fontSize:10, fontWeight:600, padding:'5px 10px', background:SILO_TEAL, color:'white', border:'none', borderRadius:3, cursor:'pointer' },
  btnGhost: { fontSize:10, fontWeight:600, padding:'5px 10px', background:'white', color:SILO_TEAL, border:`1px solid ${SILO_TEAL}`, borderRadius:3, cursor:'pointer' },
  btnDone: { fontSize:10, fontWeight:600, padding:'5px 10px', background:'#DCFCE7', color:'#166534', border:'1px solid #A7F3D0', borderRadius:3, cursor:'default' },
  digest: { background:'#F0F9FA', border:'1px solid #B2E0E8', borderRadius:5, padding:'8px 10px 9px', marginBottom:12 },
  digestHead: { display:'flex', alignItems:'center', cursor:'pointer', marginBottom:5 },
  digestTitle: { fontSize:10.5, fontWeight:700, color:SILO_TEAL },
  digestMeta: { marginLeft:'auto', fontSize:10, color:SILO_TEAL },
  digestLine: { display:'flex', gap:6, fontSize:10, color:'#374151', lineHeight:1.5, marginBottom:4 },
  bullet: { color:SILO_TEAL, flexShrink:0 },
  digestSplit: { fontSize:9.5, color:'#6B7280', borderTop:'1px solid #B2E0E8', paddingTop:6, marginTop:2 },
  foot: { fontSize:9, color:'#9CA3AF', lineHeight:1.5, paddingTop:4 },
};

Object.assign(window, { SiloPanel });
