// ─── Dashboard do Médico v3 — Estética Clínico-Orgânica ────────────────────
const { useState: useStateDoc, useEffect: useEffectDoc, useMemo: useMemoDoc } = React;

const C = {
  sage: '#5C8A6E', sageDark: '#2C4A35', sageDeep: '#1E3326',
  sageLight: '#7AAD8A', sagePale: '#EAF2ED', sageMid: '#4A6355',
  cream: '#F5F0E8', creamDark: '#EDE7D9', bg: '#F8F5EF',
  amber: '#C8973A', amberLight: '#F5E6C0', amberPale: '#FBF5E6',
  text: '#1A2B1E', textMid: '#4A6355', textMuted: '#8FAA96',
  border: '#DDD8CE', borderLight: '#EDE9E2',
  red: '#B84040', redLight: '#FFF0F0', redBorder: '#F5C5C5',
  white: '#FFFFFF',
};

const STATUS_MAP = {
  novo:     { label:'Novo',     bg:'#EAF2ED', color:'#2C4A35', border:'#B8D9C4' },
  lido:     { label:'Lido',     bg:'#F5F0E8', color:'#7A6E5A', border:'#DDD8CE' },
  revisado: { label:'Revisado', bg:'#FBF5E6', color:'#8A6A20', border:'#E8D5A0' },
  erro:     { label:'Erro IA',  bg:'#FFF0F0', color:'#B84040', border:'#F5C5C5' },
};

const AVATAR_COLORS = ['#5C8A6E','#2C4A35','#8A6A20','#B84040','#4A7A8A','#7A5C8A'];
const getInitials = n => n.trim().split(/\s+/).slice(0,2).map(w=>w[0]).join('').toUpperCase();
const getAvatarColor = n => { let h=0; for(let c of n) h=(h*31+c.charCodeAt(0))%AVATAR_COLORS.length; return AVATAR_COLORS[h]; };

// QR Code real usando biblioteca qrcode-generator (carregada via CDN, expõe global `qrcode`)
const RealQR = ({ text, size }) => {
  const sz = size || 150;
  const dataUrl = useMemoDoc(() => {
    if (!text || typeof qrcode === 'undefined') return null;
    try {
      const qr = qrcode(0, 'M');     // typeNumber 0 = auto, correção média
      qr.addData(text);
      qr.make();
      // cellSize calculado para aproximar o tamanho desejado; margin = 4 módulos (padrão QR)
      const modules = qr.getModuleCount();
      const cellSize = Math.max(2, Math.floor(sz / (modules + 8)));
      return qr.createDataURL(cellSize, cellSize * 4);
    } catch (e) {
      console.error('[QR] falha ao gerar QR code', e);
      return null;
    }
  }, [text, sz]);
  if (!dataUrl) return <div style={{width:sz,height:sz,background:C.cream,borderRadius:8}} />;
  return <img src={dataUrl} width={sz} height={sz} alt="QR Code" style={{display:'block',borderRadius:4,imageRendering:'pixelated'}} />;
};

// Modal base
const Modal = ({ onClose, children }) => (
  <div style={{position:'fixed',inset:0,background:'rgba(30,51,38,0.5)',display:'flex',alignItems:'flex-start',justifyContent:'center',zIndex:50,padding:'16px',paddingTop:'env(safe-area-inset-top, 16px)',overflowY:'auto',backdropFilter:'blur(2px)'}} onClick={onClose}>
    <div style={{background:C.white,borderRadius:20,boxShadow:'0 24px 64px rgba(30,51,38,0.18)',padding:28,width:'100%',maxWidth:380,border:`1px solid ${C.borderLight}`,marginTop:'auto',marginBottom:'auto',flexShrink:0}} onClick={e=>e.stopPropagation()}>
      {children}
    </div>
  </div>
);

// Modal — Confirmar exclusão
const ConfirmDeleteModal = ({ title, description, confirmLabel = 'Apagar', loadingLabel = 'Apagando…', loading = false, error = false, onClose, onConfirm }) => (
  <Modal onClose={loading ? undefined : onClose}>
    <style>{`@keyframes docSpin{to{transform:rotate(360deg)}}`}</style>
    {/* Ícone de alerta */}
    <div style={{width:46,height:46,borderRadius:'50%',background:C.redLight,border:`1.5px solid ${C.redBorder}`,display:'flex',alignItems:'center',justifyContent:'center',marginBottom:14}}>
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={C.red} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
    </div>
    <h3 style={{fontSize:17,fontWeight:700,color:C.text,marginBottom:8,fontFamily:'Lora, serif'}}>{title}</h3>
    <p style={{fontSize:13,color:C.textMuted,marginBottom:error?14:24,lineHeight:1.6}}>{description}</p>

    {error && (
      <div style={{display:'flex',alignItems:'center',gap:8,background:C.redLight,border:`1px solid ${C.redBorder}`,borderRadius:10,padding:'9px 12px',marginBottom:18,fontSize:12.5,color:C.red,lineHeight:1.5}}>
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" style={{flexShrink:0}}><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
        Não foi possível apagar. Tente novamente.
      </div>
    )}

    <div style={{display:'flex',gap:10}}>
      <button onClick={onClose} disabled={loading}
        style={{flex:1,padding:'11px',borderRadius:10,border:`1.5px solid ${C.border}`,background:C.white,color:C.textMid,fontSize:13,fontWeight:600,cursor:loading?'default':'pointer',opacity:loading?0.5:1,transition:'all 0.15s'}}>
        Cancelar
      </button>
      <button onClick={onConfirm} disabled={loading}
        style={{flex:1,padding:'11px',borderRadius:10,border:'none',background:C.red,color:C.white,fontSize:13,fontWeight:700,cursor:loading?'wait':'pointer',boxShadow:`0 4px 14px rgba(184,64,64,0.28)`,display:'flex',alignItems:'center',justifyContent:'center',gap:7,opacity:loading?0.85:1,transition:'all 0.15s'}}>
        {loading ? (
          <><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{animation:'docSpin 0.7s linear infinite'}}><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>{loadingLabel}</>
        ) : confirmLabel}
      </button>
    </div>
  </Modal>
);

// Modal — Criar ambiente
const CreateEnvModal = ({ onClose, onCreate }) => {
  const [envName, setEnvName] = useStateDoc('');
  const valid = envName.trim().length > 0;
  return (
    <Modal onClose={onClose}>
      <h3 style={{fontSize:18,fontWeight:700,color:C.text,marginBottom:4,fontFamily:'Lora, serif'}}>Novo ambiente</h3>
      <p style={{fontSize:13,color:C.textMuted,marginBottom:22,lineHeight:1.5}}>Organize envios de exames por clínica ou contexto.</p>
      <label style={{display:'block',fontSize:12,fontWeight:600,color:C.textMid,marginBottom:6,letterSpacing:'0.04em',textTransform:'uppercase'}}>Nome</label>
      <input
        style={{width:'100%',padding:'12px 14px',borderRadius:10,border:`1.5px solid ${C.border}`,fontSize:16,color:C.text,background:C.cream,boxSizing:'border-box',outline:'none',transition:'border-color 0.15s'}}
        placeholder="Ex: Consultório Particular"
        value={envName} onChange={e=>setEnvName(e.target.value)}
        onKeyDown={e=>e.key==='Enter'&&valid&&onCreate(envName.trim())}
        onFocus={e=>e.target.style.borderColor=C.sage}
        onBlur={e=>e.target.style.borderColor=C.border}
      />
      <div style={{display:'flex',gap:10,marginTop:20}}>
        <button onClick={onClose} style={{flex:1,padding:'11px',borderRadius:10,border:`1.5px solid ${C.border}`,background:C.white,color:C.textMid,fontSize:13,fontWeight:600,cursor:'pointer'}}>Cancelar</button>
        <button
          disabled={!valid}
          onClick={()=>valid&&onCreate(envName.trim())}
          style={{flex:1,padding:'11px',borderRadius:10,border:'none',background:valid?C.sageDark:C.border,color:valid?C.white:C.textMuted,fontSize:13,fontWeight:700,cursor:valid?'pointer':'not-allowed',boxShadow:valid?`0 4px 14px rgba(44,74,53,0.28)`:'none',transition:'all 0.15s'}}
        >Criar ambiente</button>
      </div>
    </Modal>
  );
};

// Modal — Adicionar paciente
const AddPatientModal = ({ env, onClose, onAdd }) => {
  const [form, setForm] = useStateDoc({ name:'', dob:'', cpf:'', phone:'', notes:'' });
  const [saving, setSaving] = useStateDoc(false);
  const [error, setError] = useStateDoc('');
  const set = (k,v) => setForm(f=>({...f,[k]:v}));
  const valid = form.name.trim().length > 0;

  const inputStyle = (focused) => ({
    width:'100%', padding:'10px 13px', borderRadius:10,
    border:`1.5px solid ${focused ? C.sage : C.border}`,
    fontSize:16, color:C.text, background:C.cream,
    boxSizing:'border-box', outline:'none', transition:'border-color 0.15s',
    fontFamily:'inherit',
  });
  const labelStyle = { display:'block', fontSize:11, fontWeight:600, color:C.textMid, marginBottom:5, letterSpacing:'0.04em', textTransform:'uppercase' };
  const [focus, setFocus] = useStateDoc({});

  const save = async () => {
    if (!valid || saving) return;
    setSaving(true); setError('');
    try {
      const patient = await onAdd({ env_id: env.id, ...form });
      onClose(patient);
    } catch (e) {
      setError(e.message || 'Erro ao cadastrar paciente');
      setSaving(false);
    }
  };

  return (
    <Modal onClose={onClose}>
      <div style={{display:'flex',alignItems:'center',gap:12,marginBottom:18}}>
        <div style={{width:40,height:40,borderRadius:11,background:C.sagePale,display:'flex',alignItems:'center',justifyContent:'center',border:`1.5px solid ${C.border}`}}>
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke={C.sage} strokeWidth="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
        </div>
        <div>
          <h3 style={{fontSize:16,fontWeight:700,color:C.text,margin:0,fontFamily:'Lora, serif'}}>Novo paciente</h3>
          <p style={{fontSize:12,color:C.textMuted,margin:0,marginTop:2}}>{env.name}</p>
        </div>
        <button onClick={onClose} style={{marginLeft:'auto',width:28,height:28,borderRadius:'50%',border:'none',background:C.creamDark,color:C.textMuted,cursor:'pointer',display:'flex',alignItems:'center',justifyContent:'center'}}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
        </button>
      </div>

      <div style={{display:'flex',flexDirection:'column',gap:13}}>
        <div>
          <label style={labelStyle}>Nome completo *</label>
          <input autoFocus style={inputStyle(focus.name)} placeholder="Ex: Maria Silva"
            value={form.name} onChange={e=>set('name',e.target.value)}
            onKeyDown={e=>e.key==='Enter'&&save()}
            onFocus={()=>setFocus(f=>({...f,name:true}))}
            onBlur={()=>setFocus(f=>({...f,name:false}))}/>
        </div>
        <div className="modal-grid-2">
          <div>
            <label style={labelStyle}>Data de nascimento</label>
            <input type="date" style={inputStyle(focus.dob)} value={form.dob} onChange={e=>set('dob',e.target.value)}
              onFocus={()=>setFocus(f=>({...f,dob:true}))} onBlur={()=>setFocus(f=>({...f,dob:false}))}/>
          </div>
          <div>
            <label style={labelStyle}>CPF</label>
            <input style={inputStyle(focus.cpf)} placeholder="000.000.000-00" value={form.cpf} inputMode="numeric" maxLength={14}
              onChange={e=>{
                let v = e.target.value.replace(/\D/g, '').slice(0, 11);
                if (v.length > 9) v = v.slice(0,3) + '.' + v.slice(3,6) + '.' + v.slice(6,9) + '-' + v.slice(9);
                else if (v.length > 6) v = v.slice(0,3) + '.' + v.slice(3,6) + '.' + v.slice(6);
                else if (v.length > 3) v = v.slice(0,3) + '.' + v.slice(3);
                set('cpf', v);
              }}
              onFocus={()=>setFocus(f=>({...f,cpf:true}))} onBlur={()=>setFocus(f=>({...f,cpf:false}))}/>
          </div>
        </div>
        <div>
          <label style={labelStyle}>Telefone</label>
          <input style={inputStyle(focus.phone)} placeholder="(81) 99999-9999" value={form.phone} onChange={e=>set('phone',e.target.value)}
            onFocus={()=>setFocus(f=>({...f,phone:true}))} onBlur={()=>setFocus(f=>({...f,phone:false}))}/>
        </div>
        <div>
          <label style={labelStyle}>Observações</label>
          <textarea rows={2} style={{...inputStyle(focus.notes),resize:'none'}} placeholder="Notas internas..." value={form.notes} onChange={e=>set('notes',e.target.value)}
            onFocus={()=>setFocus(f=>({...f,notes:true}))} onBlur={()=>setFocus(f=>({...f,notes:false}))}/>
        </div>
      </div>

      {error && <p style={{fontSize:12,color:C.red,marginTop:10,marginBottom:0}}>{error}</p>}

      <div style={{display:'flex',gap:10,marginTop:18}}>
        <button onClick={onClose} style={{flex:1,padding:'11px',borderRadius:10,border:`1.5px solid ${C.border}`,background:C.white,color:C.textMid,fontSize:13,fontWeight:600,cursor:'pointer'}}>Cancelar</button>
        <button
          disabled={!valid||saving}
          onClick={save}
          style={{flex:1,padding:'11px',borderRadius:10,border:'none',background:valid?C.sageDark:C.border,color:valid?C.white:C.textMuted,fontSize:13,fontWeight:700,cursor:valid?'pointer':'not-allowed',boxShadow:valid?`0 4px 14px rgba(44,74,53,0.28)`:'none',transition:'all 0.15s'}}>
          {saving ? 'Salvando...' : 'Cadastrar'}
        </button>
      </div>
    </Modal>
  );
};

// Modal — Compartilhar link
const ShareModal = ({ env, onClose }) => {
  const base = window.location.href.split('?')[0];
  const link = base + '?view=paciente&env=' + env.id;
  const [copied, setCopied] = useStateDoc(false);
  const copy = () => { try { navigator.clipboard.writeText(link); } catch(e) {} setCopied(true); setTimeout(()=>setCopied(false),2500); };
  return (
    <Modal onClose={onClose}>
      <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:4}}>
        <h3 style={{fontSize:18,fontWeight:700,color:C.text,margin:0,fontFamily:'Lora, serif'}}>Link de envio</h3>
        <button onClick={onClose} style={{width:28,height:28,borderRadius:'50%',border:'none',background:C.creamDark,color:C.textMuted,cursor:'pointer',display:'flex',alignItems:'center',justifyContent:'center'}}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
        </button>
      </div>
      <p style={{fontSize:13,color:C.textMuted,marginBottom:18,lineHeight:1.5}}>Compartilhe com pacientes para enviar exames em <strong style={{color:C.text}}>{env.name}</strong>.</p>
      <div style={{display:'flex',gap:8,marginBottom:20}}>
        <div style={{flex:1,padding:'9px 12px',background:C.cream,border:`1.5px solid ${C.border}`,borderRadius:10,fontSize:11,color:C.textMid,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',userSelect:'all'}}>{link}</div>
        <button onClick={copy} style={{padding:'9px 16px',borderRadius:10,border:'none',background:copied?C.sagePale:C.sageDark,color:copied?C.sage:C.white,fontSize:12,fontWeight:700,cursor:'pointer',flexShrink:0,transition:'all 0.2s',minWidth:82}}>
          {copied ? '✓ Copiado' : 'Copiar'}
        </button>
      </div>
      <div style={{display:'flex',flexDirection:'column',alignItems:'center',gap:10}}>
        <div style={{padding:14,border:`1.5px solid ${C.border}`,borderRadius:16,background:C.cream}}>
          <RealQR text={link} size={150}/>
        </div>
        <span style={{fontSize:11,color:C.textMuted}}>Escaneie com a câmera do celular</span>
      </div>
    </Modal>
  );
};

// Lista de envios
const SubmissionList = ({ submissions, onOpen, onOpenPatient, onShare, onDelete }) => {
  if (submissions.length === 0) {
    return (
      <div style={{display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',padding:'80px 24px',textAlign:'center'}}>
        <div style={{width:64,height:64,borderRadius:20,background:C.sagePale,display:'flex',alignItems:'center',justifyContent:'center',marginBottom:18,border:`1.5px solid ${C.border}`}}>
          <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke={C.sage} strokeWidth="1.5"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
        </div>
        <h3 style={{fontSize:16,fontWeight:600,color:C.text,marginBottom:8,fontFamily:'Lora, serif'}}>Nenhum envio ainda</h3>
        <p style={{fontSize:13,color:C.textMuted,maxWidth:280,lineHeight:1.7,marginBottom:24}}>Gere e compartilhe o link de envio com seus pacientes para começar a receber exames.</p>
        <button onClick={onShare} style={{padding:'11px 22px',borderRadius:10,border:'none',background:C.sageDark,color:C.white,fontSize:13,fontWeight:600,cursor:'pointer',boxShadow:`0 4px 14px rgba(44,74,53,0.25)`}}>
          Gerar link de envio
        </button>
      </div>
    );
  }

  return (
    <div style={{padding:'20px 20px',maxWidth:700}}>
      <div style={{display:'flex',flexDirection:'column',gap:8}}>
        {submissions.map(sub => {
          const st = STATUS_MAP[sub.status] || STATUS_MAP.lido;
          const avatarColor = getAvatarColor(sub.patientName);
          const initials = getInitials(sub.patientName);
          const hasAI = sub.labBlocks && sub.labBlocks.length > 0;
          return (
            <div key={sub.id} style={{display:'flex',alignItems:'center',gap:8,background:C.white,borderRadius:14,border:`1.5px solid ${C.borderLight}`,boxShadow:'0 1px 4px rgba(30,51,38,0.05)',overflow:'hidden'}} className="sub-item">
              <button onClick={() => onOpen(sub)}
                style={{display:'flex',alignItems:'center',gap:14,padding:'14px 16px',cursor:'pointer',textAlign:'left',transition:'all 0.18s',fontFamily:'inherit',flex:1,minWidth:0,background:'none',border:'none'}}
                onMouseEnter={e=>{e.currentTarget.closest('.sub-item').style.borderColor=C.sage;e.currentTarget.closest('.sub-item').style.boxShadow=`0 4px 18px rgba(92,138,110,0.14)`;e.currentTarget.closest('.sub-item').style.transform='translateY(-1px)';}}
                onMouseLeave={e=>{e.currentTarget.closest('.sub-item').style.borderColor=C.borderLight;e.currentTarget.closest('.sub-item').style.boxShadow='0 1px 4px rgba(30,51,38,0.05)';e.currentTarget.closest('.sub-item').style.transform='none';}}>

                {/* Avatar */}
                <div style={{width:44,height:44,borderRadius:12,background:avatarColor,display:'flex',alignItems:'center',justifyContent:'center',color:C.white,fontSize:14,fontWeight:700,flexShrink:0,letterSpacing:'0.03em'}}>
                  {initials}
                </div>

                {/* Info */}
                <div style={{flex:1,minWidth:0}}>
                  <button
                    onClick={e => { e.stopPropagation(); onOpenPatient && onOpenPatient(sub.envId, sub.patientName); }}
                    title="Ver histórico do paciente"
                    style={{display:'block',width:'100%',fontSize:14,fontWeight:600,color:C.sage,fontFamily:'Lora, serif',background:'none',border:'none',padding:0,marginBottom:5,cursor:'pointer',textAlign:'left',textDecoration:'underline',textDecorationStyle:'dotted',textUnderlineOffset:3,lineHeight:1.3}}>
                    {sub.patientName}
                  </button>
                  <div style={{display:'flex',alignItems:'center',gap:6,marginBottom:4,flexWrap:'wrap'}}>
                    <span style={{fontSize:11,fontWeight:600,color:st.color,background:st.bg,border:`1px solid ${st.border}`,borderRadius:20,padding:'2px 10px'}}>{st.label}</span>
                    {hasAI && <span style={{fontSize:11,color:C.sageDark,background:C.sagePale,borderRadius:20,padding:'2px 9px',border:`1px solid ${C.border}`,fontWeight:500}}>IA pronta</span>}
                  </div>
                  <div style={{fontSize:12,color:C.textMuted,display:'flex',gap:10,flexWrap:'wrap'}}>
                    <span>{fmtDate(sub.patientDob)} · {sub.files.length} arquivo{sub.files.length!==1?'s':''}</span>
                    <span>{fmtDateTime(sub.submittedAt)}</span>
                  </div>
                </div>

                {/* Seta */}
                <svg style={{flexShrink:0,color:C.textMuted}} width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polyline points="9 18 15 12 9 6"/></svg>
              </button>

              {/* Botão apagar — sempre visível; cinza por padrão, vermelho no hover */}
              <button className="sub-delete"
                onClick={e=>{e.stopPropagation();onDelete(sub);}}
                title="Apagar envio" aria-label="Apagar envio"
                style={{flexShrink:0,width:36,height:36,borderRadius:8,border:`1.5px solid ${C.borderLight}`,background:C.white,color:C.textMuted,cursor:'pointer',display:'flex',alignItems:'center',justifyContent:'center',transition:'all 0.15s',padding:0,margin:'0 10px 0 0'}}
                onMouseEnter={e=>{e.currentTarget.style.color=C.red;e.currentTarget.style.background=C.redLight;e.currentTarget.style.borderColor=C.redBorder;}}
                onMouseLeave={e=>{e.currentTarget.style.color=C.textMuted;e.currentTarget.style.background=C.white;e.currentTarget.style.borderColor=C.borderLight;}}>
                <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6"/><path d="M14 11v6"/><path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/></svg>
              </button>
            </div>
          );
        })}
      </div>
    </div>
  );
};

// Lista de pacientes (derivada dos submissions — sem API extra)
const PatientList = ({ submissions, onOpenPatient, onNovoEnvio }) => {
  const patients = useMemoDoc(() => {
    const map = {};
    for (const s of submissions) {
      const key = (s.patientName || '').trim().toLowerCase();
      if (!key) continue;
      if (!map[key]) {
        map[key] = {
          name_key: key,
          name: s.patientName,
          dob: s.patientDob,
          cpf: s.patientCpf,
          total_envios: 0,
          primeiro_envio: s.submittedAt,
          ultimo_envio: s.submittedAt,
          envId: s.envId,
        };
      }
      const entry = map[key];
      entry.total_envios++;
      if (s.submittedAt < entry.primeiro_envio) entry.primeiro_envio = s.submittedAt;
      if (s.submittedAt > entry.ultimo_envio) entry.ultimo_envio = s.submittedAt;
    }
    return Object.values(map).sort((a, b) => new Date(b.ultimo_envio) - new Date(a.ultimo_envio));
  }, [submissions]);

  if (patients.length === 0) {
    return (
      <div style={{display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',padding:'80px 24px',textAlign:'center'}}>
        <div style={{width:64,height:64,borderRadius:20,background:C.sagePale,display:'flex',alignItems:'center',justifyContent:'center',marginBottom:18,border:`1.5px solid ${C.border}`}}>
          <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke={C.sage} strokeWidth="1.5"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
        </div>
        <h3 style={{fontSize:16,fontWeight:600,color:C.text,marginBottom:8,fontFamily:'Lora, serif'}}>Nenhum paciente ainda</h3>
        <p style={{fontSize:13,color:C.textMuted,maxWidth:280,lineHeight:1.7}}>Os pacientes aparecem aqui automaticamente quando enviam exames pelo link de acesso.</p>
        <button onClick={() => onNovoEnvio?.()}
          style={{padding:'10px 20px',borderRadius:10,border:'none',background:C.sageDark,color:C.white,fontSize:13,fontWeight:600,cursor:'pointer',boxShadow:`0 4px 14px rgba(44,74,53,0.25)`,fontFamily:'inherit'}}>
          + Novo paciente
        </button>
      </div>
    );
  }

  return (
    <div style={{padding:'20px 20px',maxWidth:700}}>
      <div style={{display:'flex',justifyContent:'flex-end',marginBottom:12}}>
        <button onClick={() => onNovoEnvio?.()}
          style={{display:'flex',alignItems:'center',gap:6,padding:'8px 16px',borderRadius:10,border:'none',background:C.sageDark,color:C.white,fontSize:12,fontWeight:600,cursor:'pointer',boxShadow:`0 2px 8px rgba(44,74,53,0.22)`,fontFamily:'inherit'}}
          onMouseEnter={e=>{e.currentTarget.style.opacity='0.85';}}
          onMouseLeave={e=>{e.currentTarget.style.opacity='1';}}>
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
          Novo paciente
        </button>
      </div>
      <div style={{display:'flex',flexDirection:'column',gap:8}}>
        {patients.map(p => {
          const avatarColor = getAvatarColor(p.name);
          const initials = getInitials(p.name);
          return (
            <button key={p.name_key} onClick={() => onOpenPatient(p.envId, p.name)}
              style={{display:'flex',alignItems:'center',gap:14,padding:'14px 16px',background:C.white,borderRadius:14,border:`1.5px solid ${C.borderLight}`,boxShadow:'0 1px 4px rgba(30,51,38,0.05)',transition:'all 0.18s',cursor:'pointer',textAlign:'left',fontFamily:'inherit',width:'100%'}}
              onMouseEnter={e=>{e.currentTarget.style.borderColor=C.sage;e.currentTarget.style.boxShadow=`0 4px 18px rgba(92,138,110,0.14)`;e.currentTarget.style.transform='translateY(-1px)';}}
              onMouseLeave={e=>{e.currentTarget.style.borderColor=C.borderLight;e.currentTarget.style.boxShadow='0 1px 4px rgba(30,51,38,0.05)';e.currentTarget.style.transform='none';}}>

              <div style={{width:44,height:44,borderRadius:12,background:avatarColor,display:'flex',alignItems:'center',justifyContent:'center',color:C.white,fontSize:14,fontWeight:700,flexShrink:0,letterSpacing:'0.03em'}}>
                {initials}
              </div>

              <div style={{flex:1,minWidth:0}}>
                <div style={{fontSize:14,fontWeight:600,color:C.text,fontFamily:'Lora, serif',marginBottom:3}}>{p.name}</div>
                <div style={{fontSize:12,color:C.textMuted,display:'flex',gap:12,flexWrap:'wrap'}}>
                  {p.dob && <span>{fmtDate(p.dob)}</span>}
                  {p.cpf && <span>CPF: {p.cpf}</span>}
                  <span>{p.total_envios} envio{p.total_envios !== 1 ? 's' : ''}</span>
                  <span>Último: {fmtDateTime(p.ultimo_envio)}</span>
                </div>
              </div>

              <div style={{display:'flex',alignItems:'center',gap:8,flexShrink:0}}>
                {p.total_envios > 1 && (
                  <span style={{fontSize:10,fontWeight:700,color:C.sageDark,background:C.sagePale,borderRadius:20,padding:'2px 9px',border:`1px solid #B8D9C4`}}>
                    Histórico
                  </span>
                )}
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={C.textMuted} strokeWidth="2"><polyline points="9 18 15 12 9 6"/></svg>
              </div>
            </button>
          );
        })}
      </div>
    </div>
  );
};

// ─── Admin — Gestão de Médicos ───────────────────────────────────────────────
const AdminMedicos = ({ onBack }) => {
  const [medicos, setMedicos] = useStateDoc([]);
  const [loading, setLoading] = useStateDoc(true);
  const [buscarEmail, setBuscarEmail] = useStateDoc('');
  const [buscado, setBuscado] = useStateDoc(null);
  const [envIdAdd, setEnvIdAdd] = useStateDoc('');
  const [msgAdd, setMsgAdd] = useStateDoc('');
  const [removendo, setRemovendo] = useStateDoc(null); // médico no modal de confirmação

  const carregar = () => {
    setLoading(true);
    fetch('/api/admin/medicos', { credentials: 'include' })
      .then(r => r.json()).then(data => { setMedicos(Array.isArray(data) ? data : []); setLoading(false); });
  };

  useEffectDoc(carregar, []);

  const acao = (id, action) => {
    fetch(`/api/admin/medicos/${id}/${action}`, { method: 'PATCH', credentials: 'include' })
      .then(() => carregar());
  };

  const confirmarRemocao = () => {
    if (!removendo) return;
    const id = removendo.id;
    setRemovendo(null);
    fetch(`/api/admin/medicos/${id}`, { method: 'DELETE', credentials: 'include' })
      .then(() => carregar());
  };

  const buscar = () => {
    if (!buscarEmail.trim()) return;
    fetch(`/api/admin/buscar-medico?email=${encodeURIComponent(buscarEmail)}`, { credentials: 'include' })
      .then(r => r.ok ? r.json() : null).then(setBuscado);
  };

  const adicionarMembro = () => {
    if (!buscado || !envIdAdd.trim()) { setMsgAdd('Preencha o ID do ambiente'); return; }
    fetch(`/api/environments/${envIdAdd}/members`, {
      method: 'POST', credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ medicoId: buscado.id }),
    }).then(r => r.json()).then(d => setMsgAdd(d.message || d.error));
  };

  const badge = (status) => {
    const map = { pendente: ['#FBF5E6','#8A6A20'], ativo: ['#EAF2ED','#2C4A35'], bloqueado: ['#FFF0F0','#B84040'] };
    const [bg, color] = map[status] || ['#eee','#333'];
    return React.createElement('span', { style: { background: bg, color, fontSize: 11, fontWeight: 700, borderRadius: 6, padding: '2px 8px' } }, status);
  };

  return (
    <div style={{ padding: 24, maxWidth: 700, margin: '0 auto' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 24 }}>
        <button onClick={onBack} style={{ background: 'none', border: 'none', cursor: 'pointer', color: C.sage, fontSize: 14, fontWeight: 600 }}>← Voltar</button>
        <h2 style={{ fontSize: 20, fontWeight: 700, color: C.sageDark, fontFamily: 'Lora, serif', margin: 0 }}>Gestão de Médicos</h2>
      </div>

      {loading ? <p style={{ color: C.textMuted }}>Carregando...</p> : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginBottom: 32 }}>
          {medicos.map(m => (
            <div key={m.id} style={{ background: C.white, border: `1px solid ${C.border}`, borderRadius: 12, padding: '14px 18px', display: 'flex', alignItems: 'center', gap: 12 }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 14, fontWeight: 600, color: C.text }}>{m.nome}</div>
                <div style={{ fontSize: 12, color: C.textMuted }}>{m.email}</div>
              </div>
              {badge(m.status)}
              {!m.is_admin && (
                <div style={{ display: 'flex', gap: 8 }}>
                  {m.status === 'pendente' && <button onClick={() => acao(m.id, 'aprovar')} style={{ fontSize: 12, padding: '5px 12px', borderRadius: 8, border: 'none', background: C.sage, color: C.white, cursor: 'pointer', fontWeight: 600 }}>Aprovar</button>}
                  {m.status === 'ativo' && <button onClick={() => acao(m.id, 'bloquear')} style={{ fontSize: 12, padding: '5px 12px', borderRadius: 8, border: `1px solid ${C.border}`, background: C.white, color: C.textMid, cursor: 'pointer', fontWeight: 600 }}>Bloquear</button>}
                  {m.status === 'bloqueado' && <button onClick={() => acao(m.id, 'aprovar')} style={{ fontSize: 12, padding: '5px 12px', borderRadius: 8, border: 'none', background: C.sage, color: C.white, cursor: 'pointer', fontWeight: 600 }}>Reativar</button>}
                  <button onClick={() => setRemovendo(m)} style={{ fontSize: 12, padding: '5px 12px', borderRadius: 8, border: 'none', background: C.redLight, color: C.red, cursor: 'pointer', fontWeight: 600 }}>Remover</button>
                </div>
              )}
            </div>
          ))}
        </div>
      )}

      <div style={{ background: C.sagePale, borderRadius: 14, padding: 20 }}>
        <h3 style={{ fontSize: 15, fontWeight: 700, color: C.sageDark, marginBottom: 14 }}>Adicionar colaborador a ambiente</h3>
        <div style={{ display: 'flex', gap: 8, marginBottom: 10 }}>
          <input value={buscarEmail} onChange={e => setBuscarEmail(e.target.value)} placeholder="E-mail do médico" style={{ flex: 1, padding: '9px 12px', borderRadius: 8, border: `1px solid ${C.border}`, fontSize: 13 }} />
          <button onClick={buscar} style={{ padding: '9px 16px', borderRadius: 8, border: 'none', background: C.sage, color: C.white, fontWeight: 600, cursor: 'pointer', fontSize: 13 }}>Buscar</button>
        </div>
        {buscado && <p style={{ fontSize: 13, color: C.sageDark, marginBottom: 10 }}>Encontrado: <strong>{buscado.nome}</strong> ({buscado.status})</p>}
        <div style={{ display: 'flex', gap: 8 }}>
          <input value={envIdAdd} onChange={e => setEnvIdAdd(e.target.value)} placeholder="ID do ambiente (UUID)" style={{ flex: 1, padding: '9px 12px', borderRadius: 8, border: `1px solid ${C.border}`, fontSize: 13 }} />
          <button onClick={adicionarMembro} style={{ padding: '9px 16px', borderRadius: 8, border: 'none', background: C.sageDark, color: C.white, fontWeight: 600, cursor: 'pointer', fontSize: 13 }}>Adicionar</button>
        </div>
        {msgAdd && <p style={{ fontSize: 13, color: C.sageDark, marginTop: 8 }}>{msgAdd}</p>}
      </div>

      {removendo && (
        <ConfirmDeleteModal
          title="Remover este médico?"
          description={`${removendo.nome} perderá o acesso à plataforma. Esta ação não pode ser desfeita.`}
          confirmLabel="Remover"
          onClose={() => setRemovendo(null)}
          onConfirm={confirmarRemocao}
        />
      )}
    </div>
  );
};

// ─── Aba Colaboradores ────────────────────────────────────────────────────────
const AbaColaboradores = ({ envId }) => {
  const [email, setEmail] = useStateDoc('');
  const [buscado, setBuscado] = useStateDoc(null); // { nome, email, status } | null | 'erro'
  const [buscando, setBuscando] = useStateDoc(false);
  const [enviando, setEnviando] = useStateDoc(false);
  const [msgEnvio, setMsgEnvio] = useStateDoc('');
  const [dados, setDados] = useStateDoc({ colaboradores: [], pendentes: [] });
  const [carregando, setCarregando] = useStateDoc(true);
  const [confirmRemover, setConfirmRemover] = useStateDoc(null);

  const carregar = () => {
    setCarregando(true);
    fetch(`/api/invites/lista?envId=${envId}`, { credentials: 'include' })
      .then(r => r.json())
      .then(d => { setDados(d); setCarregando(false); })
      .catch(() => setCarregando(false));
  };

  useEffectDoc(() => { carregar(); }, [envId]);

  const buscar = async () => {
    if (!email.trim()) return;
    setBuscando(true); setBuscado(null); setMsgEnvio('');
    const r = await fetch(`/api/invites/buscar?email=${encodeURIComponent(email.trim())}`, { credentials: 'include' });
    setBuscando(false);
    if (!r.ok) { setBuscado('erro'); return; }
    setBuscado(await r.json());
  };

  const enviarConvite = async () => {
    if (!buscado || buscado === 'erro') return;
    setEnviando(true); setMsgEnvio('');
    const r = await fetch('/api/invites', {
      method: 'POST', credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ env_id: envId, invitee_email: buscado.email }),
    });
    const d = await r.json();
    setEnviando(false);
    if (!r.ok) { setMsgEnvio(d.error); return; }
    setMsgEnvio('Convite enviado!');
    setEmail(''); setBuscado(null);
    carregar();
  };

  const removerColaborador = async (medicoId) => {
    await fetch(`/api/environments/${envId}/members/${medicoId}`, { method: 'DELETE', credentials: 'include' });
    setConfirmRemover(null);
    carregar();
  };

  const fmtData = (iso) => new Date(iso).toLocaleDateString('pt-BR');

  const inputStyle = { flex: 1, padding: '9px 12px', borderRadius: 8, border: `1px solid ${C.border}`, fontSize: 13, fontFamily: 'inherit', outline: 'none' };
  const btnPrimary = { padding: '9px 16px', borderRadius: 8, border: 'none', background: C.sage, color: C.white, fontWeight: 600, cursor: 'pointer', fontSize: 13, fontFamily: 'inherit' };
  const sectionLabel = { fontSize: 11, fontWeight: 700, color: C.textMuted, textTransform: 'uppercase', letterSpacing: '.05em', marginBottom: 8, display: 'block' };

  return (
    <div style={{ padding: 24, maxWidth: 680, margin: '0 auto' }}>

      {/* Formulário de convite */}
      <div style={{ background: C.sagePale, border: `1px solid ${C.border}`, borderRadius: 12, padding: 18, marginBottom: 24 }}>
        <div style={{ fontSize: 13, fontWeight: 600, color: C.sageDark, marginBottom: 12 }}>Convidar colaborador</div>
        <div style={{ display: 'flex', gap: 8, marginBottom: buscado ? 10 : 0 }}>
          <input
            value={email}
            onChange={e => { setEmail(e.target.value); setBuscado(null); setMsgEnvio(''); }}
            onKeyDown={e => e.key === 'Enter' && buscar()}
            placeholder="E-mail do médico cadastrado"
            style={inputStyle}
          />
          <button onClick={buscar} disabled={buscando} style={btnPrimary}>
            {buscando ? '...' : 'Buscar'}
          </button>
        </div>

        {buscado === 'erro' && (
          <div style={{ fontSize: 13, color: C.red, marginBottom: 8 }}>Médico não encontrado nesta ferramenta.</div>
        )}
        {buscado && buscado !== 'erro' && (
          <div style={{ background: C.white, border: `1px solid ${C.border}`, borderRadius: 8, padding: '10px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div>
              <div style={{ fontSize: 13, fontWeight: 600, color: C.text }}>{buscado.nome}</div>
              <div style={{ fontSize: 12, color: C.textMuted }}>{buscado.email} · {buscado.status}</div>
            </div>
            <button onClick={enviarConvite} disabled={enviando} style={btnPrimary}>
              {enviando ? 'Enviando...' : 'Enviar convite'}
            </button>
          </div>
        )}
        {msgEnvio && (
          <div style={{ fontSize: 13, color: msgEnvio === 'Convite enviado!' ? C.sage : C.red, marginTop: 8 }}>{msgEnvio}</div>
        )}
      </div>

      {carregando ? (
        <div style={{ color: C.textMuted, fontSize: 13 }}>Carregando...</div>
      ) : (
        <>
          {/* Colaboradores ativos */}
          <span style={sectionLabel}>Colaboradores ativos</span>
          {dados.colaboradores.length === 0 ? (
            <div style={{ fontSize: 13, color: C.textMuted, marginBottom: 20 }}>Nenhum colaborador ainda.</div>
          ) : (
            <div style={{ background: C.white, border: `1px solid ${C.border}`, borderRadius: 10, overflow: 'hidden', marginBottom: 24 }}>
              {dados.colaboradores.map((c, i) => (
                <div key={c.id} style={{ padding: '14px 18px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: i < dados.colaboradores.length - 1 ? `1px solid ${C.borderLight}` : 'none' }}>
                  <div>
                    <div style={{ fontSize: 13, fontWeight: 600, color: C.text }}>{c.nome}</div>
                    <div style={{ fontSize: 12, color: C.textMuted }}>{c.email} · Adicionado em {fmtData(c.created_at)}</div>
                  </div>
                  {confirmRemover === c.id ? (
                    <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
                      <span style={{ fontSize: 12, color: C.textMuted }}>Tem certeza?</span>
                      <button onClick={() => removerColaborador(c.id)} style={{ padding: '4px 10px', borderRadius: 6, border: 'none', background: C.red, color: C.white, fontSize: 12, fontWeight: 600, cursor: 'pointer' }}>Sim</button>
                      <button onClick={() => setConfirmRemover(null)} style={{ padding: '4px 10px', borderRadius: 6, border: `1px solid ${C.border}`, background: C.white, color: C.textMid, fontSize: 12, fontWeight: 600, cursor: 'pointer' }}>Cancelar</button>
                    </div>
                  ) : (
                    <button onClick={() => setConfirmRemover(c.id)} style={{ padding: '5px 12px', borderRadius: 6, border: `1px solid ${C.redBorder}`, background: C.white, color: C.red, fontSize: 12, fontWeight: 600, cursor: 'pointer' }}>Remover</button>
                  )}
                </div>
              ))}
            </div>
          )}

          {/* Convites pendentes */}
          <span style={sectionLabel}>Convites pendentes</span>
          {dados.pendentes.length === 0 ? (
            <div style={{ fontSize: 13, color: C.textMuted }}>Nenhum convite pendente.</div>
          ) : (
            <div style={{ background: C.white, border: `1px solid ${C.border}`, borderRadius: 10, overflow: 'hidden' }}>
              {dados.pendentes.map((p, i) => (
                <div key={p.id} style={{ padding: '14px 18px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: i < dados.pendentes.length - 1 ? `1px solid ${C.borderLight}` : 'none' }}>
                  <div>
                    <div style={{ fontSize: 13, fontWeight: 600, color: C.text }}>{p.invitee_nome}</div>
                    <div style={{ fontSize: 12, color: C.textMuted }}>{p.invitee_email} · Enviado em {fmtData(p.created_at)}</div>
                  </div>
                  <span style={{ padding: '3px 10px', borderRadius: 20, background: '#FEF9C3', color: '#854D0E', fontSize: 11, fontWeight: 600 }}>Aguardando</span>
                </div>
              ))}
            </div>
          )}
        </>
      )}
    </div>
  );
};

// App principal
const DoctorApp = ({ medico, onLogout }) => {
  const [telaAdmin, setTelaAdmin] = useStateDoc(false);
  const USE_API = !!(window.API);
  const [convitesPendentes, setConvitesPendentes] = useStateDoc([]);

  const [envs, setEnvs] = useStateDoc([]);
  const [subs, setSubs] = useStateDoc([]);
  const [selEnv, setSelEnv] = useStateDoc(null);
  const [selSub, setSelSub] = useStateDoc(null);
  const [activePatient, setActivePatient] = useStateDoc(null); // { envId, name }
  const [cameFromPatient, setCameFromPatient] = useStateDoc(null); // { envId, name } | null — origem ao abrir um envio
  const [activeTab, setActiveTab] = useStateDoc('envios'); // 'envios' | 'pacientes'
  const [sidebarOpen, setSidebarOpen] = useStateDoc(false);
  const [showCreate, setShowCreate] = useStateDoc(false);
  const [showShare, setShowShare] = useStateDoc(false);
  const [deleteEnvTarget, setDeleteEnvTarget] = useStateDoc(null);
  const [deleteSubTarget, setDeleteSubTarget] = useStateDoc(null);
  const [deletandoEnv, setDeletandoEnv] = useStateDoc(false);
  const [erroDeleteEnv, setErroDeleteEnv] = useStateDoc(false);
  const [deletandoSub, setDeletandoSub] = useStateDoc(false);
  const [erroDeleteSub, setErroDeleteSub] = useStateDoc(false);
  const [showNovoEnvioDoc, setShowNovoEnvioDoc] = useStateDoc(false);
  const [loading, setLoading] = useStateDoc(true);
  const [apiError, setApiError] = useStateDoc(null);

  useEffectDoc(() => {
    async function load() {
      if (!USE_API) {
        setEnvs(window.MOCK_ENVIRONMENTS.slice());
        setSubs(window.MOCK_SUBMISSIONS.slice());
        setSelEnv(window.MOCK_ENVIRONMENTS[0] || null);
        setLoading(false);
        return;
      }
      try {
        const [envsData, subsData] = await Promise.all([
          window.API.environments.list(),
          window.API.submissions.list(),
        ]);
        setEnvs(envsData);
        setSubs(subsData);
        setSelEnv(envsData[0] || null);
      } catch (err) {
        setApiError('Não foi possível conectar ao servidor. Usando dados de demonstração.');
        setEnvs(window.MOCK_ENVIRONMENTS.slice());
        setSubs(window.MOCK_SUBMISSIONS.slice());
        setSelEnv(window.MOCK_ENVIRONMENTS[0] || null);
      } finally {
        setLoading(false);
      }
    }
    load();
  }, []);

  useEffectDoc(() => {
    if (!USE_API || !selEnv || loading) return;
    window.API.submissions.list(selEnv.id)
      .then(data => setSubs(prev => {
        const otherEnvs = prev.filter(s => s.envId !== selEnv.id);
        return [...otherEnvs, ...data];
      }))
      .catch(() => {});
  }, [selEnv?.id]);

  useEffectDoc(() => {
    if (!USE_API) return;
    fetch('/api/invites/pendentes', { credentials: 'include' })
      .then(r => r.ok ? r.json() : [])
      .then(data => setConvitesPendentes(Array.isArray(data) ? data : []))
      .catch(() => {});
  }, []);

  // ─── Botão "Voltar" do navegador: recua uma tela dentro da ferramenta ──────
  // Cada tela sobreposta (perfil do paciente, visualizador de exame, admin) conta
  // como um nível acima do dashboard. Invariante: mantemos exatamente `navDepthRef`
  // entradas no histórico acima da base. Assim o "voltar" do navegador consome uma
  // entrada e fechamos a tela mais interna, em vez de sair do app.
  const navDepthRef = React.useRef(0);
  const navBackRef = React.useRef(() => {});
  const navFromPopRef = React.useRef(false);  // a próxima mudança de depth veio de popstate?
  const navIgnorePopRef = React.useRef(false); // ignorar o próximo popstate (disparado por history.go interno)

  useEffectDoc(() => {
    const onPop = () => {
      // Popstate disparado pelo nosso próprio history.go (ao alinhar a pilha): ignorar.
      if (navIgnorePopRef.current) { navIgnorePopRef.current = false; return; }
      // O navegador já removeu uma entrada do histórico. Se havia tela aberta,
      // fechamos a mais interna; senão, deixamos o navegador sair normalmente.
      if (navDepthRef.current > 0) {
        navFromPopRef.current = true;
        navBackRef.current();
      }
    };
    window.addEventListener('popstate', onPop);
    return () => window.removeEventListener('popstate', onPop);
  }, []);

  useEffectDoc(() => {
    const depth = (telaAdmin ? 1 : 0) + (activePatient ? 1 : 0) + (selSub ? 1 : 0);
    const prev = navDepthRef.current;
    navDepthRef.current = depth;
    if (depth > prev) {
      // Entrou num nível mais profundo → empilha entradas.
      for (let i = 0; i < depth - prev; i++) window.history.pushState({ kiatiNav: true }, '');
    } else if (depth < prev && !navFromPopRef.current) {
      // Saiu de um nível por botão interno "← Voltar" (não pelo navegador):
      // remove as entradas extras para manter a invariante.
      navIgnorePopRef.current = true;
      window.history.go(-(prev - depth));
    }
    navFromPopRef.current = false;
  }, [telaAdmin, activePatient, selSub]);

  const envSubs = subs.filter(s => s.envId === selEnv?.id);

  const openSub = async (sub) => {
    if (USE_API && sub.status === 'novo') {
      window.API.submissions.patch(sub.id, { status: 'lido' }).catch(() => {});
    }
    setSubs(prev => prev.map(s => s.id===sub.id&&s.status==='novo' ? {...s,status:'lido'} : s));
    setSelSub(sub); setSidebarOpen(false);
  };

  // Converte uma submission vinda de /api/patients/history (snake_case) para o
  // formato camelCase que o ExamViewer espera, espelhando mapSubmission() do backend.
  const mapHistorySub = (sub) => {
    const demais = Array.isArray(sub.demais_exames ?? sub.demaisExames) ? (sub.demais_exames ?? sub.demaisExames) : [];
    const metaItem = demais.find(e => e && e.nome === '_meta');
    return {
      id:           sub.id,
      envId:        sub.env_id ?? sub.envId,
      status:       sub.status,
      patientName:  sub.patient_name ?? sub.patientName,
      patientDob:   sub.patient_dob ? new Date(sub.patient_dob).toISOString().slice(0, 10) : (sub.patientDob ?? null),
      patientCpf:   sub.patient_cpf ?? sub.patientCpf,
      submittedAt:  sub.submitted_at ?? sub.submittedAt,
      labBlocks:    sub.lab_blocks ?? sub.labBlocks ?? [],
      demaisExames: demais,
      files:        (sub.files ?? []).map(f => ({
        ...f,
        type: f.type || ((f.mimeType ?? f.mime_type ?? '').startsWith('image/') ? 'image' : 'pdf'),
      })),
      _meta:        metaItem ? { qualidade_imagem: metaItem.qualidade_imagem, observacoes: metaItem.observacoes } : {},
    };
  };

  // Volta do ExamViewer: se o envio foi aberto a partir do perfil de um paciente,
  // restaura esse perfil; senão, cai na lista de envios (comportamento padrão).
  const backFromViewer = () => {
    setSelSub(null);
    if (cameFromPatient) {
      setActivePatient(cameFromPatient);
      setCameFromPatient(null);
    }
  };

  // Fecha a tela mais interna, espelhando os botões "← Voltar" internos.
  // Reatribuído a cada render para sempre enxergar o estado atual.
  navBackRef.current = () => {
    if (telaAdmin) { setTelaAdmin(false); return; }
    if (selSub) { backFromViewer(); return; }
    if (activePatient) { setActivePatient(null); return; }
  };

  const createEnv = async (name) => {
    try {
      if (USE_API) {
        const e = await window.API.environments.create(name);
        setEnvs(prev => [...prev, e]); setSelEnv(e);
      } else {
        const e = {id:'env'+Date.now(),name};
        setEnvs(prev=>[...prev,e]); setSelEnv(e);
      }
      setSelSub(null); setShowCreate(false);
    } catch (err) { console.error('[DoctorApp] erro ao criar ambiente', err); }
  };

  const switchEnv = (env) => { setSelEnv(env); setSelSub(null); setCameFromPatient(null); setActivePatient(null); setSidebarOpen(false); setActiveTab('envios'); };

  const confirmDeleteEnv = async () => {
    if (deletandoEnv) return;
    const id = deleteEnvTarget.id;
    setErroDeleteEnv(false);
    setDeletandoEnv(true);
    try {
      if (USE_API) await window.API.environments.remove(id);
      setSubs(prev => prev.filter(s => s.envId !== id));
      setEnvs(prev => {
        const next = prev.filter(e => e.id !== id);
        if (selEnv?.id === id) setSelEnv(next[0] || null);
        return next;
      });
      setSelSub(null);
      setCameFromPatient(null);
      setActivePatient(null);
      setDeleteEnvTarget(null);
    } catch (err) {
      console.error('[DoctorApp] erro ao apagar ambiente', err.message);
      setErroDeleteEnv(true);
    } finally {
      setDeletandoEnv(false);
    }
  };

  const confirmDeleteSub = async () => {
    if (deletandoSub) return;
    const id = deleteSubTarget.id;
    setErroDeleteSub(false);
    setDeletandoSub(true);
    try {
      if (USE_API) await window.API.submissions.remove(id);
      setSubs(prev => prev.filter(s => s.id !== id));
      setDeleteSubTarget(null);
    } catch (err) {
      console.error('[DoctorApp] erro ao apagar envio', err.message);
      setErroDeleteSub(true);
    } finally {
      setDeletandoSub(false);
    }
  };

  const handleNovoEnvioSuccess = () => {
    if (!USE_API || !selEnv) return;
    window.API.submissions.list(selEnv.id)
      .then(data => setSubs(prev => {
        const otherEnvs = prev.filter(s => s.envId !== selEnv.id);
        return [...otherEnvs, ...data];
      }))
      .catch(() => {});
  };

  const responderConvite = async (inviteId, acao) => {
    const r = await fetch(`/api/invites/${inviteId}/${acao}`, { method: 'PATCH', credentials: 'include' });
    if (!r.ok) return;
    setConvitesPendentes(prev => prev.filter(c => c.id !== inviteId));
    if (acao === 'aceitar') {
      const envsData = await window.API.environments.list().catch(() => null);
      if (envsData) { setEnvs(envsData); if (!selEnv) setSelEnv(envsData[0] || null); }
    }
  };

  if (telaAdmin && medico?.isAdmin) return <AdminMedicos onBack={() => setTelaAdmin(false)} />;

  if (loading) return (
    <div style={{height:'100vh',display:'flex',alignItems:'center',justifyContent:'center',background:C.bg,fontFamily:'DM Sans, sans-serif'}}>
      <div style={{textAlign:'center'}}>
        <div style={{width:36,height:36,border:`3px solid ${C.border}`,borderTop:`3px solid ${C.sage}`,borderRadius:'50%',animation:'spin 0.8s linear infinite',margin:'0 auto 14px'}}/>
        <style>{`@keyframes spin{to{transform:rotate(360deg)}}`}</style>
        <span style={{fontSize:13,color:C.textMuted,fontFamily:'Lora, serif'}}>Carregando...</span>
      </div>
    </div>
  );

  return (
    <div style={{height:'100vh',display:'flex',overflow:'hidden',background:C.bg,fontFamily:'DM Sans, sans-serif'}}>

      {/* Banner modo demo */}
      {apiError && (
        <div style={{position:'fixed',top:0,left:0,right:0,background:C.amberPale,borderBottom:`1px solid ${C.amberLight}`,padding:'8px 16px',fontSize:12,color:'#7A5A1A',display:'flex',alignItems:'center',gap:8,zIndex:100}}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
          {apiError}
          <button onClick={()=>setApiError(null)} style={{marginLeft:'auto',background:'none',border:'none',cursor:'pointer',color:'#7A5A1A',fontSize:18,lineHeight:1,padding:0}}>×</button>
        </div>
      )}

      {/* Overlay mobile */}
      {sidebarOpen && <div style={{position:'fixed',inset:0,background:'rgba(30,51,38,0.45)',zIndex:20}} onClick={()=>setSidebarOpen(false)}/>}

      {/* Sidebar */}
      <aside style={{
        position:'fixed', top:0, left:0, bottom:0, width:240,
        background:`linear-gradient(180deg, ${C.sageDeep} 0%, ${C.sageDark} 100%)`,
        display:'flex', flexDirection:'column', zIndex:30,
        transition:'transform 0.25s ease',
        boxShadow: sidebarOpen ? '4px 0 32px rgba(0,0,0,0.2)' : 'none',
        height: '100%',
        maxHeight: '-webkit-fill-available',
        paddingBottom: 'env(safe-area-inset-bottom, 0px)',
      }}
      className={`lg-sidebar${sidebarOpen ? ' open' : ''}`}>

        {/* Brand */}
        <div style={{padding:'22px 18px 16px',borderBottom:'1px solid rgba(255,255,255,0.07)'}}>
          <div style={{display:'flex',alignItems:'center',gap:11}}>
            <div style={{width:34,height:34,borderRadius:10,background:'rgba(92,138,110,0.25)',border:'1px solid rgba(92,138,110,0.3)',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke={C.white} strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round">
                <line x1="8" y1="4.5" x2="8" y2="19.5" />
                <path d="M17.5 4.5 L9 12 L17.5 19.5" />
              </svg>
            </div>
            <div>
              <div style={{fontSize:13,fontWeight:700,color:C.white,lineHeight:1.2,fontFamily:'Lora, serif'}}>KIATI<span style={{fontWeight:400}}>exames</span></div>
              <div style={{fontSize:10,color:'rgba(255,255,255,0.35)',marginTop:2,letterSpacing:'0.04em'}}>Gestão clínica</div>
            </div>
          </div>
        </div>

        {/* Ambientes */}
        <div style={{flex:1,overflowY:'auto',padding:'14px 10px',minHeight:0}}>
          <div style={{fontSize:10,fontWeight:700,color:'rgba(255,255,255,0.28)',letterSpacing:'0.12em',textTransform:'uppercase',padding:'4px 8px 10px'}}>Ambientes</div>
          {envs.map(env => {
            const nNew = subs.filter(s=>s.envId===env.id&&s.status==='novo').length;
            const isActive = selEnv?.id===env.id;
            return (
              <div key={env.id} style={{position:'relative',marginBottom:2}} className="env-item">
                <button onClick={()=>switchEnv(env)}
                  style={{width:'100%',display:'flex',alignItems:'center',justifyContent:'space-between',padding:'9px 34px 9px 10px',borderRadius:10,border:'none',background:isActive?'rgba(92,138,110,0.22)':'transparent',color:isActive?C.white:'rgba(255,255,255,0.5)',cursor:'pointer',fontFamily:'inherit',fontSize:13,fontWeight:isActive?600:400,transition:'all 0.15s',textAlign:'left'}}
                  onMouseEnter={e=>{if(!isActive)e.currentTarget.style.background='rgba(255,255,255,0.06)';if(!isActive)e.currentTarget.style.color='rgba(255,255,255,0.75)';e.currentTarget.closest('.env-item').querySelector('.env-delete').style.opacity='1';}}
                  onMouseLeave={e=>{if(!isActive)e.currentTarget.style.background='transparent';if(!isActive)e.currentTarget.style.color='rgba(255,255,255,0.5)';e.currentTarget.closest('.env-item').querySelector('.env-delete').style.opacity='0';}}>
                  {isActive && <div style={{position:'absolute',left:0,top:'50%',transform:'translateY(-50%)',width:3,height:18,background:C.sageLight,borderRadius:'0 2px 2px 0'}}/>}
                  <span style={{overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',paddingLeft: isActive ? 6 : 0,transition:'padding 0.15s'}}>{env.name}</span>
                  {nNew>0 && <span style={{background:C.sage,color:C.white,fontSize:10,fontWeight:700,borderRadius:20,padding:'1px 7px',flexShrink:0,marginLeft:6}}>{nNew}</span>}
                </button>
                <button className="env-delete"
                  onClick={e=>{e.stopPropagation();setDeleteEnvTarget(env);}}
                  style={{position:'absolute',right:6,top:'50%',transform:'translateY(-50%)',width:22,height:22,borderRadius:6,border:'none',background:'rgba(184,64,64,0.15)',color:'#FF9A9A',cursor:'pointer',display:'flex',alignItems:'center',justifyContent:'center',opacity:0,transition:'opacity 0.15s',padding:0}}
                  onMouseEnter={e=>e.currentTarget.style.background='rgba(184,64,64,0.35)'}
                  onMouseLeave={e=>e.currentTarget.style.background='rgba(184,64,64,0.15)'}>
                  <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6"/><path d="M14 11v6"/><path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/></svg>
                </button>
              </div>
            );
          })}
        </div>

        {/* Criar ambiente */}
        <div style={{padding:'10px 10px 18px',borderTop:'1px solid rgba(255,255,255,0.07)',flexShrink:0}}>
          <button onClick={()=>{setShowCreate(true);setSidebarOpen(false);}}
            style={{width:'100%',padding:'12px 9px',borderRadius:10,border:'1px dashed rgba(92,138,110,0.4)',background:'transparent',color:'rgba(255,255,255,0.55)',fontSize:13,fontWeight:600,cursor:'pointer',transition:'all 0.15s',fontFamily:'inherit'}}
            onMouseEnter={e=>{e.currentTarget.style.borderColor='rgba(92,138,110,0.7)';e.currentTarget.style.color='rgba(255,255,255,0.85)';e.currentTarget.style.background='rgba(92,138,110,0.12)';}}
            onMouseLeave={e=>{e.currentTarget.style.borderColor='rgba(92,138,110,0.4)';e.currentTarget.style.color='rgba(255,255,255,0.55)';e.currentTarget.style.background='transparent';}}>
            + Criar novo ambiente
          </button>
        </div>
      </aside>

      {/* Área principal */}
      <div style={{flex:1,display:'flex',flexDirection:'column',overflow:'hidden',marginLeft:240}} className="main-area">

        {/* Navbar */}
        <div style={{display:'flex',alignItems:'center',gap:12,padding:'0 22px',height:58,background:C.white,borderBottom:`1px solid ${C.borderLight}`,flexShrink:0,boxShadow:'0 1px 0 rgba(30,51,38,0.06)'}}>
          {/* Hamburger mobile */}
          <button onClick={()=>setSidebarOpen(true)} className="hamburger-btn"
            style={{color:C.textMid,background:'none',border:'none',cursor:'pointer',padding:8,minWidth:36,minHeight:36,display:'flex',alignItems:'center',justifyContent:'center'}}>
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
          </button>

          <div style={{flex:1,minWidth:0,paddingRight:6}} className="navbar-crumb">
            {activePatient
              ? <div style={{display:'flex',alignItems:'center',gap:6,minWidth:0}}>
                  <span style={{fontSize:12,color:C.textMuted,cursor:'pointer',transition:'color 0.15s'}} onClick={()=>setActivePatient(null)}
                    onMouseEnter={e=>e.target.style.color=C.sage} onMouseLeave={e=>e.target.style.color=C.textMuted}>{selEnv?.name}</span>
                  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke={C.border} strokeWidth="2"><polyline points="9 18 15 12 9 6"/></svg>
                  <span style={{fontSize:13,fontWeight:600,color:C.text,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',fontFamily:'Lora, serif'}}>{activePatient.name}</span>
                </div>
              : selSub
              ? <div style={{display:'flex',alignItems:'center',gap:6}}>
                  <span style={{fontSize:12,color:C.textMuted,cursor:'pointer',transition:'color 0.15s'}} onClick={backFromViewer}
                    onMouseEnter={e=>e.target.style.color=C.sage} onMouseLeave={e=>e.target.style.color=C.textMuted}>{cameFromPatient ? cameFromPatient.name : selEnv?.name}</span>
                  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke={C.border} strokeWidth="2"><polyline points="9 18 15 12 9 6"/></svg>
                  <span style={{fontSize:13,fontWeight:600,color:C.text,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',fontFamily:'Lora, serif'}}>{selSub.patientName}</span>
                </div>
              : <div style={{display:'flex',alignItems:'baseline',gap:8}}>
                  <span style={{fontSize:15,fontWeight:600,color:C.text,fontFamily:'Lora, serif'}}>{selEnv?.name || 'Selecione um ambiente'}</span>
                  {envSubs.length>0 && <span style={{fontSize:12,color:C.textMuted}}>{envSubs.length} envio{envSubs.length!==1?'s':''}</span>}
                </div>
            }
          </div>

          <div style={{display:'flex',alignItems:'center',gap:6,flexShrink:0}}>
            {selEnv && (
              <button onClick={()=>setShowShare(true)} className="navbar-btn-primary" title="Gerar link de envio"
                style={{display:'flex',alignItems:'center',justifyContent:'center',gap:6,padding:'7px 12px',borderRadius:9,border:'none',background:C.sageDark,color:C.white,fontSize:12,fontWeight:600,cursor:'pointer',boxShadow:`0 2px 8px rgba(44,74,53,0.22)`,transition:'all 0.15s',whiteSpace:'nowrap'}}
                onMouseEnter={e=>{e.currentTarget.style.background=C.sageDeep;}}
                onMouseLeave={e=>{e.currentTarget.style.background=C.sageDark;}}>
                <svg className="navbar-btn-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
                <span className="navbar-btn-label">Gerar link</span>
              </button>
            )}
            {medico?.isAdmin && (
              <button onClick={() => setTelaAdmin(true)} style={{ fontSize: 12, padding: '6px 10px', borderRadius: 8, border: `1px solid ${C.border}`, background: C.white, color: C.sageDark, cursor: 'pointer', fontWeight: 600, whiteSpace:'nowrap' }}>Admin</button>
            )}
            {medico && (
              <div className="navbar-user" title={medico.email || medico.nome} style={{display:'flex',alignItems:'center',gap:8,paddingRight:8,marginRight:2,borderRight:`1px solid ${C.borderLight}`}}>
                <div style={{width:26,height:26,borderRadius:'50%',background:C.sagePale,color:C.sageDark,display:'flex',alignItems:'center',justifyContent:'center',fontSize:11,fontWeight:700,flexShrink:0,border:`1px solid ${C.border}`}}>
                  {(medico.nome || medico.email || '?').trim().charAt(0).toUpperCase()}
                </div>
                <span className="navbar-user-name" style={{fontSize:12,fontWeight:600,color:C.textMid,whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis',maxWidth:140}}>
                  {medico.nome || medico.email}
                </span>
              </div>
            )}
            <button onClick={onLogout} title="Sair"
              style={{ fontSize: 12, padding: '6px 10px', borderRadius: 8, border: `1px solid ${C.border}`, background: C.white, color: C.textMid, cursor: 'pointer', fontWeight: 600, whiteSpace:'nowrap' }}>Sair</button>
          </div>
        </div>

        {/* Banner de convites pendentes */}
        {convitesPendentes.map(c => (
          <div key={c.id} style={{ background: C.sagePale, borderBottom: `1px solid ${C.sage}`, padding: '12px 24px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12, flexShrink: 0 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span style={{ fontSize: 16 }}>📩</span>
              <div>
                <div style={{ fontSize: 13, fontWeight: 600, color: C.sageDark }}>Convite de colaboração — {c.env_name}</div>
                <div style={{ fontSize: 12, color: C.textMid }}>Convidado por <strong>{c.inviter_nome}</strong> para visualizar e editar dados dos pacientes deste ambiente.</div>
              </div>
            </div>
            <div style={{ display: 'flex', gap: 8, flexShrink: 0 }}>
              <button onClick={() => responderConvite(c.id, 'aceitar')} style={{ padding: '6px 14px', borderRadius: 8, border: 'none', background: C.sageDark, color: C.white, fontSize: 12, fontWeight: 600, cursor: 'pointer' }}>Aceitar</button>
              <button onClick={() => responderConvite(c.id, 'recusar')} style={{ padding: '6px 14px', borderRadius: 8, border: `1px solid ${C.border}`, background: C.white, color: C.textMid, fontSize: 12, fontWeight: 600, cursor: 'pointer' }}>Recusar</button>
            </div>
          </div>
        ))}

        {/* Abas Envios / Pacientes */}
        {!selSub && !activePatient && selEnv && (
          <div style={{display:'flex',gap:0,padding:'0 22px',borderBottom:`1px solid ${C.borderLight}`,background:C.white,flexShrink:0}}>
            {[
              {id:'envios',label:'Envios',count:envSubs.length},
              {id:'pacientes',label:'Pacientes',count:0},
              ...(selEnv?.role==='owner' ? [{id:'colaboradores',label:'Colaboradores',count:0}] : [])
            ].map(tab => (
              <button key={tab.id} onClick={()=>setActiveTab(tab.id)}
                style={{padding:'10px 18px',fontSize:13,fontWeight:activeTab===tab.id?600:400,color:activeTab===tab.id?C.sageDark:C.textMuted,background:'none',border:'none',borderBottom:`2px solid ${activeTab===tab.id?C.sage:'transparent'}`,cursor:'pointer',marginBottom:-1,display:'flex',alignItems:'center',gap:6,transition:'all 0.15s',fontFamily:'inherit'}}>
                {tab.label}
                {tab.count>0 && <span style={{fontSize:10,fontWeight:700,background:activeTab===tab.id?C.sagePale:C.creamDark,color:activeTab===tab.id?C.sageDark:C.textMuted,borderRadius:20,padding:'1px 7px'}}>{tab.count}</span>}
              </button>
            ))}
          </div>
        )}

        {/* Conteúdo */}
        <div style={{flex:1,overflowY:'auto'}}>
          {activePatient
            ? <PatientProfile
                envId={activePatient.envId}
                name={activePatient.name}
                onBack={() => setActivePatient(null)}
                onOpenSubmission={(sub) => { setCameFromPatient(activePatient); setActivePatient(null); openSub(mapHistorySub(sub)); }}
              />
            : selSub
            ? <ExamViewer submission={selSub} onBack={backFromViewer}
                onOpenPatient={() => { setCameFromPatient(null); setSelSub(null); setActivePatient({ envId: selSub.envId, name: selSub.patientName }); }}/>
            : activeTab === 'colaboradores'
              ? <AbaColaboradores envId={selEnv.id} />
            : activeTab === 'pacientes'
              ? <PatientList
                  submissions={envSubs}
                  onOpenPatient={(envId, name) => { setSelSub(null); setActivePatient({ envId, name }); }}
                  onNovoEnvio={() => setShowNovoEnvioDoc(true)}
                />
              : <SubmissionList
                  submissions={envSubs}
                  onOpen={openSub}
                  onOpenPatient={(envId, name) => { setSelSub(null); setActivePatient({ envId, name }); }}
                  onShare={()=>setShowShare(true)}
                  onDelete={setDeleteSubTarget}
                />
          }
        </div>
      </div>

      {showCreate && <CreateEnvModal onClose={()=>setShowCreate(false)} onCreate={createEnv}/>}
      {showShare && selEnv && <ShareModal env={selEnv} onClose={()=>setShowShare(false)}/>}
      {deleteEnvTarget && (
        <ConfirmDeleteModal
          title={`Apagar "${deleteEnvTarget.name}"?`}
          description="Todos os envios de pacientes deste ambiente serão apagados permanentemente. Esta ação não pode ser desfeita."
          loading={deletandoEnv}
          error={erroDeleteEnv}
          onClose={()=>{ if (!deletandoEnv) { setDeleteEnvTarget(null); setErroDeleteEnv(false); } }}
          onConfirm={confirmDeleteEnv}
        />
      )}
      {deleteSubTarget && (
        <ConfirmDeleteModal
          title={`Apagar envio de ${deleteSubTarget.patientName}?`}
          description="Os arquivos e dados deste envio serão apagados permanentemente. Esta ação não pode ser desfeita."
          loading={deletandoSub}
          error={erroDeleteSub}
          onClose={()=>{ if (!deletandoSub) { setDeleteSubTarget(null); setErroDeleteSub(false); } }}
          onConfirm={confirmDeleteSub}
        />
      )}
      {showNovoEnvioDoc && selEnv && (
        <SubmissionModal
          modo="novo-paciente"
          envId={selEnv.id}
          patient={null}
          onClose={() => setShowNovoEnvioDoc(false)}
          onSuccess={handleNovoEnvioSuccess}
        />
      )}
    </div>
  );
};

Object.assign(window, { DoctorApp });
