// Órbita — New Session Upload + Processing screens

const ACCEPTED_EXTS = ['txt', 'docx'];
const MAX_MB = 10;

// Espelha lib/storage.ts (AUDIO_EXTENSIONS) — o servidor é a fonte da verdade
// no tamanho (AUDIO_MAX_MB), aqui é só pra orientar antes do upload.
// Só áudio. Quem tem um .mp4 apenas de áudio pode renomear pra .m4a (mesmo contêiner).
const AUDIO_ACCEPTED_EXTS = ['mp3', 'mpeg', 'mpga', 'm4a', 'aac', 'wav', 'ogg', 'opus', 'flac'];
const AUDIO_MAX_MB = 500;

const formatDuration = (totalSeconds) => {
  const s = Math.max(0, Math.round(totalSeconds || 0));
  const m = Math.floor(s / 60);
  const r = s % 60;
  return `${m}min${r ? ` ${r}s` : ''}`;
};

const NewSessionScreen = ({ onBack, onSubmit, quotaExceeded = false, trialStatus = null, onUpgrade, initialDraft = null }) => {
  // Volta de uma falha no processamento: repõe texto, consulente e objetivos.
  // Áudio volta como transcrição pronta — não sobe nem transcreve de novo.
  const draftIsAudio = initialDraft?.source_type === 'audio';
  const draftName = initialDraft?.consulente?.name || '';
  const [sourceType, setSourceType] = React.useState(draftIsAudio ? 'audio' : 'transcript');
  const [transcript, setTranscript] = React.useState(initialDraft?.transcript || '');
  const [fileName, setFileName] = React.useState(null);
  const [uploadError, setUploadError] = React.useState(null);
  const [extracting, setExtracting] = React.useState(false);
  const [dragging, setDragging] = React.useState(false);
  const [objectives, setObjectives] = React.useState(initialDraft?.objetivos || '');
  const [yearStart, setYearStart] = React.useState(initialDraft?.year_start || '');
  const [submitting, setSubmitting] = React.useState(false);
  const fileInputRef = React.useRef(null);

  // Consulentes reais (CRM já existe em /api/consulentes — antes disso, esta
  // tela lia de window.ORBITA_DATA e nunca mandava consulente_id de verdade
  // pro motor, deixando a leitura solta do CRM e o check-in sem dono).
  const [consulentes, setConsulentes] = React.useState([]);
  const [loadingConsulentes, setLoadingConsulentes] = React.useState(true);
  const [consulentesError, setConsulentesError] = React.useState(null);
  const [consulenteId, setConsulenteId] = React.useState('');
  const [newName, setNewName] = React.useState('');
  const [newBirthDate, setNewBirthDate] = React.useState('');
  const [isNewConsulente, setIsNewConsulente] = React.useState(false);

  React.useEffect(() => {
    let cancelled = false;
    fetch('/api/consulentes')
      .then(res => res.json().catch(() => ({})).then(data => { if (!res.ok) throw new Error(data.error || 'Não foi possível carregar as consulentes.'); return data; }))
      .then(data => {
        if (cancelled) return;
        const list = data.consulentes || [];
        setConsulentes(list);
        const match = draftName ? list.find(c => c.name === draftName) : null;
        if (match) { setConsulenteId(match.id); setIsNewConsulente(false); }
        else if (draftName) { setNewName(draftName); setIsNewConsulente(true); }
        else if (list[0]) { setConsulenteId(list[0].id); }
      })
      .catch(err => { if (!cancelled) setConsulentesError(err.message || 'Falha de rede ao carregar consulentes.'); })
      .finally(() => { if (!cancelled) setLoadingConsulentes(false); });
    return () => { cancelled = true; };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Áudio: 'idle' → 'uploading' (Storage) → 'transcribing' (Groq) → 'done' | 'error'.
  const [audioPhase, setAudioPhase] = React.useState(draftIsAudio ? 'done' : 'idle');
  const [audioFileName, setAudioFileName] = React.useState(draftIsAudio ? 'Transcrição do áudio' : null);
  const [audioError, setAudioError] = React.useState(null);
  const [audioWarnings, setAudioWarnings] = React.useState([]);
  const [audioMeta, setAudioMeta] = React.useState(null);
  const audioInputRef = React.useRef(null);

  // Lê o arquivo de verdade: .txt no browser, .docx no servidor (mammoth só roda em Node).
  const readFile = async (file) => {
    const ext = file.name.split('.').pop().toLowerCase();
    if (!ACCEPTED_EXTS.includes(ext)) {
      setUploadError(`Formato .${ext} não suportado. Envie .txt ou .docx.`);
      setFileName(null);
      return;
    }
    if (file.size / (1024 * 1024) > MAX_MB) {
      setUploadError(`Arquivo muito grande (máx ${MAX_MB}MB).`);
      setFileName(null);
      return;
    }
    setUploadError(null);
    setFileName(file.name);
    setExtracting(true);
    try {
      let text;
      if (ext === 'txt') {
        text = await file.text();
      } else {
        const form = new FormData();
        form.append('file', file);
        const res = await fetch('/api/upload-text', { method: 'POST', body: form });
        const data = await res.json().catch(() => ({}));
        if (!res.ok) throw new Error(data.error || `Erro ${res.status} ao ler o arquivo.`);
        text = data.text;
      }
      setTranscript(text || '');
      if (!text || text.trim().length < 200) {
        setUploadError('O arquivo tem pouco texto (mínimo 200 caracteres). Confira o conteúdo ou cole a transcrição abaixo.');
      }
    } catch (err) {
      setUploadError(err.message || 'Falha ao ler o arquivo.');
      setFileName(null);
    } finally {
      setExtracting(false);
    }
  };

  const handleDrop = (e) => {
    e.preventDefault(); setDragging(false);
    const file = e.dataTransfer?.files?.[0];
    if (file) readFile(file);
  };
  const handleFilePick = (e) => {
    const file = e.target.files?.[0];
    if (file) readFile(file);
    e.target.value = '';
  };

  // Sobe o áudio direto pro Storage (URL assinada) e manda transcrever. O
  // arquivo não passa pelo Vercel — só o texto que sai da transcrição.
  const processAudioFile = async (file) => {
    const ext = file.name.split('.').pop().toLowerCase();
    if (!AUDIO_ACCEPTED_EXTS.includes(ext)) {
      setAudioError(`Formato .${ext} não suportado. Envie ${AUDIO_ACCEPTED_EXTS.map(e => `.${e}`).join(', ')}.`);
      setAudioPhase('error');
      return;
    }
    if (file.size / (1024 * 1024) > AUDIO_MAX_MB) {
      setAudioError(`Arquivo com ${(file.size / 1048576).toFixed(1)}MB — o limite é ${AUDIO_MAX_MB}MB.`);
      setAudioPhase('error');
      return;
    }
    setAudioFileName(file.name);
    setAudioError(null);
    setAudioWarnings([]);
    setAudioMeta(null);
    setTranscript('');
    setAudioPhase('uploading');
    try {
      const signRes = await fetch('/api/audio/upload-url', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ filename: file.name, size: file.size }),
      });
      const signData = await signRes.json().catch(() => ({}));
      if (!signRes.ok) throw new Error(signData.error || `Erro ${signRes.status} ao preparar o envio.`);

      const putRes = await fetch(signData.upload_url, {
        method: 'PUT',
        headers: { 'Content-Type': signData.content_type },
        body: file,
      });
      if (!putRes.ok) throw new Error(`Falha ao enviar o áudio (${putRes.status}). Tente de novo.`);

      setAudioPhase('transcribing');
      const transcribeRes = await fetch('/api/audio/transcribe', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ path: signData.path }),
      });
      const result = await transcribeRes.json().catch(() => ({}));
      if (!transcribeRes.ok) throw new Error(result.error || `Erro ${transcribeRes.status} na transcrição.`);

      setTranscript(result.transcript || '');
      setAudioWarnings(result.warnings || []);
      setAudioMeta({ duration_s: result.duration_s, chunks: result.chunks });
      setAudioPhase('done');
    } catch (err) {
      setAudioError(err.message || 'Falha ao processar o áudio.');
      setAudioPhase('error');
    }
  };

  const handleAudioDrop = (e) => {
    e.preventDefault(); setDragging(false);
    const file = e.dataTransfer?.files?.[0];
    if (file) processAudioFile(file);
  };
  const handleAudioPick = (e) => {
    const file = e.target.files?.[0];
    if (file) processAudioFile(file);
    e.target.value = '';
  };

  const charCount = transcript.length;
  const trialExceeded = Boolean(trialStatus && trialStatus.exhausted);
  const blocked = quotaExceeded || trialExceeded;
  const canSubmit = !blocked && !submitting && charCount >= 200 && yearStart
    && (isNewConsulente ? newName.trim() : consulenteId);

  // Cria a consulente nova (se for o caso) antes de mandar pro motor, pra
  // sempre existir um consulente_id real — sem isso a leitura fica solta do
  // CRM e o check-in do portal não sabe de quem é (P0-2 do service blueprint).
  const handleSubmit = async () => {
    if (!canSubmit) return;
    setSubmitting(true);
    setUploadError(null);
    try {
      let consulente_id = consulenteId;
      let consulenteSnapshot = consulentes.find(c => c.id === consulenteId) || null;
      if (isNewConsulente) {
        const res = await fetch('/api/consulentes', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ name: newName.trim(), birth_date: newBirthDate || undefined }),
        });
        const data = await res.json().catch(() => ({}));
        if (!res.ok || !data.consulente) throw new Error(data.error || 'Não foi possível criar a consulente.');
        consulente_id = data.consulente.id;
        consulenteSnapshot = data.consulente;
      }
      onSubmit({
        transcript,
        consulente: consulenteSnapshot
          ? { name: consulenteSnapshot.name, birth_date: consulenteSnapshot.birth_date, birth_city: consulenteSnapshot.birth_city, birth_time: consulenteSnapshot.birth_time }
          : { name: newName.trim() },
        consulente_id,
        year_start: yearStart,
        objetivos: objectives || undefined,
        source_type: sourceType,
      });
    } catch (err) {
      setUploadError(err.message || 'Falha ao preparar a sessão.');
      setSubmitting(false);
    }
  };

  return (
    <div style={{ minHeight: '100vh', background: T.bg, fontFamily: 'Inter, sans-serif', color: T.fg }}>
      <GrainOverlay />
      {/* Header — tarefa focada: só "← Painel" + título */}
      <header style={{
        position: 'sticky', top: 0, zIndex: 100,
        background: 'rgba(16,13,10,0.85)', backdropFilter: 'blur(16px)',
        borderBottom: `1px solid ${T.border}`,
        padding: '0 32px', height: 60,
        display: 'flex', alignItems: 'center', gap: 16,
      }}>
        <button onClick={onBack} style={{ background: 'none', border: 'none', color: T.fgMuted, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 6, fontSize: 13, padding: 0 }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M15 18l-6-6 6-6"/></svg>
          Painel
        </button>
        <span style={{ color: T.fgDim }}>·</span>
        <span style={{ fontSize: 14, color: T.fg }}>Nova sessão</span>
      </header>

      <div className="orbita-page" style={{ maxWidth: 680, margin: '0 auto', padding: '48px 32px 100px' }}>
        <div style={{ marginBottom: 40 }}>
          <h1 style={{ margin: '0 0 8px', fontSize: 28, fontFamily: '"Instrument Serif", serif', fontWeight: 400, letterSpacing: '-0.01em' }}>
            Nova sessão
          </h1>
          <p style={{ margin: 0, fontSize: 14, color: T.fgMuted }}>
            Cole a transcrição, envie um arquivo .txt/.docx ou suba o áudio da consulta. A IA vai extrair os temas e montar o painel anual.
          </p>
        </div>

        {blocked && (
          <div style={{
            display: 'flex', gap: 14, alignItems: 'flex-start', padding: '16px 18px', borderRadius: 14,
            background: 'rgba(231,111,81,0.08)', border: `1px solid rgba(231,111,81,0.3)`, marginBottom: 24,
          }}>
            <div style={{ fontSize: 20, lineHeight: 1 }}>⚠</div>
            <div style={{ flex: 1 }}>
              {trialExceeded ? (
                <>
                  <div style={{ fontSize: 14, fontWeight: 600, color: T.hot, marginBottom: 4 }}>Seu teste grátis acabou</div>
                  <div style={{ fontSize: 13, color: T.fgMuted }}>
                    {trialStatus.reason === 'sessoes'
                      ? `Você usou as ${trialStatus.limits.sessions} sessões gratuitas do teste.`
                      : `Seus ${trialStatus.limits.days} dias de teste terminaram.`} Escolha um plano para continuar processando sessões.
                  </div>
                </>
              ) : (
                <>
                  <div style={{ fontSize: 14, fontWeight: 600, color: T.hot, marginBottom: 4 }}>Limite de sessões do plano atingido</div>
                  <div style={{ fontSize: 13, color: T.fgMuted }}>Você usou as 25 sessões do plano Atelier neste mês. Faça upgrade para continuar processando novas sessões.</div>
                </>
              )}
            </div>
            <button onClick={onUpgrade} style={{
              flexShrink: 0, padding: '9px 16px', borderRadius: 999, border: 'none', cursor: 'pointer',
              background: T.hot, color: '#100D0A', fontSize: 12, fontWeight: 600, fontFamily: 'Inter, sans-serif',
            }}>{trialExceeded ? 'Escolher plano →' : 'Fazer upgrade →'}</button>
          </div>
        )}

        {initialDraft && (
          <div style={{
            display: 'flex', gap: 12, alignItems: 'flex-start', padding: '14px 16px', borderRadius: 12,
            background: 'rgba(122,158,201,0.08)', border: `1px solid rgba(122,158,201,0.25)`, marginBottom: 24,
          }}>
            <div style={{ fontSize: 16, lineHeight: 1, color: T.info }}>ⓘ</div>
            <div style={{ fontSize: 13, color: T.fgMuted, lineHeight: 1.5 }}>
              O processamento anterior falhou. O texto enviado foi mantido — revise e processe de novo.
            </div>
          </div>
        )}

        <div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
          {/* Source type toggle */}
          <div>
            <label style={{ fontSize: 12, fontWeight: 500, color: T.fgMuted, letterSpacing: '0.02em', display: 'block', marginBottom: 10 }}>Tipo de entrada</label>
            <div style={{ display: 'flex', gap: 10 }}>
              {[{ id: 'transcript', label: '📄 Transcrição (texto)' }, { id: 'audio', label: '🎙 Áudio' }].map(opt => (
                <button key={opt.id} onClick={() => setSourceType(opt.id)} style={{
                  flex: 1, padding: '12px 16px', borderRadius: 12, fontSize: 13, fontFamily: 'Inter, sans-serif',
                  background: sourceType === opt.id ? T.accent + '1F' : 'rgba(245,241,232,0.04)',
                  border: `1px solid ${sourceType === opt.id ? T.accent + '59' : T.border}`,
                  color: sourceType === opt.id ? T.accent : T.fgMuted,
                  cursor: 'pointer', transition: 'all 0.15s', textAlign: 'left',
                }}>
                  {opt.label}
                </button>
              ))}
            </div>
          </div>

          {sourceType === 'audio' ? (
            <>
              <div
                onDragOver={e => { e.preventDefault(); if (audioPhase === 'idle' || audioPhase === 'error') setDragging(true); }}
                onDragLeave={() => setDragging(false)}
                onDrop={e => { if (audioPhase === 'idle' || audioPhase === 'error') handleAudioDrop(e); else e.preventDefault(); }}
                onClick={() => (audioPhase === 'idle' || audioPhase === 'error' || audioPhase === 'done') && audioInputRef.current && audioInputRef.current.click()}
                style={{
                  borderRadius: 16,
                  border: `2px dashed ${dragging ? T.accent : audioPhase === 'error' ? T.hot : audioPhase === 'done' ? T.success : T.border}`,
                  padding: '32px 24px', textAlign: 'center',
                  cursor: audioPhase === 'uploading' || audioPhase === 'transcribing' ? 'default' : 'pointer',
                  background: dragging ? T.accent + '0D' : audioPhase === 'error' ? 'rgba(231,111,81,0.05)' : audioPhase === 'done' ? 'rgba(140,175,136,0.05)' : 'rgba(245,241,232,0.02)',
                  transition: 'all 0.2s',
                }}
              >
                <input ref={audioInputRef} type="file" accept={AUDIO_ACCEPTED_EXTS.map(e => `.${e}`).join(',')} onChange={handleAudioPick} style={{ display: 'none' }} />
                {audioPhase === 'uploading' ? (
                  <>
                    <div style={{ fontSize: 26, marginBottom: 8 }}>…</div>
                    <div style={{ fontSize: 14, color: T.fgMuted }}>Enviando {audioFileName}…</div>
                  </>
                ) : audioPhase === 'transcribing' ? (
                  <>
                    <div style={{ fontSize: 26, marginBottom: 8 }}>…</div>
                    <div style={{ fontSize: 14, color: T.fgMuted }}>Transcrevendo áudio — pode levar alguns minutos…</div>
                  </>
                ) : audioPhase === 'error' ? (
                  <>
                    <div style={{ fontSize: 28, marginBottom: 10 }}>✕</div>
                    <div style={{ fontSize: 14, fontWeight: 500, color: T.hot, marginBottom: 4 }}>Falha na transcrição</div>
                    <div style={{ fontSize: 12, color: T.fgMuted }}>{audioError}</div>
                    <div style={{ fontSize: 11, color: T.fgDim, marginTop: 6 }}>Clique para tentar de novo</div>
                  </>
                ) : audioPhase === 'done' ? (
                  <>
                    <div style={{ fontSize: 28, marginBottom: 10 }}>✓</div>
                    <div style={{ fontSize: 14, fontWeight: 500, color: T.success, marginBottom: 4 }}>{audioFileName}</div>
                    <div style={{ fontSize: 12, color: T.fgMuted }}>
                      {audioMeta && `${formatDuration(audioMeta.duration_s)} transcritos`}
                      {audioMeta?.chunks > 1 ? ` · ${audioMeta.chunks} partes` : ''}
                      {' · clique para trocar o áudio'}
                    </div>
                  </>
                ) : (
                  <>
                    <div style={{ fontSize: 28, marginBottom: 12, opacity: 0.4 }}>🎙</div>
                    <div style={{ fontSize: 14, fontWeight: 500, marginBottom: 4 }}>Arraste ou clique para enviar o áudio</div>
                    <div style={{ fontSize: 12, color: T.fgMuted }}>{AUDIO_ACCEPTED_EXTS.slice(0, 5).map(e => `.${e.toUpperCase()}`).join(', ')} e outros, máx {AUDIO_MAX_MB}MB</div>
                  </>
                )}
              </div>

              {audioPhase === 'done' && (
                <>
                  <Textarea
                    label="Revise a transcrição antes de processar"
                    value={transcript}
                    onChange={e => setTranscript(e.target.value)}
                    placeholder="Transcrição gerada pela IA…"
                    rows={8}
                  />
                  <div style={{ fontSize: 11, color: charCount > 0 && charCount < 200 ? T.hot : T.fgDim, marginTop: -14 }}>
                    {charCount.toLocaleString('pt-BR')} caracteres{charCount < 200 ? ' · mínimo 200' : ''}
                  </div>
                  {audioWarnings.length > 0 && (
                    <div style={{
                      display: 'flex', gap: 12, alignItems: 'flex-start', padding: '12px 14px', borderRadius: 12,
                      background: 'rgba(122,158,201,0.08)', border: `1px solid rgba(122,158,201,0.25)`,
                    }}>
                      <div style={{ fontSize: 16, lineHeight: 1, color: T.info }}>ⓘ</div>
                      <div style={{ fontSize: 12, color: T.fgMuted, lineHeight: 1.5 }}>
                        {audioWarnings.map((w, i) => <div key={i}>{w}</div>)}
                      </div>
                    </div>
                  )}
                </>
              )}
            </>
          ) : (
            <>
              {/* Drop zone */}
              <div
                onDragOver={e => { e.preventDefault(); setDragging(true); }}
                onDragLeave={() => setDragging(false)}
                onDrop={handleDrop}
                onClick={() => fileInputRef.current && fileInputRef.current.click()}
                style={{
                  borderRadius: 16, border: `2px dashed ${dragging ? T.accent : uploadError ? T.hot : fileName ? T.success : T.border}`,
                  padding: '32px 24px', textAlign: 'center', cursor: 'pointer',
                  background: dragging ? T.accent + '0D' : uploadError ? 'rgba(231,111,81,0.05)' : fileName ? 'rgba(140,175,136,0.05)' : 'rgba(245,241,232,0.02)',
                  transition: 'all 0.2s',
                }}
              >
                <input ref={fileInputRef} type="file" accept=".txt,.docx" onChange={handleFilePick} style={{ display: 'none' }} />
                {extracting ? (
                  <>
                    <div style={{ fontSize: 26, marginBottom: 8 }}>…</div>
                    <div style={{ fontSize: 14, color: T.fgMuted }}>Lendo {fileName}…</div>
                  </>
                ) : uploadError ? (
                  <>
                    <div style={{ fontSize: 28, marginBottom: 10 }}>✕</div>
                    <div style={{ fontSize: 14, fontWeight: 500, color: T.hot, marginBottom: 4 }}>{fileName ? 'Arquivo com problema' : 'Falha no envio'}</div>
                    <div style={{ fontSize: 12, color: T.fgMuted }}>{uploadError}</div>
                    <div style={{ fontSize: 11, color: T.fgDim, marginTop: 6 }}>Clique para tentar de novo</div>
                  </>
                ) : fileName ? (
                  <>
                    <div style={{ fontSize: 28, marginBottom: 10 }}>✓</div>
                    <div style={{ fontSize: 14, fontWeight: 500, color: T.success, marginBottom: 4 }}>{fileName}</div>
                    <div style={{ fontSize: 12, color: T.fgMuted }}>{charCount.toLocaleString('pt-BR')} caracteres · clique para trocar o arquivo</div>
                  </>
                ) : (
                  <>
                    <div style={{ fontSize: 28, marginBottom: 12, opacity: 0.4 }}>📄</div>
                    <div style={{ fontSize: 14, fontWeight: 500, marginBottom: 4 }}>Arraste ou clique para enviar</div>
                    <div style={{ fontSize: 12, color: T.fgMuted }}>.TXT ou .DOCX, máx {MAX_MB}MB</div>
                  </>
                )}
              </div>

              <Textarea
                label="Ou cole a transcrição aqui"
                value={transcript}
                onChange={e => { setTranscript(e.target.value); setFileName(null); setUploadError(null); }}
                placeholder="Cole aqui o texto da consulta…"
                rows={8}
              />
              <div style={{ fontSize: 11, color: charCount > 0 && charCount < 200 ? T.hot : T.fgDim, marginTop: -14 }}>
                {charCount.toLocaleString('pt-BR')} caracteres{charCount < 200 ? ' · mínimo 200' : ''}
              </div>
            </>
          )}

          {/* Consulente — lista real de /api/consulentes, não mock. Sem isso a
              leitura fica solta do CRM e o check-in do portal não sabe de quem é. */}
          <div>
            <label style={{ fontSize: 12, fontWeight: 500, color: T.fgMuted, letterSpacing: '0.02em', display: 'block', marginBottom: 10 }}>Consulente</label>
            {loadingConsulentes ? (
              <p style={{ margin: 0, fontSize: 13, color: T.fgMuted }}>Carregando consulentes…</p>
            ) : consulentesError ? (
              <p style={{ margin: 0, fontSize: 13, color: T.hot }}>{consulentesError}</p>
            ) : (
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                {/* Existing */}
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                  {consulentes.map(c => (
                    <button key={c.id} onClick={() => { setConsulenteId(c.id); setIsNewConsulente(false); }} style={{
                      padding: '8px 14px', borderRadius: 999, fontSize: 13, fontFamily: 'Inter, sans-serif',
                      background: consulenteId === c.id && !isNewConsulente ? T.accent + '24' : 'rgba(245,241,232,0.04)',
                      border: `1px solid ${consulenteId === c.id && !isNewConsulente ? T.accent + '59' : T.border}`,
                      color: consulenteId === c.id && !isNewConsulente ? T.accent : T.fgMuted,
                      cursor: 'pointer', transition: 'all 0.15s',
                    }}>
                      {c.name}
                    </button>
                  ))}
                  <button onClick={() => setIsNewConsulente(true)} style={{
                    padding: '8px 14px', borderRadius: 999, fontSize: 13, fontFamily: 'Inter, sans-serif',
                    background: isNewConsulente ? 'rgba(122,158,201,0.12)' : 'rgba(245,241,232,0.04)',
                    border: `1px solid ${isNewConsulente ? 'rgba(122,158,201,0.35)' : T.border}`,
                    color: isNewConsulente ? T.info : T.fgMuted,
                    cursor: 'pointer', transition: 'all 0.15s',
                  }}>
                    + Nova consulente
                  </button>
                </div>
                {isNewConsulente && (
                  <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                    <Input placeholder="Nome completo da consulente" value={newName} onChange={e => setNewName(e.target.value)} style={{ flex: 2, minWidth: 200 }} />
                    <Input label={null} type="date" value={newBirthDate} onChange={e => setNewBirthDate(e.target.value)} style={{ flex: 1, minWidth: 160 }} />
                  </div>
                )}
              </div>
            )}
          </div>

          {/* Início do ciclo — o "ano solar" da consulente (aniversário astrológico).
              Sem essa data o portal não sabe calcular o mês atual do ciclo. */}
          <Input
            label="Início do ciclo (aniversário astrológico)"
            type="date"
            value={yearStart}
            onChange={e => setYearStart(e.target.value)}
          />

          {/* Objectives */}
          <Textarea
            label="Objetivos ou contexto (opcional)"
            value={objectives}
            onChange={e => setObjectives(e.target.value)}
            placeholder="Ex: Consulente quer focar em carreira e relacionamentos. Está passando por transição profissional..."
            rows={3}
          />

          {/* Submit */}
          <div style={{ display: 'flex', gap: 12, paddingTop: 8 }}>
            <BtnGhost onClick={onBack} style={{ flex: 1 }}>Cancelar</BtnGhost>
            <BtnPrimary onClick={handleSubmit} disabled={!canSubmit} style={{ flex: 2 }}>
              {submitting ? 'Preparando…' : 'Processar sessão →'}
            </BtnPrimary>
          </div>
        </div>
      </div>
    </div>
  );
};

// ── Processing Screen — reflete o estado real da chamada ao motor ─────────
// (status vem de cima: 'running' enquanto POST /api/extract está em voo,
// 'done'/'error' quando resolve). Sem timers fingindo etapas que não existem.
const ProcessingScreen = ({ status = 'running', errorMessage, leitura, onReady, onBackToUpload, onRetry = null }) => {
  const [progress, setProgress] = React.useState(10);
  const failed = status === 'error';
  const done = status === 'done';

  React.useEffect(() => {
    if (status !== 'running') return;
    setProgress(10); // "Tentar de novo" recomeça a barra
    const t = setInterval(() => {
      setProgress(p => (p < 92 ? p + (92 - p) * 0.05 : p));
    }, 180);
    return () => clearInterval(t);
  }, [status]);

  React.useEffect(() => {
    if (done) setProgress(100);
  }, [done]);

  const steps = [
    { id: 'send', label: 'Enviando transcrição' },
    { id: 'extract', label: 'Extraindo leitura estruturada com IA', detail: 'O motor lê a transcrição e monta tema, meses, alertas e cards — pode levar até um minuto.' },
    { id: 'ready', label: 'Pronto para revisão' },
  ];
  const currentStep = done || failed ? (failed ? 1 : 2) : (status === 'running' ? 1 : 0);

  return (
    <div style={{
      minHeight: '100vh', background: T.bg, fontFamily: 'Inter, sans-serif', color: T.fg,
      display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '32px 20px',
    }}>
      <GrainOverlay />
      <RadialGlow opacity={0.12} top="-120px" />

      <div style={{ width: '100%', maxWidth: 480, position: 'relative', zIndex: 1 }}>
        {/* Orbital animation */}
        <div style={{ textAlign: 'center', marginBottom: 48 }}>
          <div style={{ position: 'relative', display: 'inline-block', width: 96, height: 96 }}>
            <svg width="96" height="96" viewBox="0 0 96 96" style={{ animation: 'spin 8s linear infinite' }}>
              <circle cx="48" cy="48" r="40" stroke={T.accent} strokeWidth="1" opacity="0.2" fill="none" strokeDasharray="4 8" />
            </svg>
            <svg width="96" height="96" viewBox="0 0 96 96" style={{ position: 'absolute', top: 0, left: 0, animation: 'spin 3.5s linear infinite reverse' }}>
              <circle cx="48" cy="48" r="28" stroke={T.info} strokeWidth="1" opacity="0.3" fill="none" strokeDasharray="3 6" />
            </svg>
            <div style={{
              position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%,-50%)',
              width: 20, height: 20, borderRadius: '50%', background: T.accent,
              boxShadow: `0 0 20px ${T.accent}80`,
            }} />
          </div>
        </div>

        <Card hover={false} style={{ padding: 32 }}>
          <div style={{ marginBottom: 28 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
              <span style={{ fontSize: 13, color: T.fgMuted }}>
                {failed ? 'Processamento interrompido' : done ? 'Concluído' : 'Processando sessão…'}
              </span>
              <span style={{ fontSize: 13, color: T.accent, fontWeight: 500 }}>{Math.round(progress)}%</span>
            </div>
            <div style={{ height: 4, background: T.border, borderRadius: 999, overflow: 'hidden' }}>
              <div style={{
                height: '100%', borderRadius: 999, transition: 'width 0.3s ease',
                width: `${progress}%`,
                background: failed ? T.hot : T.accent,
              }} />
            </div>
          </div>

          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            {steps.map((step, i) => {
              if (failed && i > currentStep) return null;
              const isActive = i === currentStep && !done && !failed;
              const isDone = i < currentStep || done;
              return (
                <div key={step.id} style={{ display: 'flex', gap: 14, alignItems: 'flex-start' }}>
                  <div style={{
                    width: 24, height: 24, borderRadius: '50%', flexShrink: 0, marginTop: 1,
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    background: isDone ? 'rgba(140,175,136,0.2)' : isActive ? T.accent + '26' : 'transparent',
                    border: `1.5px solid ${isDone ? T.success : isActive ? T.accent : T.border}`,
                    transition: 'all 0.3s',
                  }}>
                    {isDone ? (
                      <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke={T.success} strokeWidth="2.5"><polyline points="20 6 9 17 4 12"/></svg>
                    ) : isActive ? (
                      <div style={{ width: 8, height: 8, borderRadius: '50%', background: T.accent, animation: 'pulse 1s ease-in-out infinite' }} />
                    ) : (
                      <div style={{ width: 6, height: 6, borderRadius: '50%', background: T.fgDim }} />
                    )}
                  </div>
                  <div>
                    <div style={{ fontSize: 14, fontWeight: 500, color: isDone ? T.fg : isActive ? T.fg : T.fgDim, transition: 'color 0.3s' }}>
                      {failed && i === currentStep ? `${step.label} — falhou` : step.label}
                    </div>
                    {(isActive || isDone) && !(failed && i === currentStep) && step.detail && (
                      <div style={{ fontSize: 12, color: T.fgMuted, marginTop: 2 }}>{step.detail}</div>
                    )}
                  </div>
                </div>
              );
            })}
          </div>

          {failed && (
            <div style={{ marginTop: 28, paddingTop: 24, borderTop: `1px solid ${T.border}` }}>
              <div style={{
                display: 'flex', gap: 12, alignItems: 'flex-start', padding: '14px 16px', borderRadius: 12,
                background: 'rgba(231,111,81,0.08)', border: `1px solid rgba(231,111,81,0.28)`, marginBottom: 16,
              }}>
                <div style={{ fontSize: 18, lineHeight: 1 }}>✕</div>
                <div>
                  <div style={{ fontSize: 13, fontWeight: 600, color: T.hot, marginBottom: 3 }}>Não conseguimos processar esta sessão</div>
                  <div style={{ fontSize: 12, color: T.fgMuted }}>{errorMessage || 'Tente novamente em alguns instantes.'}</div>
                </div>
              </div>
              <div style={{ display: 'flex', gap: 10 }}>
                <BtnGhost onClick={onBackToUpload} style={{ flex: 1 }}>Voltar e editar</BtnGhost>
                {onRetry ? (
                  <BtnPrimary onClick={onRetry} style={{ flex: 1 }}>Tentar de novo</BtnPrimary>
                ) : (
                  <BtnPrimary onClick={() => window.open('mailto:suporte@orbitas.app.br')} style={{ flex: 1 }}>Falar com suporte</BtnPrimary>
                )}
              </div>
            </div>
          )}

          {done && (
            <div style={{ marginTop: 28, paddingTop: 24, borderTop: `1px solid ${T.border}`, textAlign: 'center' }}>
              <div style={{ fontSize: 13, color: T.fgMuted, marginBottom: 16 }}>
                {leitura
                  ? `${leitura.cards.length} cards gerados · ${leitura.alertas.length} alertas · Prontos para revisão`
                  : 'Sessão gerada com sucesso.'}
              </div>
              <BtnPrimary onClick={onReady} style={{ width: '100%' }}>
                Revisar sessão →
              </BtnPrimary>
            </div>
          )}
        </Card>
      </div>

      <style>{`
        @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
        @keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:0.3; } }
      `}</style>
    </div>
  );
};

Object.assign(window, { NewSessionScreen, ProcessingScreen });
