// ==========================================================================
// Shell: left rail (threads + agents), composer (with real file input),
// canvas header. All driven from the store.
// ==========================================================================

function LeftRail() {
  const { me, threads, currentThread, route, navigate, createThread, deleteThread, resetAll, briefings, agents } = useStore();
  const [hoverThreadId, setHoverThreadId] = React.useState(null);

  const handleReset = async () => {
    if (!confirm('Reset everything? This wipes:\n- All threads, messages, artifacts (localStorage)\n- All server-side CD sessions and CDBriefs\n\nThe page will reload.')) return;
    await resetAll();
  };

  // Editorial issue line — the "Studio №" masthead reads as a magazine issue.
  // Volume rotates by month; folio counts the threads as the catalogue.
  const today = new Date();
  const volume = `Vol. ${String(today.getFullYear()).slice(-2)}.${String(today.getMonth() + 1).padStart(2, '0')}`;
  const folio = String((threads || []).length).padStart(3, '0');

  const briefingsBadge = (briefings || []).filter(b => ['in_creative_review', 'in_business_review'].includes(b.status)).length;
  const agentsBadge = (agents || []).filter(a => a.unread).length;

  return (
    <div className="glass" style={{
      width: 264, height: 'calc(100vh - 24px)', flexShrink: 0,
      margin: '12px 0 12px 12px',
      padding: '24px 18px 16px',
      display: 'flex', flexDirection: 'column',
      borderRadius: 'var(--radius-lg)',
      position: 'relative', zIndex: 2,
    }}>
      {/* ── Masthead ─────────────────────────────────────────────────── */}
      <div style={{
        display: 'flex', alignItems: 'center', height: 26,
        padding: '0 2px', marginBottom: 4,
        color: 'var(--ink)',
      }}>
        <svg viewBox="0 0 254 92" aria-label="Inku" role="img" style={{ height: 20, width: 'auto', display: 'block', color: 'var(--ink)' }} xmlns="http://www.w3.org/2000/svg">
          <path d="M90.702 19.7382C82.3854 19.7382 76.1465 22.31 71.9914 27.4599V23.2221C71.9914 22.2339 71.2123 21.4358 70.2558 21.4358H55.1683C53.4961 21.4358 52.1406 22.8294 52.1406 24.5524V86.6302C52.1406 88.3531 53.4961 89.7467 55.1683 89.7467H68.7103C70.3825 89.7467 71.738 88.3531 71.738 86.6302V51.5372C71.738 46.3049 72.4157 42.3776 73.7712 39.7614C75.1267 37.1453 77.8883 35.834 82.0434 35.834C88.4914 35.834 91.7154 39.7614 91.7154 47.6098V86.6302C91.7154 88.3531 93.0709 89.7467 94.743 89.7467H108.285C109.957 89.7467 111.313 88.3531 111.313 86.6302V40.6736C111.313 26.7188 104.44 19.7382 90.6956 19.7382H90.702Z" fill="currentColor"/>
          <path d="M165.375 47.3249C164.837 46.4127 164.97 45.2409 165.692 44.4744L183.636 25.4076C185.036 23.919 184.01 21.4359 181.995 21.4359H165.141C164.298 21.4359 163.5 21.7906 162.924 22.4178L142.319 44.8608V3.28765C142.319 1.55201 140.951 0.1521 139.266 0.1521H126.149C124.464 0.1521 123.096 1.55834 123.096 3.28765V86.6049C123.096 88.3406 124.464 89.7405 126.149 89.7405H139.14C140.825 89.7405 142.193 88.3343 142.193 86.6049V69.8819C142.193 69.0268 142.535 68.2033 143.136 67.6142L150.592 60.2979L166.756 88.2076C167.307 89.1577 168.301 89.7405 169.378 89.7405H184.89C187.265 89.7405 188.729 87.0737 187.5 84.9833L165.375 47.3249Z" fill="currentColor"/>
          <path d="M251.074 21.4359H237.462C235.84 21.4359 234.529 22.7851 234.529 24.4511V64.0986C234.529 67.4178 233.592 70.1163 231.73 72.213C229.861 74.3034 227.061 75.3549 223.331 75.3549C217.047 75.3549 213.912 71.9977 213.912 65.2831V24.4574C213.912 22.7915 212.601 21.4422 210.979 21.4422H197.114C195.493 21.4422 194.182 22.7915 194.182 24.4574V67.2468C194.182 75.7096 195.835 81.9048 199.148 85.8258C202.454 89.7532 207.755 91.7168 215.058 91.7168C219.891 91.7168 224.008 90.7983 227.403 88.9677C230.798 87.137 233.129 85.262 234.402 83.3427V87.8718C234.402 88.9107 235.22 89.7532 236.233 89.7532H251.067C252.689 89.7532 254 88.4039 254 86.738V24.4574C254 22.7915 252.689 21.4422 251.067 21.4422L251.074 21.4359Z" fill="currentColor"/>
          <path d="M37.3452 20.6884H23.6321C21.6939 20.6884 20.1231 19.0731 20.1231 17.0777V3.49664C20.1231 1.56463 18.6029 0 16.7217 0H3.40135C1.52015 0 0 1.56463 0 3.49664V17.1918C0 19.1238 1.52015 20.6884 3.40135 20.6884H16.6077C18.5459 20.6884 20.1168 22.3037 20.1168 24.299V37.8801C20.1168 38.1779 20.1548 38.4629 20.2244 38.7353V86.5289C20.2244 88.0871 21.4722 89.3477 23.0114 89.3477H37.3389C38.878 89.3477 40.1258 88.0871 40.1258 86.5289V38.7353C40.1955 38.4629 40.2335 38.1715 40.2335 37.8801V24.185C40.2335 23.8746 40.1892 23.5706 40.1132 23.2792C39.9992 21.8286 38.802 20.6884 37.3389 20.6884H37.3452Z" fill="currentColor"/>
        </svg>
      </div>
      <div className="kicker" style={{ padding: '0 2px', display: 'flex', justifyContent: 'space-between', marginBottom: 22 }}>
        <span>{volume}</span>
        <span className="numeral">№ {folio}</span>
      </div>

      <hr className="rule" style={{ marginBottom: 14 }} />

      {/* ── Begin a thread — glass pill with iridescent border ─────── */}
      <button className="btn-reset shimmer iris-border" onClick={() => createThread({ title: 'New thread' })} style={{
        display: 'flex', gap: 10, alignItems: 'center', justifyContent: 'space-between',
        padding: '12px 16px', cursor: 'pointer',
        color: 'var(--ink)', textAlign: 'left',
        borderRadius: 'var(--radius)',
        background: 'var(--glass-strong)',
        WebkitBackdropFilter: 'blur(20px) saturate(180%)',
        backdropFilter: 'blur(20px) saturate(180%)',
        marginBottom: 16,
        boxShadow: 'var(--shadow-glass)',
        transition: 'transform .35s var(--ease-fluid), box-shadow .35s var(--ease-fluid)',
      }}
      onMouseEnter={e => { e.currentTarget.style.transform = 'translateY(-1px)'; e.currentTarget.style.boxShadow = 'var(--shadow-md), inset 0 1px 0 rgba(255,255,255,.85)'; }}
      onMouseLeave={e => { e.currentTarget.style.transform = 'none'; e.currentTarget.style.boxShadow = 'var(--shadow-glass)'; }}
      >
        <span style={{ fontFamily: 'var(--font-serif)', fontStyle: 'italic', fontSize: 17, fontWeight: 400, letterSpacing: '-0.005em' }}>Begin a thread</span>
        <span className="iridescent" style={{ fontFamily: 'var(--font-mono)', fontSize: 14, lineHeight: 1 }}>→</span>
      </button>

      {/* ── Threads — Contra-style numbered index ────────────────────── */}
      <div className="kicker" style={{ padding: '0 2px 8px', display: 'flex', justifyContent: 'space-between' }}>
        <span>Threads</span>
        <span className="numeral" style={{ color: 'var(--ink-mute)' }}>{folio}</span>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', flex: 1, overflowY: 'auto', margin: '0 -2px' }}>
        {threads.length === 0 && (
          <div className="serif-italic" style={{ padding: '8px 6px', color: 'var(--ink-mute)', fontSize: 13 }}>
            No threads yet.
          </div>
        )}
        {threads.map((t, i) => {
          const active = route.threadId === t.id;
          const hovered = hoverThreadId === t.id;
          return (
            <div key={t.id}
              onMouseEnter={() => setHoverThreadId(t.id)}
              onMouseLeave={() => setHoverThreadId(null)}
              style={{ position: 'relative' }}>
              <button className="btn-reset" onClick={() => navigate(`/t/${t.id}`)} style={{
                width: '100%', padding: '8px 26px 8px 12px',
                color: active ? 'var(--ink)' : 'var(--ink-soft)',
                background: active ? 'var(--glass-soft)' : (hovered ? 'rgba(255,255,255,0.32)' : 'transparent'),
                cursor: 'pointer', display: 'grid',
                gridTemplateColumns: '24px 1fr', gap: 10, alignItems: 'baseline',
                textAlign: 'left',
                borderRadius: 10,
                position: 'relative',
                WebkitBackdropFilter: active ? 'blur(12px)' : 'none',
                backdropFilter: active ? 'blur(12px)' : 'none',
                transition: 'background .25s var(--ease-fluid), color .25s var(--ease-fluid)',
              }}>
                {active && (
                  <span style={{
                    position: 'absolute', left: 2, top: 8, bottom: 8, width: 2,
                    background: 'var(--iris)', borderRadius: 2,
                  }} />
                )}
                <span className="numeral" style={{ fontSize: 10, color: active ? 'var(--moss-deep)' : 'var(--ink-mute)' }}>
                  {String(i + 1).padStart(2, '0')}
                </span>
                <span style={{
                  fontFamily: 'var(--font-serif)', fontSize: 14, fontWeight: active ? 500 : 400,
                  letterSpacing: '-0.005em', lineHeight: 1.25,
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>
                  {t.title}
                </span>
              </button>
              {hovered && !active && (
                <button className="btn-reset" onClick={(e) => { e.stopPropagation(); if (confirm(`Delete "${t.title}"?`)) deleteThread(t.id); }}
                  style={{
                    position: 'absolute', right: 4, top: 6, padding: 4, borderRadius: 4,
                    color: 'var(--ink-mute)', cursor: 'pointer',
                  }}>
                  <Icon name="x" size={11} />
                </button>
              )}
            </div>
          );
        })}
      </div>

      {/* ── Sections ─────────────────────────────────────────────────── */}
      <hr className="rule" style={{ margin: '12px 0 12px' }} />
      <SectionLink
        label="Briefings"
        active={route.name === 'briefings'}
        badge={briefingsBadge}
        onClick={() => navigate('/briefings')}
      />
      <SectionLink
        label="Scheduled agents"
        active={route.name === 'agents'}
        badge={agentsBadge}
        onClick={() => navigate('/agents')}
      />

      {/* ── Colophon ─────────────────────────────────────────────────── */}
      <hr className="rule" style={{ margin: '14px 0 12px' }} />
      <div style={{ display: 'flex', gap: 10, alignItems: 'baseline', padding: '0 2px' }}>
        <div className="kicker">Studio</div>
        <div style={{ flex: 1, overflow: 'hidden', textAlign: 'right' }}>
          <div style={{ fontFamily: 'var(--font-serif)', fontSize: 13, color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{me?.org || '...'}</div>
          <div className="kicker" style={{ marginTop: 2 }}>{me?.name || ''}</div>
        </div>
      </div>
      <button
        type="button"
        className="btn-reset"
        onClick={handleReset}
        title="Reset everything (server sessions + localStorage). Page will reload."
        style={{
          width: '100%', marginTop: 12, padding: '6px 2px',
          background: 'transparent', color: 'var(--ink-mute)',
          fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '.18em',
          textTransform: 'uppercase', cursor: 'pointer',
          display: 'flex', gap: 6, justifyContent: 'flex-end', alignItems: 'center',
        }}
      >
        Reset all · dev
      </button>
    </div>
  );
}

function SectionLink({ label, active, badge, onClick }) {
  const [hover, setHover] = React.useState(false);
  return (
    <button
      className="btn-reset"
      onClick={onClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        width: '100%', padding: '9px 12px',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        cursor: 'pointer', position: 'relative',
        color: active ? 'var(--ink)' : 'var(--ink-soft)',
        borderRadius: 10,
        background: active ? 'var(--glass-soft)' : (hover ? 'rgba(255,255,255,0.32)' : 'transparent'),
        WebkitBackdropFilter: active ? 'blur(12px)' : 'none',
        backdropFilter: active ? 'blur(12px)' : 'none',
        transition: 'background .25s var(--ease-fluid), color .25s var(--ease-fluid)',
      }}>
      {active && (
        <span style={{
          position: 'absolute', left: 2, top: 9, bottom: 9, width: 2,
          background: 'var(--iris)', borderRadius: 2,
        }} />
      )}
      <span style={{
        fontFamily: 'var(--font-serif)',
        fontStyle: hover && !active ? 'italic' : 'normal',
        fontSize: 15, fontWeight: active ? 500 : 400, letterSpacing: '-0.005em',
      }}>{label}</span>
      {badge ? (
        <span className="numeral" style={{
          fontSize: 10,
          color: active ? 'var(--moss-deep)' : 'var(--ink-mute)',
        }}>{String(badge).padStart(2, '0')}</span>
      ) : (
        <span className={hover ? 'iridescent' : ''} style={{ color: hover ? undefined : 'var(--ink-mute)', fontFamily: 'var(--font-mono)', fontSize: 13, lineHeight: 1 }}>→</span>
      )}
    </button>
  );
}

function Composer({ onSend }) {
  const { route, streaming, uploadFiles, currentMessages, currentArtifacts } = useStore();
  const [value, setValue] = React.useState('');
  const fileInputRef = React.useRef(null);

  const disabled = !route.threadId || streaming.active;
  // Mirror ThreadView's canvasActive: wide until canvas appears
  const wide = (currentMessages || []).length === 0 && (currentArtifacts || []).length === 0 && !streaming.active;

  const send = () => {
    const v = value.trim();
    if (!v) return;
    setValue('');
    onSend(v);
  };

  const onFiles = (files) => {
    const arr = Array.from(files);
    if (arr.length) uploadFiles(arr);
  };

  return (
    <div style={{ padding: '14px 18px 18px' }}>
      <div style={{ maxWidth: wide ? 760 : 'none', margin: '0 auto', transition: 'max-width .6s var(--ease-fluid)' }}>
      <input ref={fileInputRef} type="file" multiple style={{ display: 'none' }}
        accept=".pdf,.csv,.xlsx,.doc,.docx,.png,.jpg,.jpeg"
        onChange={(e) => { onFiles(e.target.files); e.target.value = ''; }} />
      <div
        onDragOver={(e) => { e.preventDefault(); }}
        onDrop={(e) => { e.preventDefault(); onFiles(e.dataTransfer.files); }}
        className="glass-strong"
        style={{
          borderRadius: 'var(--radius-lg)',
          padding: '14px 16px',
          display: 'flex', flexDirection: 'column', gap: 10,
        }}>
        <textarea value={value}
          onChange={e => setValue(e.target.value)}
          onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } }}
          placeholder={disabled ? (streaming.active ? 'Inku is thinking…' : 'Create a thread to start') : "Ask Inku, or drop a brief…"}
          disabled={disabled}
          style={{
            border: 'none', outline: 'none', resize: 'none',
            background: 'transparent',
            fontFamily: 'var(--font-serif)', fontStyle: 'italic',
            fontSize: 16, color: 'var(--ink)',
            minHeight: 28, lineHeight: 1.45, width: '100%',
          }} />
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <button className="btn-reset" title="Attach files" disabled={disabled} onClick={() => fileInputRef.current?.click()}
            style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '4px 0', color: disabled ? 'var(--ink-mute)' : 'var(--ink-soft)', cursor: disabled ? 'default' : 'pointer', fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.18em', textTransform: 'uppercase' }}>
            <Icon name="upload" size={13} stroke={1.5} />
            Attach
          </button>
          <button className="btn-reset shimmer" onClick={send} disabled={disabled || !value.trim()} style={{
            padding: '8px 16px', borderRadius: 99,
            background: value.trim() && !disabled ? 'var(--iris)' : 'var(--glass-soft)',
            color: value.trim() && !disabled ? '#fff' : 'var(--ink-mute)',
            cursor: value.trim() && !disabled ? 'pointer' : 'default',
            display: 'flex', gap: 8, alignItems: 'center',
            fontFamily: 'var(--font-serif)', fontStyle: 'italic', fontSize: 14, fontWeight: 500,
            boxShadow: value.trim() && !disabled ? '0 6px 20px rgba(53,2,246,.30)' : 'none',
            transition: 'all .35s var(--ease-fluid)',
          }}>
            Send <Icon name="arrow-up" size={13} stroke={2} />
          </button>
        </div>
      </div>
      </div>
    </div>
  );
}

function CanvasHeader({ title, subtitle, right }) {
  return (
    <div style={{
      padding: '24px 36px 18px',
      display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end',
      position: 'relative',
    }}>
      <div>
        <div className="kicker" style={{ marginBottom: 8 }}>Canvas</div>
        <div className="display" style={{ fontSize: 32, color: 'var(--ink)' }}>{title}</div>
        {subtitle && <div className="serif-italic" style={{ fontSize: 14, color: 'var(--ink-mute)', marginTop: 6 }}>{subtitle}</div>}
      </div>
      <div>{right}</div>
      <span style={{ position: 'absolute', left: 36, right: 36, bottom: 0, height: 1, background: 'var(--iris)', opacity: 0.35, borderRadius: 2 }} />
    </div>
  );
}

function Toast() {
  const { toast } = useStore();
  if (!toast) return null;
  const isError = toast.kind === 'error';
  return (
    <div className="fade-up glass-strong" style={{
      position: 'fixed', bottom: 24, left: '50%', transform: 'translateX(-50%)',
      padding: '12px 22px', borderRadius: 99,
      color: isError ? 'var(--accent-warm-2)' : 'var(--ink)',
      fontFamily: 'var(--font-serif)', fontStyle: 'italic', fontSize: 14, fontWeight: 500,
      zIndex: 1000,
      boxShadow: 'var(--shadow-lg)',
      borderColor: isError ? 'rgba(255,143,160,0.45)' : 'var(--glass-border-strong)',
    }}>
      {toast.text}
    </div>
  );
}

Object.assign(window, { LeftRail, SectionLink, Composer, CanvasHeader, Toast });
