// chat-extra-2.jsx — Chat components G'–L
// G': Composer mic button, G'': Speak button on assistant messages
// H: Thread length, I: Export/share, J: Citations, K: Model switcher, L: Empty guide

// ═════════════════════════════════════════════════════════════
// G' · COMPOSER MIC BUTTON (idle / recording / transcribing / denied / done)
// ═════════════════════════════════════════════════════════════

function ChatComposerMic({ dark, state = 'idle' }) {
  const t = dark ? G.d : G.l;
  const isRecording = state === 'recording-1s' || state === 'recording-4s';
  const recordTime = state === 'recording-1s' ? '0:01' : state === 'recording-4s' ? '0:04' : '0:00';

  // Pre-existing conversation context above
  const Convo = () => (
    <>
      <UserMsg dark={dark}>Audit the auth middleware</UserMsg>
      <AssistantMsg dark={dark}>
        <p style={{ margin: '4px 0' }}>I found two critical issues with the auth middleware on lines 142 and 156. The first lets external clients bypass authentication via a header.</p>
      </AssistantMsg>
    </>
  );

  // Composer with custom mic state
  const placeholderText = {
    idle: 'Reply or speak…',
    'recording-1s': '',
    'recording-4s': '',
    transcribing: '',
    denied: 'Reply or speak…',
    done: '',
  }[state];

  const filledText = state === 'done' ? 'Add proxy chain verification before trusting the internal trust header' : '';

  // Waveform bars (live mic)
  const WaveBars = ({ count = 32, intense }) => (
    <div style={{ display: 'flex', gap: 2, alignItems: 'center', height: 14 }}>
      {Array.from({ length: count }, (_, i) => {
        const h = intense
          ? 3 + Math.abs(Math.sin(i * 0.7 + (state === 'recording-4s' ? 1 : 0))) * 11
          : 2 + Math.abs(Math.sin(i * 0.4)) * 4;
        return <div key={i} style={{ width: 2, height: h, background: '#ff5f57', borderRadius: 1, opacity: 0.6 + Math.abs(Math.sin(i * 0.3)) * 0.4 }} />;
      })}
    </div>
  );

  const MicButton = () => {
    if (isRecording) {
      return (
        <button style={{
          height: 36, padding: '0 12px', borderRadius: 999, border: 'none',
          background: '#ff5f57', color: '#fff', display: 'flex', alignItems: 'center', gap: 8,
          cursor: 'pointer', fontFamily: G.mono, fontSize: 12, fontWeight: 500,
        }}>
          <div style={{ width: 8, height: 8, borderRadius: 2, background: '#fff', animation: 'gh-pulse 1s infinite' }} />
          {recordTime}
          <Icon name="check" size={12} color="#fff" />
        </button>
      );
    }
    if (state === 'transcribing') {
      return (
        <button style={{
          width: 36, height: 36, borderRadius: 18, border: `1px solid ${t.border}`,
          background: t.surface, display: 'flex', alignItems: 'center', justifyContent: 'center',
          cursor: 'pointer', position: 'relative',
        }}>
          <Icon name="mic" size={15} color={t.fg2} />
          <div style={{ position: 'absolute', top: -2, right: -2, width: 14, height: 14, borderRadius: 7, background: t.bg, border: `2px solid ${t.fg2}`, borderTopColor: 'transparent', animation: 'gh-spin 0.8s linear infinite' }} />
        </button>
      );
    }
    if (state === 'denied') {
      return (
        <div style={{ position: 'relative' }}>
          <button style={{
            width: 36, height: 36, borderRadius: 18, border: `1px solid #ff5f57`,
            background: 'transparent', display: 'flex', alignItems: 'center', justifyContent: 'center',
            cursor: 'pointer', color: '#ff5f57',
          }}>
            <Icon name="warn" size={15} color="#ff5f57" />
          </button>
          {/* Tooltip */}
          <div style={{
            position: 'absolute', bottom: 'calc(100% + 8px)', right: -6, width: 220,
            padding: '8px 12px', background: dark ? '#1a1a1a' : '#0A0A0A', color: '#fff',
            borderRadius: 8, fontSize: 11, lineHeight: 1.4, boxShadow: '0 8px 24px rgba(0,0,0,0.25)',
          }}>
            Microphone access denied. Enable in System Settings → Privacy → Microphone.
            <div style={{ position: 'absolute', top: '100%', right: 14, width: 0, height: 0, borderLeft: '5px solid transparent', borderRight: '5px solid transparent', borderTop: `5px solid ${dark ? '#1a1a1a' : '#0A0A0A'}` }} />
          </div>
        </div>
      );
    }
    // idle / done
    return (
      <button style={{
        width: 36, height: 36, borderRadius: 18, border: `1px solid ${t.border}`,
        background: 'transparent', display: 'flex', alignItems: 'center', justifyContent: 'center',
        cursor: 'pointer', color: t.fg2,
      }}>
        <Icon name="mic" size={15} />
      </button>
    );
  };

  return (
    <ChatLayout dark={dark} title="Auth audit"
      composer={
        <div style={{ padding: '12px 24px 18px', borderTop: `0.5px solid ${t.border}` }}>
          <div style={{
            background: t.surface, border: `1px solid ${isRecording ? '#ff5f57' : t.border}`, borderRadius: 14,
            padding: '10px 12px', display: 'flex', flexDirection: 'column', gap: 8,
          }}>
            {/* Top: text input area */}
            <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
              <div style={{ flex: 1, minHeight: 22, fontSize: 14, color: filledText ? t.fg : t.fg3, lineHeight: 1.45 }}>
                {filledText || placeholderText}
                {state === 'transcribing' && (
                  <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, color: t.fg3 }}>
                    <span style={{ display: 'inline-block', width: 10, height: 10, border: `1.5px solid ${t.fg3}`, borderTopColor: t.fg, borderRadius: 5, animation: 'gh-spin 0.8s linear infinite' }} />
                    Transcribing 4s clip…
                  </span>
                )}
              </div>
            </div>
            {/* Bottom row */}
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <button style={{ width: 28, height: 28, borderRadius: 6, border: 'none', background: 'transparent', color: t.fg3, cursor: 'pointer' }}>
                <Icon name="paperclip" size={14} />
              </button>
              {/* Live waveform when recording */}
              {isRecording && (
                <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 8 }}>
                  <WaveBars intense={state === 'recording-4s'} />
                  <span style={{ fontSize: 11, color: t.fg3, fontFamily: G.mono }}>Tap mic again to send</span>
                </div>
              )}
              {!isRecording && <div style={{ flex: 1 }} />}
              <MicButton />
              <button style={{
                width: 36, height: 36, borderRadius: 18, border: 'none',
                background: filledText ? t.fg : t.surface2,
                color: filledText ? t.bg : t.fg3,
                display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
              }}>
                <Icon name="arrowUp" size={15} />
              </button>
            </div>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8, fontSize: 10, color: t.fg3, fontFamily: G.mono }}>
            <span>claude-3.7-sonnet</span>
            <span>{isRecording ? `Recording · ${recordTime}` : state === 'transcribing' ? 'whisper-1' : 'Hold ⌘ to dictate'}</span>
          </div>
        </div>
      }
    >
      <Convo />
    </ChatLayout>
  );
}


// ═════════════════════════════════════════════════════════════
// G'' · SPEAK BUTTON ON ASSISTANT MESSAGES
// ═════════════════════════════════════════════════════════════

function ChatSpeakButton({ dark, state = 'idle' }) {
  const t = dark ? G.d : G.l;
  const isPlaying = state === 'playing';
  const isPaused = state === 'paused';
  const isActive = isPlaying || isPaused;

  // Mini progress bars inside message card (left edge waveform)
  const ProgressBars = ({ progress }) => (
    <div style={{ position: 'absolute', left: 0, top: 8, bottom: 8, width: 3, display: 'flex', flexDirection: 'column', justifyContent: 'space-around', alignItems: 'center', overflow: 'hidden' }}>
      {Array.from({ length: 18 }, (_, i) => {
        const played = i / 18 < progress;
        const h = 3 + Math.abs(Math.sin(i * 0.6)) * 4;
        return <div key={i} style={{ width: 3, height: h, background: played ? '#5865F2' : t.fg4, borderRadius: 1.5 }} />;
      })}
    </div>
  );

  const ActionBar = ({ active }) => (
    <div style={{
      position: 'absolute', top: -32, right: 12, display: 'flex', gap: 1,
      padding: 3, background: t.surface, border: `1px solid ${t.border}`, borderRadius: 10,
      boxShadow: t.shadow, opacity: active ? 1 : 0,
    }}>
      {[
        { ic: 'copy', lbl: 'Copy' },
        { ic: 'edit', lbl: 'Edit' },
        { ic: 'refresh', lbl: 'Re-roll' },
        { ic: 'branch', lbl: 'Branch' },
      ].map(a => (
        <button key={a.ic} title={a.lbl} style={{ width: 26, height: 26, borderRadius: 7, background: 'transparent', border: 'none', color: t.fg2, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <Icon name={a.ic} size={12} />
        </button>
      ))}
      {/* The new Speak button */}
      <button style={{
        height: 26, padding: '0 8px', borderRadius: 7,
        background: isActive ? '#5865F2' : 'transparent', color: isActive ? '#fff' : t.fg2,
        border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 4, fontSize: 11, fontFamily: G.font, fontWeight: 500,
      }}>
        <Icon name={isPlaying ? 'pause' : 'play'} size={11} color={isActive ? '#fff' : t.fg2} />
        {isPlaying ? '0:14 / 0:38' : isPaused ? '0:09 / 0:38' : 'Speak'}
      </button>
    </div>
  );

  return (
    <ChatLayout dark={dark} title="Auth audit">
      <UserMsg dark={dark}>Walk me through the X-Internal-Trust issue</UserMsg>

      {/* Other assistant message — not playing */}
      <div style={{ display: 'flex', gap: 12, marginBottom: 16 }}>
        <GhastLogo size={20} color={t.fg2} style={{ flexShrink: 0, marginTop: 2 }} />
        <div style={{ flex: 1, fontSize: 14, color: t.fg, lineHeight: 1.55 }}>
          <p style={{ margin: 0 }}>Sure — the header on line 142 is being trusted directly without verifying the request actually came from a known proxy.</p>
        </div>
      </div>

      {/* Hovered/active assistant message with the action bar */}
      <div style={{ position: 'relative', display: 'flex', gap: 12, marginBottom: 8, padding: '10px 12px 10px 16px', borderRadius: 12, background: isActive ? (dark ? 'rgba(88,101,242,0.06)' : 'rgba(88,101,242,0.04)') : 'transparent', border: isActive ? `1px solid rgba(88,101,242,0.2)` : '1px solid transparent' }}>
        {isActive && <ProgressBars progress={isPlaying ? 0.36 : 0.24} />}
        <GhastLogo size={20} color={t.fg2} style={{ flexShrink: 0, marginTop: 2, marginLeft: isActive ? 8 : 0 }} />
        <div style={{ flex: 1, fontSize: 14, color: t.fg, lineHeight: 1.55 }}>
          <p style={{ margin: 0 }}>
            The fix has three parts. <strong style={{ background: isPlaying ? 'rgba(88,101,242,0.2)' : 'transparent', borderRadius: 3, padding: isPlaying ? '0 2px' : 0 }}>First, verify the proxy chain</strong> — only trust the header when the request originates from a server you control. Second, sign the header server-side so it can't be forged. Third, log every bypass attempt so you can detect probing.
          </p>
        </div>
        <ActionBar active />
      </div>

      <UserMsg dark={dark}>Got it. Show me the patch.</UserMsg>
    </ChatLayout>
  );
}


// ═════════════════════════════════════════════════════════════
// H · THREAD LENGTH MANAGEMENT
// ═════════════════════════════════════════════════════════════

function ChatThreadManagement({ dark, variant = 'collapsed' }) {
  const t = dark ? G.d : G.l;

  return (
    <ChatLayout dark={dark} title="Long architecture discussion">
      {/* Collapsed early messages */}
      {variant === 'collapsed' && (
        <div style={{
          padding: '10px 16px', background: t.surface, border: `1px solid ${t.border}`, borderRadius: 12,
          display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer',
        }}>
          <Icon name="chevronRight" size={13} color={t.fg3} />
          <span style={{ fontSize: 13, color: t.fg2, flex: 1 }}>Collapsed <strong>142</strong> earlier messages</span>
          <Button variant="ghost" size="sm">Expand</Button>
        </div>
      )}

      {/* Compaction prompt */}
      {variant === 'prompt' && (
        <Card style={{ padding: 16, border: `1px solid rgba(254,188,46,0.3)`, background: dark ? 'rgba(254,188,46,0.04)' : 'rgba(254,188,46,0.03)' }}>
          <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12 }}>
            <Icon name="warn" size={18} color="#febc2e" style={{ marginTop: 2 }} />
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 4 }}>Context approaching limit</div>
              <div style={{ fontSize: 13, color: t.fg2, lineHeight: 1.5, marginBottom: 12 }}>
                This thread uses 178k of 200k tokens. Summarizing earlier messages preserves key facts while freeing space. You can expand the originals anytime.
              </div>
              <div style={{ display: 'flex', gap: 8 }}>
                <Button variant="primary" size="sm">Summarize earlier</Button>
                <Button variant="ghost" size="sm">Keep all</Button>
              </div>
            </div>
          </div>
        </Card>
      )}

      {/* Compacted summary card */}
      {variant === 'compacted' && (
        <>
          <div style={{
            padding: '14px 16px', background: t.surface, border: `1px solid ${t.border}`, borderRadius: 12,
            cursor: 'pointer',
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
              <Icon name="archive" size={14} color={t.fg3} />
              <span style={{ fontSize: 12, fontWeight: 600, color: t.fg2 }}>Compacted summary · 142 messages → 1</span>
              <span style={{ flex: 1 }} />
              <Button variant="ghost" size="sm">Expand originals</Button>
            </div>
            <div style={{ fontSize: 13, color: t.fg3, lineHeight: 1.55, fontStyle: 'italic' }}>
              Discussed auth middleware architecture: decided on JWT with opaque session IDs, proxy verification via signed headers, and CSRF tokens on all POST/PUT/DELETE routes. Key decisions: no admin-cookie bypass, all middleware must validate proxy chain, error responses use generic messages. Liu prefers concise code — no comments on obvious lines.
            </div>
          </div>
        </>
      )}

      {/* Recent messages after the fold */}
      <UserMsg dark={dark}>Now let's add rate limiting to the auth endpoints.</UserMsg>
      <AssistantMsg dark={dark}>
        <p style={{ margin: '4px 0 0' }}>Based on our earlier decisions, I'll add a sliding-window rate limiter using Redis. The middleware will sit after auth but before the route handler.</p>
      </AssistantMsg>
    </ChatLayout>
  );
}


// ═════════════════════════════════════════════════════════════
// I · EXPORT / SHARE / FORK
// ═════════════════════════════════════════════════════════════

function ChatExportShare({ dark, variant = 'menu' }) {
  const t = dark ? G.d : G.l;

  return (
    <ChatLayout dark={dark}>
      <UserMsg dark={dark}>Audit the auth middleware.</UserMsg>
      <AssistantMsg dark={dark}>
        <p style={{ margin: '4px 0 0' }}>Found 2 critical issues in auth.ts. Full report attached.</p>
      </AssistantMsg>

      {/* Thread menu dropdown */}
      {variant === 'menu' && (
        <div style={{ position: 'absolute', top: 50, right: 16, zIndex: 20 }}>
          <Glass radius={14} dark={dark} strong style={{ width: 220 }}>
            <div style={{ padding: 6 }}>
              {[
                { icon: 'file', label: 'Export as Markdown' },
                { icon: 'code', label: 'Export as JSON' },
                { icon: 'link', label: 'Create public link' },
                { icon: 'git', label: 'Fork to new thread' },
                { icon: 'download', label: 'Download all files' },
              ].map((item, i) => (
                <div key={i} style={{
                  padding: '8px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', gap: 10,
                  fontSize: 13, cursor: 'pointer', color: t.fg2,
                }}>
                  <Icon name={item.icon} size={14} color={t.fg3} />
                  {item.label}
                </div>
              ))}
            </div>
          </Glass>
        </div>
      )}

      {/* Public link dialog */}
      {variant === 'share-dialog' && (
        <>
          <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.3)', zIndex: 10 }} />
          <div style={{
            position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)',
            width: 440, background: t.surface, border: `1px solid ${t.border}`, borderRadius: 18,
            boxShadow: t.shadowLg, zIndex: 11, padding: '24px 24px 20px',
          }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 18 }}>
              <div style={{ fontSize: 17, fontWeight: 600 }}>Share Thread</div>
              <button style={{ background: 'transparent', border: 'none', color: t.fg3, cursor: 'pointer' }}><Icon name="close" size={18} /></button>
            </div>

            <div style={{ fontSize: 12, fontWeight: 500, color: t.fg2, marginBottom: 6 }}>Public link</div>
            <div style={{
              height: 40, padding: '0 12px', display: 'flex', alignItems: 'center', gap: 8,
              background: t.surface2, border: `1px solid ${t.border}`, borderRadius: 8, marginBottom: 16,
              fontFamily: G.mono, fontSize: 12, color: t.fg2,
            }}>
              https://ghast.ai/s/a3f8c912
              <span style={{ flex: 1 }} />
              <Button variant="ghost" size="sm" icon={<Icon name="copy" size={11} />}>Copy</Button>
            </div>

            <SectionHeader title="Include" dark={dark} small />
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 16 }}>
              {[
                { label: 'User messages', on: true },
                { label: 'Assistant responses', on: true },
                { label: 'Tool call details', on: false },
                { label: 'Thinking blocks', on: false },
                { label: 'Attached files', on: true },
              ].map((item, i) => (
                <div key={i} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', fontSize: 13 }}>
                  <span>{item.label}</span>
                  <Toggle on={item.on} dark={dark} />
                </div>
              ))}
            </div>

            <div style={{ display: 'flex', gap: 14, marginBottom: 16 }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 12, fontWeight: 500, color: t.fg2, marginBottom: 6 }}>Expires</div>
                <div style={{
                  height: 36, padding: '0 12px', display: 'flex', alignItems: 'center',
                  background: t.surface2, border: `1px solid ${t.border}`, borderRadius: 8,
                  fontSize: 12, color: t.fg,
                }}>7 days <span style={{ flex: 1 }} /><Icon name="chevronDown" size={11} color={t.fg3} /></div>
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 12, fontWeight: 500, color: t.fg2, marginBottom: 6 }}>Password</div>
                <div style={{
                  height: 36, padding: '0 12px', display: 'flex', alignItems: 'center',
                  background: t.surface2, border: `1px solid ${t.border}`, borderRadius: 8,
                  fontSize: 12, color: t.fg3,
                }}>Optional…</div>
              </div>
            </div>

            <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
              <Button variant="secondary" size="md">Cancel</Button>
              <Button variant="primary" size="md" icon={<Icon name="link" size={13} color={t.bg} />}>Create link</Button>
            </div>
          </div>
        </>
      )}
    </ChatLayout>
  );
}


// ═════════════════════════════════════════════════════════════
// J · CITATION POPOVER
// ═════════════════════════════════════════════════════════════

function ChatCitations({ dark, variant = 'file' }) {
  const t = dark ? G.d : G.l;

  const citations = {
    file: { type: 'file', icon: 'file', title: 'auth.ts:142', desc: 'The middleware trusts the x-internal-trust header without verifying the proxy chain, allowing any external client to bypass authentication.', source: 'apps/web/middleware/auth.ts', action: 'Open file' },
    web: { type: 'web', icon: 'ext', title: 'OWASP: Broken Access Control', desc: 'Trusting client-supplied headers for authorization decisions is listed as A01:2021 in the OWASP Top 10.', source: 'owasp.org/Top10/A01_2021', action: 'Open page' },
    skill: { type: 'skill', icon: 'skills', title: 'Auth Hardening · Rule #4', desc: 'Always validate proxy chain assertions before trusting X-Forwarded-* or custom internal trust headers.', source: 'Skill: Auth Hardening v1.4', action: 'View skill' },
  };
  const cite = citations[variant];

  return (
    <ChatLayout dark={dark}>
      <UserMsg dark={dark}>What are the security issues in our auth?</UserMsg>
      <AssistantMsg dark={dark}>
        <div style={{ margin: '4px 0 8px', lineHeight: 1.55 }}>
          The main issue is the unverified proxy header bypass
          <span style={{ position: 'relative', display: 'inline' }}>
            <sup style={{ fontSize: 10, fontWeight: 600, color: t.fg, background: t.surface2, padding: '1px 4px', borderRadius: 4, cursor: 'pointer', marginLeft: 2 }}>[1]</sup>

            {/* Citation popover */}
            <div style={{
              position: 'absolute', bottom: 22, left: -20, width: 320, zIndex: 20,
              background: t.surface, border: `1px solid ${t.border}`, borderRadius: 14,
              boxShadow: t.shadowLg, padding: '14px 16px',
            }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
                <div style={{ width: 28, height: 28, borderRadius: 8, background: t.surface2, border: `1px solid ${t.border}`, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <Icon name={cite.icon} size={14} color={t.fg2} />
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 600 }}>{cite.title}</div>
                  <div style={{ fontSize: 10, color: t.fg3, fontFamily: G.mono }}>{cite.source}</div>
                </div>
              </div>
              <div style={{ fontSize: 12, color: t.fg2, lineHeight: 1.55, marginBottom: 12 }}>
                {cite.desc}
              </div>
              <Button variant="secondary" size="sm" icon={<Icon name="ext" size={11} />}>{cite.action}</Button>
              {/* Arrow */}
              <div style={{ position: 'absolute', bottom: -6, left: 32, width: 12, height: 12, background: t.surface, border: `1px solid ${t.border}`, borderTop: 'none', borderLeft: 'none', transform: 'rotate(45deg)' }} />
            </div>
          </span>
          {' '}which violates OWASP A01:2021<sup style={{ fontSize: 10, fontWeight: 600, color: t.fg, background: t.surface2, padding: '1px 4px', borderRadius: 4, cursor: 'pointer', marginLeft: 2 }}>[2]</sup>.
          The Auth Hardening skill flags this pattern specifically<sup style={{ fontSize: 10, fontWeight: 600, color: t.fg, background: t.surface2, padding: '1px 4px', borderRadius: 4, cursor: 'pointer', marginLeft: 2 }}>[3]</sup>.
        </div>
      </AssistantMsg>
    </ChatLayout>
  );
}


// ═════════════════════════════════════════════════════════════
// K · PROVIDER/MODEL SWITCHER
// ═════════════════════════════════════════════════════════════

function ChatModelSwitcher({ dark, variant = 'open' }) {
  const t = dark ? G.d : G.l;
  const isOverride = variant === 'override';

  return (
    <ChatLayout dark={dark} title="New thread" composerProps={false}>
      <div style={{ flex: 1 }} />
      <div style={{ padding: '0 24px 20px', position: 'relative' }}>
        <Glass radius={20} dark={dark} style={{ background: 'transparent' }}>
          <div style={{ padding: '14px 14px 10px', display: 'flex', flexDirection: 'column', gap: 10 }}>
            <div style={{ minHeight: 28, fontSize: 14, color: t.fg3, padding: '4px 4px' }}>Ask, build, or run...</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
              <button style={{ width: 30, height: 30, borderRadius: 8, background: 'transparent', border: 'none', color: t.fg2, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Icon name="paperclip" size={15} /></button>
              <button style={{ width: 30, height: 30, borderRadius: 8, background: 'transparent', border: 'none', color: t.fg2, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Icon name="image" size={15} /></button>
              <button style={{ width: 30, height: 30, borderRadius: 8, background: 'transparent', border: 'none', color: t.fg2, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Icon name="mic" size={15} /></button>
              <Divider vertical style={{ height: 16, margin: '0 4px' }} />
              <Tag variant={isOverride ? 'solid' : 'outline'} style={{ height: 24, gap: 4, cursor: 'pointer' }}>
                <Icon name="sparkle" size={11} /> {isOverride ? 'GPT-5 (override)' : 'Ghast 2 Pro'} <Icon name="chevronDown" size={10} />
              </Tag>
              <div style={{ flex: 1 }} />
              <button style={{ width: 32, height: 32, borderRadius: 16, background: t.surface2, color: t.fg3, border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <Icon name="arrowUp" size={16} color={t.fg3} />
              </button>
            </div>
          </div>
        </Glass>

        {/* Model selector dropdown */}
        {(variant === 'open') && (
          <div style={{
            position: 'absolute', bottom: 70, left: 120, width: 320, zIndex: 20,
          }}>
            <Glass radius={14} dark={dark} strong style={{ width: '100%' }}>
              <div style={{ padding: 6 }}>
                <div style={{ padding: '6px 10px', fontSize: 10, fontWeight: 600, color: t.fg3, letterSpacing: 0.6 }}>DEFAULT</div>
                <div style={{ padding: '8px 10px', borderRadius: 8, background: t.surface2, display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
                  <Icon name="sparkle" size={13} color={t.fg} />
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 13, fontWeight: 500 }}>Ghast 2 Pro</div>
                    <div style={{ fontSize: 10, color: t.fg3 }}>200k context · vision · tools</div>
                  </div>
                  <Icon name="check" size={13} color={t.fg} />
                </div>

                {[
                  { provider: 'Anthropic', models: [
                    { name: 'claude-4-sonnet', cost: '$$$', latency: 'Fast' },
                    { name: 'claude-3.5-sonnet', cost: '$$', latency: 'Fast' },
                  ]},
                  { provider: 'OpenAI', models: [
                    { name: 'gpt-5', cost: '$$$', latency: 'Med' },
                    { name: 'o3', cost: '$$$$', latency: 'Slow' },
                  ]},
                  { provider: 'Local', models: [
                    { name: 'llama-3.3-70b', cost: 'Free', latency: 'Fast' },
                  ]},
                ].map((group, gi) => (
                  <React.Fragment key={gi}>
                    <div style={{ padding: '10px 10px 4px', fontSize: 10, fontWeight: 600, color: t.fg3, letterSpacing: 0.6 }}>{group.provider.toUpperCase()}</div>
                    {group.models.map((m, mi) => (
                      <div key={mi} style={{ padding: '7px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer' }}>
                        <Icon name="sparkle" size={13} color={t.fg3} />
                        <div style={{ flex: 1 }}>
                          <div style={{ fontSize: 12, fontFamily: G.mono }}>{m.name}</div>
                        </div>
                        <Tag style={{ height: 18, fontSize: 9 }}>{m.cost}</Tag>
                        <span style={{ fontSize: 10, color: t.fg3, width: 32, textAlign: 'right' }}>{m.latency}</span>
                      </div>
                    ))}
                  </React.Fragment>
                ))}

                <Divider style={{ margin: '6px 10px', width: 'auto' }} />
                <div style={{ padding: '6px 10px', fontSize: 10, fontWeight: 600, color: t.fg3, letterSpacing: 0.6 }}>TOOL MODEL</div>
                <div style={{ padding: '7px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer' }}>
                  <Icon name="bolt" size={13} color={t.fg3} />
                  <span style={{ fontSize: 12, fontFamily: G.mono, flex: 1 }}>gpt-5</span>
                  <span style={{ fontSize: 10, color: t.fg3 }}>for agentic tasks</span>
                </div>

                <Divider style={{ margin: '6px 10px', width: 'auto' }} />
                <div style={{ padding: '7px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer', fontSize: 12, color: t.fg2 }}>
                  <Icon name="settings" size={13} color={t.fg3} />
                  Per-message override
                  <span style={{ flex: 1 }} />
                  <Toggle on={false} dark={dark} />
                </div>
              </div>
            </Glass>
          </div>
        )}
      </div>
    </ChatLayout>
  );
}


// ═════════════════════════════════════════════════════════════
// L · EMPTY THREAD GUIDE (no provider)
// ═════════════════════════════════════════════════════════════

function ChatEmptyGuide({ dark }) {
  const t = dark ? G.d : G.l;

  const providers = [
    { name: 'Anthropic', sub: 'Claude 4 Sonnet', icon: 'A', color: '#d97706' },
    { name: 'OpenAI', sub: 'GPT-5', icon: 'O', color: '#10a37f' },
    { name: 'Ollama', sub: 'Local · no API key', icon: '🦙', color: '#666' },
    { name: 'Other', sub: '12+ providers', icon: '⚙', color: t.fg2 },
  ];

  return (
    <AppShell dark={dark} active="chat" sidebar={chatSidebar(dark)}
      topBar={<AppTopBar dark={dark} breadcrumbs={['Chat', 'New thread']} />}
    >
      <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 32 }}>
          {/* Banner overlay */}
          <Card style={{
            padding: 28, maxWidth: 520, textAlign: 'center', width: '100%',
            border: `1px solid rgba(254,188,46,0.3)`,
            background: dark ? 'rgba(254,188,46,0.04)' : 'rgba(254,188,46,0.03)',
          }}>
            <Icon name="warn" size={28} color="#febc2e" style={{ marginBottom: 12 }} />
            <div style={{ fontSize: 18, fontWeight: 600, marginBottom: 4 }}>Configure a provider to start</div>
            <div style={{ fontSize: 13, color: t.fg2, lineHeight: 1.5, marginBottom: 24 }}>
              Ghast needs at least one AI provider. Pick one below to get started — you can add more later in Settings.
            </div>

            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 10, textAlign: 'left' }}>
              {providers.map((p, i) => (
                <div key={i} style={{
                  padding: 14, background: t.surface, border: `1px solid ${t.border}`, borderRadius: 12,
                  display: 'flex', alignItems: 'center', gap: 12, cursor: 'pointer',
                }}>
                  <div style={{
                    width: 36, height: 36, borderRadius: 10, background: p.color + '18',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontSize: 16, fontWeight: 600, fontFamily: G.mono,
                  }}>{p.icon}</div>
                  <div>
                    <div style={{ fontSize: 13, fontWeight: 600 }}>{p.name}</div>
                    <div style={{ fontSize: 11, color: t.fg3 }}>{p.sub}</div>
                  </div>
                </div>
              ))}
            </div>

            <div style={{ marginTop: 16 }}>
              <Button variant="ghost" size="sm">Skip — I'll configure later in Settings →</Button>
            </div>
          </Card>
        </div>
        <Composer dark={dark} large />
      </div>
    </AppShell>
  );
}

Object.assign(window, {
  ChatComposerMic, ChatSpeakButton,
  ChatThreadManagement,
  ChatExportShare,
  ChatCitations,
  ChatModelSwitcher,
  ChatEmptyGuide,
});
