// ═══ GENESIS BUILD perfil-m5-peso-checkin · 2026-07-12 ═══
// Meu Perfil — layout 3 colunas (mockup): identidade+bio · progresso+conquistas · rotação+certs
// Conquistas universais e ostentáveis (Steam-style) + especiais criadas pela gestão

const CERT_SUGESTOES = ['HUET', 'BOSIET', 'CBSP', 'Medical Fitness (OGUK)', 'ASO', 'DP Basic', 'DP Advanced', 'DP Revalidation', 'STCW Basic Safety', 'GMDSS', 'Radar/ARPA', 'Chief Mate', 'Master', 'Passaporte', 'Seaman Book (CIR)', 'Visto'];

const NIVEL_CORES = ['var(--cream-3)', '#A5713F', '#8C9BA5', 'var(--sun)']; // bloqueada · bronze · prata · ouro

const certStatus = (c, lang) => {
  if (!c.validade) return { rotulo: lang==='pt'?'Permanente':'Unlimited', cor: 'var(--teal)', bg: 'rgba(31,87,85,0.10)' };
  const dias = Math.floor((new Date(c.validade).getTime() - Date.now()) / 864e5);
  if (dias < 0) return { rotulo: lang==='pt'?'Vencido':'Expired', cor: 'var(--rose)', bg: 'rgba(177,78,92,0.12)', dias };
  if (dias <= 60) return { rotulo: (lang==='pt'?'Vence em ':'Expires in ') + dias + 'd', cor: 'var(--sun)', bg: 'rgba(198,138,31,0.13)', dias };
  return { rotulo: lang==='pt'?'Válido':'Valid', cor: 'var(--leaf)', bg: 'rgba(92,126,79,0.12)', dias };
};

const PerfilStatCard = ({num, label, cor, sub}) => (
  <div style={{background:'var(--surface)',border:'1px solid var(--line-soft)',borderRadius:16,padding:'13px 14px',boxShadow:'var(--shadow-sm)'}}>
    <div style={{display:'flex',alignItems:'center',gap:7,marginBottom:6}}>
      <span style={{width:8,height:8,borderRadius:3,background:cor||'var(--accent)',display:'inline-block'}}/>
      <span style={{fontFamily:'var(--fm)',fontSize:9,letterSpacing:1,textTransform:'uppercase',color:'var(--muted)'}}>{label}</span>
    </div>
    <div style={{fontFamily:'var(--fs)',fontSize:27,fontWeight:600,letterSpacing:'-1px',lineHeight:1}}>{num == null ? '—' : num}<span style={{fontSize:12,fontFamily:'var(--fm)',fontWeight:400,color:'var(--muted)',marginLeft:5}}>{sub||''}</span></div>
  </div>
);

const PerfilLinha = ({rotulo, valor}) => !valor ? null : (
  <div style={{display:'flex',justifyContent:'space-between',alignItems:'baseline',gap:12,padding:'8px 0',borderBottom:'1px solid var(--cream-3)'}}>
    <span style={{fontFamily:'var(--fm)',fontSize:10.5,letterSpacing:0.8,textTransform:'uppercase',color:'var(--muted)',flexShrink:0}}>{rotulo}</span>
    <span style={{fontSize:13.5,color:'var(--ink)',textAlign:'right',minWidth:0,overflowWrap:'anywhere'}}>{valor}</span>
  </div>
);

// medalha automática — o selo de nível na borda
const Medalha = ({c, lang}) => {
  const cor = NIVEL_CORES[Math.min(c.nivel, 3)];
  const on = c.nivel > 0;
  const progresso = c.proximo ? Math.min(1, c.atual / c.proximo) : 1;
  const nivelNome = lang==='pt' ? ['', 'bronze', 'prata', 'ouro'][Math.min(c.nivel,3)] : ['','bronze','silver','gold'][Math.min(c.nivel,3)];
  return (
    <div title={`${c.desc} — ${c.atual}${c.proximo?` / ${c.proximo}`:''}`}
      style={{display:'flex',flexDirection:'column',alignItems:'center',gap:6,width:100,flexShrink:0}}>
      <div style={{width:66,height:66,borderRadius:'50%',display:'grid',placeItems:'center',fontSize:26,position:'relative',
        background: on ? `radial-gradient(circle at 32% 30%, #ffffff66, transparent 60%), ${cor}` : 'var(--cream-2)',
        border: `3px solid ${on ? cor : 'var(--line)'}`,
        filter: on ? 'none' : 'grayscale(1)', opacity: on ? 1 : 0.45,
        boxShadow: on ? '0 2px 10px rgba(31,42,46,0.18)' : 'none'}}>
        {c.emoji}
        {on && c.nivel >= 3 && <span style={{position:'absolute',top:-7,right:-4,fontSize:14}}>👑</span>}
      </div>
      <div style={{textAlign:'center'}}>
        <div style={{fontSize:11,fontWeight:600,lineHeight:1.2}}>{c.nome}</div>
        <div style={{fontFamily:'var(--fm)',fontSize:8.5,letterSpacing:0.6,textTransform:'uppercase',color: on ? cor : 'var(--muted)',marginTop:1,fontWeight:700}}>
          {on ? nivelNome : '🔒'}
        </div>
      </div>
      {c.proximo != null && (
        <div style={{width:'84%',height:4,borderRadius:999,background:'var(--cream-3)',overflow:'hidden'}}>
          <div style={{height:'100%',width:`${Math.round(progresso*100)}%`,background:on?cor:'var(--sky)',borderRadius:999}}/>
        </div>
      )}
      <div style={{fontFamily:'var(--fm)',fontSize:8.5,color:'var(--muted)',marginTop:-2}}>{c.atual}{c.proximo?`/${c.proximo}`:' ✓'}</div>
    </div>
  );
};

// medalha MINI (36px) — a fileira de ostentação compacta
const MedalhaMini = ({item, tipo, lang, onClick}) => {
  const especial = tipo === 'especial';
  const cor = especial ? 'var(--teal)' : NIVEL_CORES[Math.min(item.nivel||0, 3)];
  const on = especial || (item.nivel||0) > 0;
  return (
    <div onClick={onClick} title={item.nome}
      style={{width:38,height:38,borderRadius:'50%',display:'grid',placeItems:'center',fontSize:16,cursor:'pointer',overflow:'hidden',flexShrink:0,
        background: item.imagem_url ? 'var(--ink)' : (on ? `radial-gradient(circle at 32% 28%, #ffffff55, transparent 60%), ${cor}` : 'var(--cream-2)'),
        border:`2px solid ${on ? cor : 'var(--line)'}`,
        filter: on ? 'none' : 'grayscale(1)', opacity: on ? 1 : 0.4,
        transition:'transform .12s'}}
      onMouseEnter={e=>e.currentTarget.style.transform='scale(1.12)'}
      onMouseLeave={e=>e.currentTarget.style.transform='none'}>
      {item.imagem_url ? <img src={item.imagem_url} alt="" style={{width:'100%',height:'100%',objectFit:'cover'}}/> : (item.emoji || '🏆')}
    </div>
  );
};

// medalha ESPECIAL — a rara, com imagem temática (Mobilização Wahoo, Docagem 2026…)
const MedalhaEspecial = ({e, lang}) => {
  const tier = e.nivel ? [null, '#A5713F', '#8C9BA5', 'var(--sun)'][e.nivel] : null;   // bronze · prata · ouro
  const tierNome = e.nivel ? [null, 'bronze', 'prata', 'ouro'][e.nivel] : null;
  return (
  <div title={`${e.descricao || e.nome}${tierNome ? ` · ${tierNome}` : ''} · ${new Date(e.quando).toLocaleDateString(lang==='pt'?'pt-BR':'en-GB')}`}
    style={{display:'flex',flexDirection:'column',alignItems:'center',gap:6,width:100,flexShrink:0}}>
    <div style={{width:66,height:66,borderRadius:'50%',display:'grid',placeItems:'center',fontSize:26,overflow:'hidden',
      background: e.imagem_url ? 'var(--ink)' : 'radial-gradient(circle at 32% 30%, #ffffff55, transparent 60%), linear-gradient(135deg, var(--teal), var(--sky))',
      border: `3px solid ${tier || 'var(--teal)'}`, boxShadow: '0 2px 12px rgba(31,87,85,0.35)'}}>
      {e.imagem_url ? <img src={e.imagem_url} alt="" style={{width:'100%',height:'100%',objectFit:'cover'}}/> : (e.emoji || '🏆')}
    </div>
    <div style={{textAlign:'center'}}>
      <div style={{fontSize:11,fontWeight:600,lineHeight:1.2}}>{e.nome}</div>
      <div style={{fontFamily:'var(--fm)',fontSize:8.5,letterSpacing:0.6,textTransform:'uppercase',color:tier||'var(--teal)',marginTop:1,fontWeight:700}}>
        {tierNome ? (['','🥉 bronze','🥈 prata','🥇 ouro'][e.nivel]) : (lang==='pt'?'especial':'special')}
      </div>
    </div>
  </div>
  );
};

// modal de DETALHE da medalha (Steam-style): imagem grande + nível + progresso
const MedalhaDetalheModal = ({item, tipo, canManage, token, toast, lang, onClose, onSaved}) => {
  // tipo: 'auto' (conquista calculada) | 'especial' (atribuída)
  const [busy, setBusy] = React.useState(false);
  const imgRef = React.useRef(null);
  const H = () => ({'Authorization':`Bearer ${token()}`});
  const cor = tipo === 'especial' ? 'var(--teal)' : NIVEL_CORES[Math.min(item.nivel||0, 3)];
  const on = tipo === 'especial' || (item.nivel||0) > 0;
  const nivelNome = tipo === 'especial' ? (lang==='pt'?'especial':'special') : (on ? (lang==='pt'?['','bronze','prata','ouro']:['','bronze','silver','gold'])[Math.min(item.nivel,3)] : (lang==='pt'?'bloqueada':'locked'));
  const trocarImagem = async (file) => {
    if (!file) return;
    setBusy(true);
    try {
      const comp = await _pfComprimirFoto(file, 512, 0.8);
      const fd = new FormData(); fd.append('photo', comp, 'conquista.jpg');
      const r = await fetch('/api/upload/photo', { method:'POST', headers:H(), body: fd });
      const d = await r.json();
      if (r.ok && d.url) {
        if (tipo === 'especial') await fetch(`/api/users/conquistas-custom/${item.id}`, { method:'PUT', headers:{...H(),'Content-Type':'application/json'}, body: JSON.stringify({ nome: item.nome, descricao: item.descricao, emoji: item.emoji, imagem_url: d.url }) });
        else await fetch(`/api/users/conquistas-imagem/${item.id}`, { method:'PUT', headers:{...H(),'Content-Type':'application/json'}, body: JSON.stringify({ imagem_url: d.url }) });
        toast.push({icon:'check', title: lang==='pt'?'Imagem temática aplicada 🎨':'Image set 🎨'});
        onSaved && onSaved();
      }
    } catch(e){}
    setBusy(false);
  };
  return (
    <div style={{position:'fixed',inset:0,zIndex:260,background:'rgba(31,42,46,0.6)',backdropFilter:'blur(4px)',display:'flex',alignItems:'center',justifyContent:'center',padding:16}} onClick={onClose}>
      <div onClick={e=>e.stopPropagation()} style={{width:'100%',maxWidth:340,background:'var(--cream)',borderRadius:22,padding:'28px 26px',textAlign:'center'}}>
        <div style={{width:130,height:130,borderRadius:'50%',margin:'0 auto 14px',display:'grid',placeItems:'center',fontSize:52,overflow:'hidden',position:'relative',
          background: item.imagem_url ? 'var(--ink)' : (on ? `radial-gradient(circle at 32% 28%, #ffffff66, transparent 60%), ${cor}` : 'var(--cream-2)'),
          border:`5px solid ${on ? cor : 'var(--line)'}`,
          filter: on ? 'none' : 'grayscale(1)', opacity: on ? 1 : 0.5,
          boxShadow: on ? '0 6px 24px rgba(31,42,46,0.28)' : 'none'}}>
          {item.imagem_url ? <img src={item.imagem_url} alt="" style={{width:'100%',height:'100%',objectFit:'cover'}}/> : (item.emoji || '🏆')}
          {on && tipo !== 'especial' && item.nivel >= 3 && <span style={{position:'absolute',top:2,right:10,fontSize:24}}>👑</span>}
        </div>
        <div style={{fontFamily:'var(--fs)',fontSize:21,letterSpacing:'-0.3px'}}>{item.nome}</div>
        <div style={{fontFamily:'var(--fm)',fontSize:10,letterSpacing:1.2,textTransform:'uppercase',color:cor,fontWeight:700,marginTop:3}}>{nivelNome}{tipo!=='especial' && on && item.nivel < 3 ? ` · ${lang==='pt'?'nível':'level'} ${item.nivel}/3` : ''}</div>
        {(item.desc || item.descricao) && <div style={{fontSize:12.5,color:'var(--muted)',marginTop:8,lineHeight:1.5}}>{item.desc || item.descricao}</div>}
        {tipo === 'auto' && (
          <div style={{marginTop:14}}>
            <div style={{fontFamily:'var(--fs)',fontSize:26,fontWeight:600,letterSpacing:'-0.5px'}}>
              {item.atual}<span style={{fontSize:15,color:'var(--muted)',fontFamily:'var(--fm)',fontWeight:400}}>{item.proximo != null ? ` / ${item.proximo}` : ' ✓'}</span>
            </div>
            {item.proximo != null && (
              <div style={{height:8,borderRadius:999,background:'var(--cream-3)',overflow:'hidden',marginTop:8}}>
                <div style={{height:'100%',width:`${Math.min(100, Math.round((item.atual/item.proximo)*100))}%`,background:on?cor:'var(--sky)',borderRadius:999}}/>
              </div>
            )}
            <div style={{fontFamily:'var(--fm)',fontSize:9.5,color:'var(--muted)',marginTop:6}}>
              {lang==='pt'?'marcos':'milestones'}: {(item.marcos||[]).join(' · ')}
            </div>
          </div>
        )}
        {tipo === 'especial' && item.quando && (
          <div style={{fontFamily:'var(--fm)',fontSize:10,color:'var(--muted)',marginTop:10}}>🗓 {lang==='pt'?'recebida em':'awarded'} {new Date(item.quando).toLocaleDateString(lang==='pt'?'pt-BR':'en-GB')}</div>
        )}
        <div style={{display:'flex',justifyContent:'center',gap:8,marginTop:18}}>
          {canManage && (
            <>
              <button className="btn btn-sm" disabled={busy} onClick={()=>imgRef.current && imgRef.current.click()}>{busy?'…':'🎨 ' + (lang==='pt'?'trocar imagem':'set image')}</button>
              <input ref={imgRef} type="file" accept="image/*" style={{display:'none'}}
                onChange={e=>{ const fs = Array.from(e.target.files||[]); e.target.value=''; if (fs[0]) trocarImagem(fs[0]); }}/>
            </>
          )}
          <button className="btn btn-primary btn-sm" onClick={onClose}>{lang==='pt'?'fechar':'close'}</button>
        </div>
      </div>
    </div>
  );
};

// galeria completa: todas as conquistas, desbloqueadas e bloqueadas
const GaleriaConquistasModal = ({jogo, lang, onAbrir, onClose}) => {
  const desbloq = jogo.conquistas.filter(c=>c.nivel>0).length + (jogo.especiais||[]).length;
  const total = jogo.conquistas.length + (jogo.especiais||[]).length;
  return (
    <div style={{position:'fixed',inset:0,zIndex:255,background:'rgba(31,42,46,0.55)',backdropFilter:'blur(3px)',display:'flex',alignItems:'flex-start',justifyContent:'center',padding:'5vh 16px',overflowY:'auto'}} onClick={onClose}>
      <div onClick={e=>e.stopPropagation()} style={{width:'100%',maxWidth:620,background:'var(--cream)',borderRadius:22,padding:'24px 26px'}}>
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'baseline',marginBottom:4}}>
          <div style={{fontFamily:'var(--fs)',fontSize:21}}>🏅 {lang==='pt'?'Todas as conquistas':'All achievements'}</div>
          <span style={{fontFamily:'var(--fm)',fontSize:11,color:'var(--teal)',fontWeight:700}}>{desbloq}/{total}</span>
        </div>
        <div style={{fontFamily:'var(--fm)',fontSize:10,color:'var(--muted)',marginBottom:16}}>{lang==='pt'?'toque numa medalha pra ver os detalhes e o progresso.':'tap a medal for details.'}</div>
        {(jogo.especiais||[]).length > 0 && (
          <div style={{marginBottom:18}}>
            <div style={{fontFamily:'var(--fm)',fontSize:9.5,letterSpacing:1.2,textTransform:'uppercase',color:'var(--teal)',fontWeight:700,marginBottom:10}}>✦ {lang==='pt'?'especiais':'special'}</div>
            <div style={{display:'flex',gap:10,flexWrap:'wrap'}}>
              {jogo.especiais.map(e => <div key={'e'+e.id} onClick={()=>onAbrir({item:e, tipo:'especial'})} style={{cursor:'pointer'}}><MedalhaEspecial e={e} lang={lang}/></div>)}
            </div>
          </div>
        )}
        <div style={{display:'flex',gap:10,flexWrap:'wrap'}}>
          {jogo.conquistas.map(c => <div key={c.id} onClick={()=>onAbrir({item:c, tipo:'auto'})} style={{cursor:'pointer'}}><Medalha c={c} lang={lang}/></div>)}
        </div>
        <div style={{display:'flex',justifyContent:'flex-end',marginTop:16}}>
          <button className="btn btn-primary btn-sm" onClick={onClose}>{lang==='pt'?'fechar':'close'}</button>
        </div>
      </div>
    </div>
  );
};

// compressão local (mesma receita dos outros módulos)
function _pfComprimirFoto(file, maxW = 1024, quality = 0.75) {
  return new Promise((resolve) => {
    if (!file || !file.type || !file.type.startsWith('image/')) { resolve(file); return; }
    const img = new Image();
    const url = URL.createObjectURL(file);
    img.onload = () => {
      URL.revokeObjectURL(url);
      let { width, height } = img;
      if (width > maxW) { height = Math.round(height * maxW / width); width = maxW; }
      const canvas = document.createElement('canvas');
      canvas.width = width; canvas.height = height;
      canvas.getContext('2d').drawImage(img, 0, 0, width, height);
      canvas.toBlob(b => resolve(b ? new File([b], 'foto.jpg', { type: 'image/jpeg' }) : file), 'image/jpeg', quality);
    };
    img.onerror = () => { URL.revokeObjectURL(url); resolve(file); };
    img.src = url;
  });
}

const CertModal = ({cert, pessoas, userIdFixo, token, toast, lang, onClose, onSaved}) => {
  const [userId, setUserId] = React.useState(cert ? cert.user_id : (userIdFixo || (pessoas[0] && pessoas[0].id) || ''));
  const [tipo, setTipo] = React.useState(cert ? cert.tipo : '');
  const [emissao, setEmissao] = React.useState(cert && cert.emissao ? String(cert.emissao).slice(0,10) : '');
  const [validade, setValidade] = React.useState(cert && cert.validade ? String(cert.validade).slice(0,10) : '');
  const [obs, setObs] = React.useState(cert ? (cert.obs || '') : '');
  const [salvando, setSalvando] = React.useState(false);
  const H = () => ({'Authorization':`Bearer ${token()}`, 'Content-Type':'application/json'});
  const salvar = async () => {
    if (!tipo.trim()) { toast.push({icon:'lock', title: lang==='pt'?'Informe o tipo':'Type required'}); return; }
    setSalvando(true);
    try {
      const body = { user_id: userId, tipo: tipo.trim(), emissao: emissao || null, validade: validade || null, obs };
      const r = cert
        ? await fetch(`/api/users/certs/${cert.id}`, { method:'PUT', headers:H(), body: JSON.stringify(body) })
        : await fetch('/api/users/certs', { method:'POST', headers:H(), body: JSON.stringify(body) });
      if (r.ok) { toast.push({icon:'check', title: lang==='pt'?'Certificado salvo 📜':'Saved 📜'}); onSaved(); onClose(); }
      else { const d = await r.json(); toast.push({icon:'x', title: d.error || 'Erro'}); }
    } catch(e) { toast.push({icon:'x', title:'Erro de rede'}); }
    setSalvando(false);
  };
  return (
    <div style={{position:'fixed',inset:0,zIndex:250,background:'rgba(31,42,46,0.55)',backdropFilter:'blur(3px)',display:'flex',alignItems:'flex-start',justifyContent:'center',padding:'6vh 16px',overflowY:'auto'}} onClick={onClose}>
      <div onClick={e=>e.stopPropagation()} style={{width:'100%',maxWidth:440,background:'var(--cream)',borderRadius:20,padding:'22px 24px'}}>
        <div style={{fontFamily:'var(--fs)',fontSize:19,marginBottom:14}}>📜 {cert ? (lang==='pt'?'Editar certificado':'Edit certificate') : (lang==='pt'?'Novo certificado':'New certificate')}</div>
        <div style={{display:'grid',gap:11}}>
          {!userIdFixo && pessoas.length > 0 && (
            <div><div className="label">{lang==='pt'?'Pessoa':'Person'}</div>
              <select className="select" value={userId} onChange={e=>setUserId(parseInt(e.target.value))} style={{width:'100%'}} disabled={!!cert}>
                {pessoas.map(p => <option key={p.id} value={p.id}>{p.nome || p.email || `#${p.id}`}</option>)}
              </select>
            </div>
          )}
          <div><div className="label">{lang==='pt'?'Tipo':'Type'}</div>
            <input className="input" list="cert-tipos" value={tipo} onChange={e=>setTipo(e.target.value)} placeholder="HUET, BOSIET, Medical…" style={{width:'100%',boxSizing:'border-box'}}/>
            <datalist id="cert-tipos">{CERT_SUGESTOES.map(t => <option key={t} value={t}/>)}</datalist>
          </div>
          <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:9}}>
            <div><div className="label">{lang==='pt'?'Emissão':'Issued'}</div><input type="date" className="input" value={emissao} onChange={e=>setEmissao(e.target.value)} style={{width:'100%',boxSizing:'border-box'}}/></div>
            <div><div className="label">{lang==='pt'?'Validade (vazio = permanente)':'Expiry (blank = unlimited)'}</div><input type="date" className="input" value={validade} onChange={e=>setValidade(e.target.value)} style={{width:'100%',boxSizing:'border-box'}}/></div>
          </div>
          <div><div className="label">{lang==='pt'?'Observações':'Notes'}</div><input className="input" value={obs} onChange={e=>setObs(e.target.value)} style={{width:'100%',boxSizing:'border-box'}}/></div>
          <div style={{display:'flex',justifyContent:'flex-end',gap:8}}>
            <button className="btn" onClick={onClose}>{lang==='pt'?'cancelar':'cancel'}</button>
            <button className="btn btn-primary" disabled={salvando} onClick={salvar}>{salvando?'…':(lang==='pt'?'Salvar':'Save')}</button>
          </div>
        </div>
      </div>
    </div>
  );
};

// modal admin: criar/editar conquista especial (com imagem temática)
// ─── 📸 Check-in da academia com foto (o professor valida) ───
const CheckinFotoModal = ({ lang, toast, onClose, onEnviado }) => {
  const H = () => ({ 'Authorization': `Bearer ${localStorage.getItem('genesis_token')}` });
  const [preview, setPreview] = React.useState(null);
  const [arquivo, setArquivo] = React.useState(null);
  const [peso, setPeso] = React.useState('');
  const [enviando, setEnviando] = React.useState(false);
  const escolher = (e) => {
    const f = e.target.files[0]; if (!f) return;
    setArquivo(f);
    const r = new FileReader(); r.onload = ev => setPreview(ev.target.result); r.readAsDataURL(f);
    e.target.value = '';
  };
  const enviar = async () => {
    if (!arquivo || enviando) return;
    setEnviando(true);
    try {
      const fd = new FormData(); fd.append('photo', arquivo);
      const up = await fetch('/api/upload/photo', { method: 'POST', headers: H(), body: fd });
      const ju = await up.json().catch(() => ({}));
      if (!up.ok || !ju.url) { toast.push({ icon: 'x', title: ju.error || 'Erro no upload da foto' }); setEnviando(false); return; }
      const r = await fetch('/api/users/gym-checkin/solicitar', { method: 'POST', headers: { ...H(), 'Content-Type': 'application/json' }, body: JSON.stringify({ foto_url: ju.url }) });
      const j = await r.json().catch(() => ({}));
      // peso da balança da academia (opcional) → check-in diário de saúde
      const pesoNum = parseFloat(String(peso).replace(',', '.'));
      if (r.ok && !isNaN(pesoNum) && pesoNum > 20 && pesoNum < 300) {
        fetch('/api/saude/checkin', { method: 'PUT', headers: { ...H(), 'Content-Type': 'application/json' }, body: JSON.stringify({ peso: pesoNum }) }).catch(() => {});
      }
      if (r.ok) { toast.push({ icon: 'check', title: '📸 Check-in enviado!', body: lang === 'pt' ? 'Agora é com o professor.' : 'Coach will validate it.' }); onEnviado(); onClose(); }
      else toast.push({ icon: 'x', title: j.error || 'Erro ao enviar' });
    } catch (e) { toast.push({ icon: 'x', title: 'Erro de conexão' }); }
    setEnviando(false);
  };
  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 9200, background: 'rgba(31,42,46,0.5)', display: 'flex', alignItems: 'flex-start', justifyContent: 'center', padding: '8vh 14px', overflowY: 'auto' }}>
      <div onClick={e => e.stopPropagation()} style={{ width: '100%', maxWidth: 400, background: 'var(--cream)', borderRadius: 18, border: '1px solid var(--line-soft)', borderTop: '3px solid var(--leaf)', padding: '18px 20px', boxShadow: 'var(--shadow-lg)' }}>
        <div style={{ fontFamily: 'var(--fs)', fontSize: 19, marginBottom: 4 }}>📸 {lang === 'pt' ? 'Check-in da academia' : 'Gym check-in'}</div>
        <div style={{ fontSize: 12, color: 'var(--muted)', marginBottom: 12 }}>
          {lang === 'pt' ? 'Tira uma foto AÍ DA ACADEMIA — tu no espelho, no equipamento, do jeito que quiser. O professor valida e o treino conta.' : 'Snap a photo at the gym — the coach validates it and your workout counts.'}
        </div>
        {preview ? <img src={preview} alt="" style={{ width: '100%', maxHeight: 300, objectFit: 'contain', borderRadius: 12, background: 'var(--cream-2)', marginBottom: 12 }} /> : null}
        <div style={{ marginBottom: 10 }}>
          <label className="label">{lang === 'pt' ? '⚖ Peso de hoje (balança da academia — opcional)' : '⚖ Today\'s weight (optional)'}</label>
          <input className="input" type="text" inputMode="decimal" placeholder="82.5" style={{ width: '100%', boxSizing: 'border-box' }}
            value={peso} onChange={e => setPeso(e.target.value)} />
        </div>
        <label className="btn" style={{ width: '100%', boxSizing: 'border-box', cursor: 'pointer', textAlign: 'center', marginBottom: 10, display: 'block' }}>
          {preview ? '📷 ' + (lang === 'pt' ? 'Trocar foto' : 'Retake') : '📷 ' + (lang === 'pt' ? 'Tirar / escolher foto' : 'Take / choose photo')}
          <input type="file" accept="image/*" capture="environment" style={{ display: 'none' }} onChange={escolher} />
        </label>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="btn" style={{ flex: 1 }} onClick={onClose}>{lang === 'pt' ? 'Cancelar' : 'Cancel'}</button>
          <button className="btn btn-primary" style={{ flex: 1 }} onClick={enviar} disabled={!arquivo || enviando}>{enviando ? '…' : lang === 'pt' ? 'Enviar 🏋️' : 'Send 🏋️'}</button>
        </div>
      </div>
    </div>
  );
};

const Perfil = ({state, setState, setPage}) => {
  const { lang } = useT();
  const toast = useToast();
  const isMobile = useMobile();
  const token = () => localStorage.getItem('genesis_token');
  const me = state.currentUser || {};
  const canManage = me.role === 'admin' || me.is_staff === true;

  const [stats, setStats] = React.useState(null);
  const [jogo, setJogo] = React.useState(null);
  const [certs, setCerts] = React.useState([]);
  const [radar, setRadar] = React.useState([]);
  const [pessoas, setPessoas] = React.useState([]);
  const [certModal, setCertModal] = React.useState(null);
  const [editPerfil, setEditPerfil] = React.useState(false);
  const [detalhe, setDetalhe] = React.useState(null); // {item, tipo}
  const [galeria, setGaleria] = React.useState(false);
  const [gymStatus, setGymStatus] = React.useState(null);   // null · validado · pendente · recusado (+motivo)
  const [checkinModal, setCheckinModal] = React.useState(false);
  const carregarGymStatus = () => fetch('/api/users/gym-checkin/meu-status', {headers:{'Authorization':`Bearer ${localStorage.getItem('genesis_token')}`}})
    .then(r=>r.ok?r.json():null).then(d=>setGymStatus(d)).catch(()=>{});
  React.useEffect(() => { carregarGymStatus(); }, [me.id]);
  const H = () => ({'Authorization':`Bearer ${token()}`});

  const carregar = () => {
    if (!me.id) return;
    fetch(`/api/users/perfil-stats/${me.id}`, {headers:H()}).then(r=>r.ok?r.json():null).then(d=>d&&setStats(d)).catch(()=>{});
    fetch(`/api/users/conquistas/${me.id}`, {headers:H()}).then(r=>r.ok?r.json():null).then(d=>d&&setJogo(d)).catch(()=>{});
    fetch(`/api/users/certs/${me.id}`, {headers:H()}).then(r=>r.ok?r.json():[]).then(d=>setCerts(Array.isArray(d)?d:[])).catch(()=>{});
    if (canManage) {
      fetch('/api/users/certs-painel', {headers:H()}).then(r=>r.ok?r.json():[]).then(d=>setRadar(Array.isArray(d)?d:[])).catch(()=>{});
      fetch('/api/users', {headers:H()}).then(r=>r.ok?r.json():[]).then(d=>setPessoas((Array.isArray(d)?d:[]).filter(p=>p.nome).sort((a,b)=>a.nome.localeCompare(b.nome)))).catch(()=>{});
    }
  };
  React.useEffect(carregar, [me.id]);

  // dados frescos do próprio perfil (bio pode não estar no currentUser do login antigo)
  const [meuPerfil, setMeuPerfil] = React.useState(me);
  React.useEffect(() => {
    if (!me.id) return;
    fetch(`/api/users/${me.id}`, {headers:H()}).then(r=>r.ok?r.json():null).then(d=>d&&setMeuPerfil({...me, ...d})).catch(()=>{});
  }, [me.id, editPerfil]);

  const aBordo = stats && stats.manifesto && stats.manifesto.status === 'a_bordo';
  const embarque = aBordo && stats.manifesto.embarque ? new Date(stats.manifesto.embarque) : null;
  const REGIME = 28;
  const diasRot = stats ? stats.dias_a_bordo : null;
  const previstoDesembarque = embarque ? new Date(embarque.getTime() + REGIME * 864e5) : null;
  const diasRestantes = (diasRot != null) ? Math.max(0, REGIME - diasRot) : null;
  const progresso = (diasRot != null) ? Math.min(1, diasRot / REGIME) : 0;
  const fmtData = (d) => d ? d.toLocaleDateString(lang==='pt'?'pt-BR':'en-GB', {day:'2-digit', month:'short', year:'numeric'}) : '—';
  const byId = jogo ? Object.fromEntries(jogo.conquistas.map(c=>[c.id,c])) : {};

  const cardBase = {background:'var(--surface)',border:'1px solid var(--line-soft)',borderRadius:18,padding:'18px 20px',boxShadow:'var(--shadow-sm)'};

  return (
    <main style={{padding: isMobile ? '16px 16px 80px' : '28px 34px 56px', flex:1, overflowY:'auto'}}>
      {/* cabeçalho */}
      <div style={{marginBottom:20,display:'flex',justifyContent:'space-between',alignItems:'flex-end',gap:14,flexWrap:'wrap'}}>
        <div>
          <div className="t-eyebrow">{lang==='pt'?'meu perfil':'my profile'}</div>
          <h1 style={{fontFamily:'var(--fs)',fontSize:isMobile?28:36,letterSpacing:'-0.8px',lineHeight:1.05,marginTop:6}}>
            {lang==='pt'?<>Seu <em style={{fontStyle:'italic',color:'var(--accent)'}}>perfil.</em></>:<>Your <em style={{fontStyle:'italic',color:'var(--accent)'}}>profile.</em></>}
          </h1>
          <div style={{fontSize:13,color:'var(--muted)',marginTop:6,maxWidth:440}}>
            {lang==='pt'?'Seu espaço. Mantenha seus dados em dia e acompanhe sua jornada a bordo.':'Your space. Keep your info up to date and track your journey aboard.'}
          </div>
        </div>
        <button className="btn btn-primary btn-sm" onClick={()=>setEditPerfil(true)}>✏️ {lang==='pt'?'Editar perfil':'Edit profile'}</button>
      </div>

      <div style={{display:'grid',gridTemplateColumns:isMobile?'1fr':'320px 1fr 320px',gap:16,alignItems:'start'}}>

        {/* ═══ ESQUERDA: identidade + sobre mim ═══ */}
        <div style={{display:'grid',gap:16}}>
          <div style={{...cardBase, borderTop:'3px solid var(--accent)'}}>
            <div style={{display:'flex',alignItems:'center',gap:14,marginBottom:8}}>
              <div style={{position:'relative',flexShrink:0}}>
                {meuPerfil.foto_url
                  ? <img src={meuPerfil.foto_url} alt="" style={{width:72,height:72,borderRadius:'50%',objectFit:'cover',border:'2px solid var(--cream-3)'}}/>
                  : <div style={{width:72,height:72,borderRadius:'50%',background:'var(--accent)',color:'#fff',display:'grid',placeItems:'center',fontFamily:'var(--fs)',fontSize:25,fontWeight:600}}>{meuPerfil.initials || (meuPerfil.nome||'?').split(' ').map(p=>p[0]).slice(0,2).join('').toUpperCase()}</div>}
                <button onClick={()=>setEditPerfil(true)} title={lang==='pt'?'trocar foto':'change photo'}
                  style={{position:'absolute',bottom:-2,right:-2,width:24,height:24,borderRadius:'50%',border:'2px solid var(--surface)',background:'var(--ink)',color:'#fff',cursor:'pointer',display:'grid',placeItems:'center',fontSize:11}}>📷</button>
              </div>
              <div style={{minWidth:0}}>
                <div style={{fontFamily:'var(--fs)',fontSize:19,letterSpacing:'-0.3px',lineHeight:1.2}}>{meuPerfil.nome || '—'}</div>
                {meuPerfil.funcao && <div style={{fontFamily:'var(--fm)',fontSize:11,color:'var(--accent-2)',marginTop:2}}>{meuPerfil.funcao}</div>}
                <div style={{fontFamily:'var(--fm)',fontSize:10,color:'var(--muted)',marginTop:2}}>{meuPerfil.genesis_id || ''}</div>
              </div>
            </div>
            {stats && (
              <span style={{display:'inline-flex',alignItems:'center',gap:6,padding:'3px 11px',borderRadius:999,fontFamily:'var(--fm)',fontSize:10.5,fontWeight:600,marginBottom:10,
                background: aBordo ? 'rgba(92,126,79,0.14)' : 'var(--cream-2)', color: aBordo ? 'var(--leaf)' : 'var(--muted)',
                border: '1px solid ' + (aBordo ? 'var(--leaf)' : 'var(--line-soft)')}}>
                <span style={{width:7,height:7,borderRadius:'50%',background:aBordo?'var(--leaf)':'var(--muted)',display:'inline-block'}}/>
                {aBordo ? (lang==='pt'?'A bordo':'On board') : (lang==='pt'?'Em casa':'Off board')}
              </span>
            )}
            <PerfilLinha rotulo={<>✉️ E-mail</>} valor={meuPerfil.email}/>
            <PerfilLinha rotulo={<>📞 {lang==='pt'?'Telefone / Satphone':'Phone / Satphone'}</>} valor={meuPerfil.telefone}/>
            <PerfilLinha rotulo={<>🌐 {lang==='pt'?'Nacionalidade':'Nationality'}</>} valor={meuPerfil.nacionalidade}/>
            <PerfilLinha rotulo={<>🎂 {lang==='pt'?'Nascimento':'Date of birth'}</>} valor={meuPerfil.data_nascimento ? fmtData(new Date(meuPerfil.data_nascimento)) : null}/>
            <PerfilLinha rotulo={<>⚓ {lang==='pt'?'No Genesis desde':'Join date'}</>} valor={meuPerfil.created_at ? fmtData(new Date(meuPerfil.created_at)) : null}/>
            <PerfilLinha rotulo={<>🧭 {lang==='pt'?'Rotação atual':'Current rotation'}</>} valor={aBordo && diasRot != null ? `${diasRot} / ${REGIME}` : null}/>

            {/* fileira de ostentação: as medalhas mini */}
            {jogo && (
              <div style={{marginTop:14}}>
                <div style={{display:'flex',justifyContent:'space-between',alignItems:'baseline',marginBottom:8}}>
                  <span style={{fontFamily:'var(--fm)',fontSize:9.5,letterSpacing:1.2,textTransform:'uppercase',color:'var(--muted)'}}>🏅 {lang==='pt'?'conquistas':'achievements'}</span>
                  <button onClick={()=>setGaleria(true)} style={{border:'none',background:'transparent',cursor:'pointer',color:'var(--accent)',fontFamily:'var(--fm)',fontSize:10,textDecoration:'underline'}}>{lang==='pt'?'ver todas':'view all'}</button>
                </div>
                <div style={{display:'flex',gap:6,flexWrap:'wrap'}}>
                  {(jogo.especiais||[]).map(e => <MedalhaMini key={'e'+e.id} item={e} tipo="especial" lang={lang} onClick={()=>setDetalhe({item:e, tipo:'especial'})}/>)}
                  {jogo.conquistas.filter(c=>c.nivel>0).map(c => <MedalhaMini key={c.id} item={c} tipo="auto" lang={lang} onClick={()=>setDetalhe({item:c, tipo:'auto'})}/>)}
                  {jogo.conquistas.filter(c=>c.nivel>0).length === 0 && (jogo.especiais||[]).length === 0 && (
                    <span style={{fontFamily:'var(--fm)',fontSize:10,color:'var(--muted)',fontStyle:'italic'}}>{lang==='pt'?'nenhuma ainda — bora desbloquear!':'none yet!'}</span>
                  )}
                </div>
              </div>
            )}
          </div>

          <div style={{...cardBase, borderTop:'3px solid var(--sky)'}}>
            <div style={{fontFamily:'var(--fs)',fontSize:16,marginBottom:8}}>{lang==='pt'?'Sobre mim':'About me'}</div>
            {meuPerfil.bio
              ? <div style={{fontSize:13,lineHeight:1.6,color:'var(--ink-2)',whiteSpace:'pre-wrap'}}>{meuPerfil.bio}</div>
              : <div style={{fontFamily:'var(--fm)',fontSize:11,color:'var(--muted)',fontStyle:'italic'}}>{lang==='pt'?'conte um pouco de você — vale a conquista 🪪!':'tell us about you — unlocks 🪪!'} <button onClick={()=>setEditPerfil(true)} style={{border:'none',background:'transparent',color:'var(--accent)',cursor:'pointer',fontFamily:'var(--fm)',fontSize:11,textDecoration:'underline'}}>{lang==='pt'?'escrever':'write'}</button></div>}
            {(meuPerfil.end_logradouro || meuPerfil.end_cidade) && <div style={{fontFamily:'var(--fm)',fontSize:10.5,color:'var(--muted)',marginTop:10}}>📍 {[meuPerfil.end_logradouro, meuPerfil.end_numero, meuPerfil.end_complemento, meuPerfil.end_cidade, meuPerfil.end_estado].filter(Boolean).join(', ')}</div>}
          </div>
        </div>

        {/* ═══ MEIO: progresso + conquistas ═══ */}
        <div style={{display:'grid',gap:16}}>
          <div style={{...cardBase, borderTop:'3px solid var(--accent)'}}>
            <div style={{fontFamily:'var(--fs)',fontSize:17,marginBottom:2}}>{lang==='pt'?'Meu progresso':'My progress'}</div>
            <div style={{fontFamily:'var(--fm)',fontSize:10,color:'var(--muted)',marginBottom:12}}>{lang==='pt'?'sua atividade e evolução num relance — tudo dado real.':'your activity at a glance.'}</div>
            <div style={{display:'grid',gridTemplateColumns:isMobile?'1fr 1fr':'repeat(4, 1fr)',gap:10}}>
              <PerfilStatCard num={byId.mar ? byId.mar.atual : null} sub={lang==='pt'?'dias':'days'} label={lang==='pt'?'total a bordo':'time on board'} cor="var(--teal)"/>
              <PerfilStatCard num={byId.gym_ano ? byId.gym_ano.atual : null} sub={lang==='pt'?'no ano':'this yr'} label={lang==='pt'?'academia':'gym days'} cor="var(--leaf)"/>
              <PerfilStatCard num={byId.fainas ? byId.fainas.atual : null} label={lang==='pt'?'fainas concluídas':'tasks done'} cor="var(--sun)"/>
              <PerfilStatCard num={byId.gym_streak ? byId.gym_streak.atual : null} sub={lang==='pt'?'dias':'days'} label={lang==='pt'?'sequência atual':'current streak'} cor="var(--rose)"/>
            </div>
            <div style={{marginTop:12,display:'flex',alignItems:'center',justifyContent:'space-between',gap:10,flexWrap:'wrap'}}>
              {gymStatus && gymStatus.hoje === 'validado' ? (
                <span style={{display:'inline-flex',alignItems:'center',gap:7,padding:'7px 13px',borderRadius:999,background:'rgba(92,126,79,0.14)',border:'1px solid var(--leaf)',fontFamily:'var(--fm)',fontSize:10.5,color:'var(--leaf)',fontWeight:700}}>
                  ✓ {lang==='pt'?'treino de hoje validado!':'today validated!'}
                </span>
              ) : gymStatus && gymStatus.hoje === 'pendente' ? (
                <span style={{display:'inline-flex',alignItems:'center',gap:7,padding:'7px 13px',borderRadius:999,background:'var(--cream-2)',border:'1px solid var(--sun)',fontFamily:'var(--fm)',fontSize:10.5,color:'var(--sun)',fontWeight:700}}>
                  ⏳ {lang==='pt'?'check-in aguardando o professor':'awaiting coach'}
                </span>
              ) : (
                <span style={{display:'inline-flex',alignItems:'center',gap:8,flexWrap:'wrap'}}>
                  <button className="btn btn-primary btn-sm" style={{fontSize:12.5}} onClick={()=>setCheckinModal(true)}>
                    📸 {lang==='pt'?'Check-in da academia':'Gym check-in'}
                  </button>
                  {gymStatus && gymStatus.hoje === 'recusado' ? <span style={{fontFamily:'var(--fm)',fontSize:10,color:'var(--rose)'}}>✗ {lang==='pt'?'recusado':'declined'}{gymStatus.motivo?`: ${gymStatus.motivo}`:''} — {lang==='pt'?'tenta de novo':'try again'}</span> : null}
                </span>
              )}
              {jogo && (
                <span style={{display:'inline-flex',alignItems:'baseline',gap:8,fontFamily:'var(--fm)'}}>
                  <span style={{fontSize:10,letterSpacing:1,textTransform:'uppercase',color:'var(--teal)',fontWeight:700}}>⭐ {lang==='pt'?'pontos':'points'}</span>
                  <span style={{fontFamily:'var(--fs)',fontSize:24,fontWeight:600,color:'var(--teal)',letterSpacing:'-0.5px'}}>{jogo.pontos.toLocaleString(lang==='pt'?'pt-BR':'en-GB')}</span>
                </span>
              )}
            </div>
          </div>

          <div onClick={()=>setGaleria(true)} style={{...cardBase, borderTop:'3px solid var(--sun)', cursor:'pointer'}}
            onMouseEnter={e=>e.currentTarget.style.boxShadow='var(--shadow-lg)'}
            onMouseLeave={e=>e.currentTarget.style.boxShadow='var(--shadow-sm)'}>
            <div style={{display:'flex',justifyContent:'space-between',alignItems:'baseline',marginBottom:2}}>
              <div style={{fontFamily:'var(--fs)',fontSize:17}}>🏅 {lang==='pt'?'Conquistas':'Achievements'}</div>
              {jogo && <span style={{fontFamily:'var(--fm)',fontSize:11,color:'var(--teal)',fontWeight:700}}>{jogo.conquistas.filter(c=>c.nivel>0).length + (jogo.especiais||[]).length}/{jogo.conquistas.length + (jogo.especiais||[]).length}</span>}
            </div>
            <div style={{fontFamily:'var(--fm)',fontSize:10,color:'var(--muted)',marginBottom:12}}>{lang==='pt'?'toque pra ver a galeria completa — desbloqueadas e por desbloquear.':'tap for the full gallery.'}</div>
            <div style={{display:'flex',gap:7,flexWrap:'wrap'}}>
              {jogo ? (
                <>
                  {(jogo.especiais||[]).slice(0,3).map(e => <MedalhaMini key={'e'+e.id} item={e} tipo="especial" lang={lang} onClick={()=>setDetalhe({item:e, tipo:'especial'})}/>)}
                  {jogo.conquistas.map(c => <MedalhaMini key={c.id} item={c} tipo="auto" lang={lang} onClick={()=>setDetalhe({item:c, tipo:'auto'})}/>)}
                </>
              ) : <span style={{fontFamily:'var(--fm)',fontSize:11,color:'var(--muted)'}}>carregando…</span>}
            </div>
          </div>

        </div>

        {/* ═══ DIREITA: rotação + certificações + radar ═══ */}
        <div style={{display:'grid',gap:16}}>
          <div style={{...cardBase, borderTop:'3px solid var(--teal)'}}>
            <div style={{fontFamily:'var(--fs)',fontSize:16,marginBottom:12}}>🗓 {lang==='pt'?'Rotação atual':'Current rotation'}</div>
            {aBordo && embarque ? (
              <>
                <div style={{display:'flex',justifyContent:'space-between',gap:10,marginBottom:12}}>
                  <div>
                    <div style={{fontFamily:'var(--fm)',fontSize:9,letterSpacing:1,textTransform:'uppercase',color:'var(--muted)'}}>{lang==='pt'?'Embarque':'Embark'}</div>
                    <div style={{fontFamily:'var(--fs)',fontSize:15,marginTop:2}}>{fmtData(embarque)}</div>
                  </div>
                  <div style={{textAlign:'right'}}>
                    <div style={{fontFamily:'var(--fm)',fontSize:9,letterSpacing:1,textTransform:'uppercase',color:'var(--muted)'}}>{lang==='pt'?'Desemb. previsto':'Disembark'}</div>
                    <div style={{fontFamily:'var(--fs)',fontSize:15,marginTop:2}}>{fmtData(previstoDesembarque)}</div>
                  </div>
                </div>
                <div style={{height:9,borderRadius:999,background:'var(--cream-3)',overflow:'hidden'}}>
                  <div style={{height:'100%',width:`${Math.round(progresso*100)}%`,borderRadius:999,background:'linear-gradient(90deg, var(--teal), var(--leaf))'}}/>
                </div>
                <div style={{display:'flex',justifyContent:'space-between',marginTop:7,fontFamily:'var(--fm)',fontSize:10,color:'var(--muted)'}}>
                  <span>{diasRot}/{REGIME} {lang==='pt'?'dias':'days'}</span>
                  <span style={{color: diasRestantes <= 3 ? 'var(--accent-2)' : 'var(--teal)', fontWeight:600}}>
                    {diasRestantes === 0 ? (lang==='pt'?'troca! 🎉':'crew change! 🎉') : `${diasRestantes} ${lang==='pt'?'dias pra lancha':'days to go'}`}
                  </span>
                </div>
              </>
            ) : (
              <div style={{fontFamily:'var(--fm)',fontSize:11.5,color:'var(--muted)'}}>
                {stats ? (lang==='pt'?'Em casa — bom descanso! 🏠':'Off board — enjoy! 🏠') : (lang==='pt'?'carregando…':'loading…')}
              </div>
            )}
          </div>

          <div style={{...cardBase, borderTop:'3px solid var(--sun)'}}>
            <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:10}}>
              <div style={{fontFamily:'var(--fs)',fontSize:16}}>📜 {lang==='pt'?'Certificações':'Certifications'}</div>
              {canManage && <button className="btn btn-sm" onClick={()=>setCertModal({ userIdFixo: me.id })}>+</button>}
            </div>
            {certs.length === 0 ? (
              <div style={{fontFamily:'var(--fm)',fontSize:11,color:'var(--muted)',fontStyle:'italic'}}>{lang==='pt'?'nenhum cadastrado.':'none yet.'}</div>
            ) : (
              <div style={{display:'grid',gap:6}}>
                {certs.map(c => {
                  const st = certStatus(c, lang);
                  return (
                    <div key={c.id} style={{display:'flex',alignItems:'center',gap:8,padding:'7px 10px',borderRadius:10,border:'1px solid var(--cream-3)',background:'var(--cream)'}}>
                      <div style={{flex:1,minWidth:0}}>
                        <div style={{fontSize:12.5,fontWeight:600,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{c.tipo}</div>
                        <div style={{fontFamily:'var(--fm)',fontSize:9.5,color:'var(--muted)'}}>{c.validade ? new Date(c.validade).toLocaleDateString(lang==='pt'?'pt-BR':'en-GB') : (lang==='pt'?'sem vencimento':'no expiry')}</div>
                      </div>
                      <span style={{padding:'2px 9px',borderRadius:999,fontFamily:'var(--fm)',fontSize:9.5,fontWeight:700,color:st.cor,background:st.bg,border:`1px solid ${st.cor}`,flexShrink:0}}>{st.rotulo}</span>
                      {canManage && (
                        <span style={{display:'flex',gap:3,flexShrink:0}}>
                          <button onClick={()=>setCertModal({ cert: c })} style={{border:'none',background:'transparent',cursor:'pointer',fontSize:12}}>✏️</button>
                          <button onClick={async ()=>{ if(!confirm(lang==='pt'?'Excluir?':'Delete?')) return; await fetch(`/api/users/certs/${c.id}`, {method:'DELETE', headers:H()}); carregar(); }} style={{border:'none',background:'transparent',cursor:'pointer',fontSize:12,color:'var(--rose)'}}>×</button>
                        </span>
                      )}
                    </div>
                  );
                })}
              </div>
            )}
          </div>

          {canManage && (
            <div style={{...cardBase, borderTop:'3px solid var(--rose)'}}>
              <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:4}}>
                <div style={{fontFamily:'var(--fs)',fontSize:16}}>🛟 {lang==='pt'?'Radar da tripulação':'Crew radar'}</div>
                <button className="btn btn-sm" onClick={()=>setCertModal({})}>+</button>
              </div>
              <div style={{fontFamily:'var(--fm)',fontSize:9.5,color:'var(--muted)',marginBottom:10}}>{lang==='pt'?'certs vencendo em 90d — avisos automáticos 60/30/7.':'expiring within 90 days.'}</div>
              {radar.length === 0 ? (
                <div style={{fontFamily:'var(--fm)',fontSize:11,color:'var(--leaf)'}}>✓ {lang==='pt'?'tudo em dia na frota!':'all clear!'}</div>
              ) : (
                <div style={{display:'grid',gap:5}}>
                  {radar.map(c => {
                    const st = certStatus(c, lang);
                    return (
                      <div key={c.id} style={{display:'flex',alignItems:'center',gap:8,padding:'6px 10px',borderRadius:9,border:`1px solid ${st.cor}`,background:st.bg}}>
                        <div style={{flex:1,minWidth:0,fontSize:11.5,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}><b>{c.nome || `#${c.user_id}`}</b> — {c.tipo}</div>
                        <span style={{fontFamily:'var(--fm)',fontSize:9.5,fontWeight:700,color:st.cor,flexShrink:0}}>{st.rotulo}</span>
                        <button onClick={()=>setCertModal({ cert: c })} style={{border:'none',background:'transparent',cursor:'pointer',fontSize:11,flexShrink:0}}>✏️</button>
                      </div>
                    );
                  })}
                </div>
              )}
            </div>
          )}
        </div>
      </div>

      {editPerfil && <PersonDrawer user={meuPerfil} onClose={()=>setEditPerfil(false)} onSaved={()=>{ setEditPerfil(false); carregar(); }} onDelete={()=>{}}/>}
      {checkinModal && <CheckinFotoModal lang={lang} toast={toast} onClose={()=>setCheckinModal(false)} onEnviado={carregarGymStatus}/>}
      {detalhe && <MedalhaDetalheModal item={detalhe.item} tipo={detalhe.tipo} canManage={canManage} token={token} toast={toast} lang={lang} onClose={()=>setDetalhe(null)} onSaved={()=>{ setDetalhe(null); carregar(); }}/>}
      {galeria && jogo && <GaleriaConquistasModal jogo={jogo} lang={lang} onAbrir={(d)=>{ setGaleria(false); setDetalhe(d); }} onClose={()=>setGaleria(false)}/>}
      {certModal && <CertModal cert={certModal.cert} userIdFixo={certModal.userIdFixo} pessoas={pessoas} token={token} toast={toast} lang={lang} onClose={()=>setCertModal(null)} onSaved={carregar}/>}
    </main>
  );
};
