// ═══════════════════════════════════════════════════════════════
// SCREEN · Movimentação Profissional · 3 subguias (Admissão · Promoção · Desligamento)
// Pedido pela Maria no Site AVD (3): GC e Gestor abrem solicitações
// como cards num kanban. Cada card tem formulário, subtarefas e
// comentários. Acessos: GC, Financeiro, Líder da vaga.
// ═══════════════════════════════════════════════════════════════

// ── Form genérico construído a partir de MOV_FORM_DEF ──────────
// type 'motivo-secundario': select que lê motivos de getMotivosDeslig() + botão "+ Novo" inline
const CampoMotivoSecundario = ({ val, setV }) => {
  const [motivos, setMotivos] = useState(() => (typeof getMotivosDeslig === 'function' ? getMotivosDeslig() : []));
  const [novoTxt, setNovoTxt] = useState('');
  const [adicionando, setAdicionando] = useState(false);

  function adicionar() {
    const t = (novoTxt || '').trim();
    if (!t) return;
    const id = 'm_' + Date.now();
    const novos = [...motivos, { id, label: t, cor: '#4A5560' }];
    setMotivos(novos);
    if (typeof salvarMotivosDeslig === 'function') salvarMotivosDeslig(novos);
    setV(id);
    setNovoTxt('');
    setAdicionando(false);
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      <div style={{ display: 'flex', gap: 6 }}>
        <select value={val} onChange={e => setV(e.target.value)}
          style={{ flex: 1, border: '1px solid var(--escalab-line)', borderRadius: 8, padding: '10px 12px', fontSize: 14, fontFamily: 'var(--font-sans)', outline: 0, background: '#fff' }}>
          <option value="">· selecione um motivo ·</option>
          {motivos.map(m => <option key={m.id} value={m.id}>{m.label}</option>)}
        </select>
        <button type="button" onClick={() => setAdicionando(a => !a)}
          style={{ border: '1px solid var(--escalab-brand)', background: adicionando ? 'var(--escalab-brand)' : '#fff', color: adicionando ? '#fff' : 'var(--escalab-brand)', borderRadius: 8, padding: '0 14px', cursor: 'pointer', fontSize: 12.5, fontFamily: 'var(--font-sans)', fontWeight: 600, whiteSpace: 'nowrap' }}>
          + Novo
        </button>
      </div>
      {adicionando && (
        <div style={{ display: 'flex', gap: 6, padding: 10, background: 'var(--escalab-paper)', borderRadius: 8, border: '1px solid var(--escalab-line)' }}>
          <input value={novoTxt} onChange={e => setNovoTxt(e.target.value)} onKeyDown={e => e.key === 'Enter' && (e.preventDefault(), adicionar())}
            placeholder='Ex: "Mudança para outro estado"' autoFocus
            style={{ flex: 1, border: '1px solid var(--escalab-line)', borderRadius: 7, padding: '8px 11px', fontSize: 13.5, fontFamily: 'var(--font-sans)', outline: 0, background: '#fff' }} />
          <button type="button" onClick={adicionar} disabled={!novoTxt.trim()}
            style={{ border: 0, background: 'var(--escalab-brand)', color: '#fff', borderRadius: 7, padding: '0 16px', cursor: novoTxt.trim() ? 'pointer' : 'not-allowed', fontSize: 12.5, fontWeight: 600, opacity: novoTxt.trim() ? 1 : .5 }}>
            Adicionar
          </button>
        </div>
      )}
    </div>
  );
};

const FormularioMov = ({ campos, dados, onChange }) => (
  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 12 }} className="mobile-col1">
    {campos.map(c => {
      const val = dados[c.id] ?? '';
      const setV = v => onChange(c.id, v);
      const reqMark = c.req ? <span style={{ color: 'var(--escalab-brand-deep)' }}> *</span> : null;
      const wide = c.type === 'textarea' || c.type === 'motivo-secundario';
      return (
        <div key={c.id} style={{ gridColumn: wide ? '1 / -1' : 'auto' }}>
          <Field label={<>{c.label}{reqMark}</>}>
            {c.type === 'textarea' ? (
              <textarea value={val} onChange={e => setV(e.target.value)} rows={3}
                style={{ width: '100%', border: '1px solid var(--escalab-line)', borderRadius: 8, padding: '10px 12px', fontSize: 14, fontFamily: 'var(--font-sans)', outline: 0, resize: 'vertical', boxSizing: 'border-box' }} />
            ) : c.type === 'select' ? (
              <SelectInput value={val} onChange={setV} options={[{ value: '', label: '· selecione ·' }, ...c.options.map(o => ({ value: o, label: o }))]} />
            ) : c.type === 'motivo-secundario' ? (
              <CampoMotivoSecundario val={val} setV={setV} />
            ) : c.type === 'date' ? (
              <Input type="date" value={val} onChange={setV} />
            ) : c.type === 'number' ? (
              <Input type="number" value={val} onChange={v => setV(v === '' ? '' : Number(v))} prefix={c.id.toLowerCase().includes('valor') ? 'R$' : undefined} />
            ) : c.type === 'email' ? (
              <Input type="email" value={val} onChange={setV} placeholder="alguem@escalab.com.br" />
            ) : (
              <Input value={val} onChange={setV} />
            )}
          </Field>
        </div>
      );
    })}
  </div>
);

// ── Modal: criar nova solicitação ───────────────────────────────
const ModalNovaSolMov = ({ tipo, onClose, onSalvar, user }) => {
  const campos = MOV_FORM_DEF[tipo] || [];
  const initial = useMemo(() => {
    const d = {};
    // Pré-preencher solicitante + email com o usuário logado quando possível
    if (campos.find(c => c.id === 'solicitante')) d.solicitante = user?.nome || '';
    if (campos.find(c => c.id === 'email'))       d.email       = user?.email || '';
    return d;
  }, [tipo]);
  const [dados, setDados] = useState(initial);

  const valido = campos.filter(c => c.req).every(c => {
    const v = dados[c.id];
    return v !== undefined && v !== null && String(v).trim().length > 0;
  });

  function setCampo(id, v) { setDados(d => ({ ...d, [id]: v })); }

  function salvar() {
    if (!valido) return;
    const sol = {
      id: gerarIdMov(tipo),
      etapa: MOV_ETAPAS[tipo][0].id,
      criadoEm: new Date().toISOString().slice(0, 10),
      criadoPor: user?.nome || dados.solicitante || 'Sistema',
      dados,
      subtarefas: [],
      comentarios: [],
    };
    onSalvar(sol);
  }

  return (
    <Modal open onClose={onClose} title={`Nova solicitação · ${MOV_LABEL[tipo]}`} width={760}
      footer={<>
        <Button variant="ghost" onClick={onClose}>Cancelar</Button>
        <Button variant="primary" onClick={salvar} disabled={!valido}>Criar card</Button>
      </>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        <Banner tone="info">
          {tipo === 'admissao' && 'Preencha os dados da nova vaga. O card entra na etapa "Inicial" e segue até "Admitido".'}
          {tipo === 'promocao' && 'Preencha os dados da movimentação. O card passa por Documentos → Implementação → Concluído.'}
          {tipo === 'desligamento' && 'Preencha os dados do desligamento. Esse card também é criado automaticamente quando o GC desliga um colaborador pelo fluxo de Colaboradores.'}
        </Banner>
        <FormularioMov campos={campos} dados={dados} onChange={setCampo} />
      </div>
    </Modal>
  );
};

// ── Modal: detalhe do card (form, subtarefas, comentários) ──────
const ModalDetalheMov = ({ tipo, sol, etapas, onClose, onSave, onDelete, user, podeEditar }) => {
  const [aba, setAba] = useState('form');
  const [draft, setDraft] = useState(() => JSON.parse(JSON.stringify(sol)));

  function setDadosCampo(id, v) {
    setDraft(d => ({ ...d, dados: { ...d.dados, [id]: v } }));
  }
  function marcarNovidade(kind) {
    return {
      novidade: { ts: Date.now(), autor: user?.nome || 'Anônimo', kind },
      vistoPor: { ...(draft.vistoPor || {}), [user?.id]: Date.now() },
    };
  }
  function moverEtapa(novaEt) {
    setDraft(d => ({ ...d, etapa: novaEt, ...marcarNovidade('mov') }));
  }
  function toggleMarcado(colabId) {
    setDraft(d => {
      const atual = d.marcadosIds || [];
      const novo = atual.includes(colabId) ? atual.filter(x => x !== colabId) : [...atual, colabId];
      return { ...d, marcadosIds: novo };
    });
  }

  function addSubtarefa() {
    setDraft(d => ({ ...d, subtarefas: [...(d.subtarefas || []), { id: Date.now(), txt: '', resp: '', prazo: '', feita: false }] }));
  }
  function setSubtarefa(id, patch) {
    setDraft(d => ({ ...d, subtarefas: (d.subtarefas || []).map(s => s.id === id ? { ...s, ...patch } : s) }));
  }
  function rmSubtarefa(id) {
    setDraft(d => ({ ...d, subtarefas: (d.subtarefas || []).filter(s => s.id !== id) }));
  }

  const [novoComentario, setNovoComentario] = useState('');
  function addComentario() {
    if (!novoComentario.trim()) return;
    const c = { autor: user?.nome || 'Anônimo', em: new Date().toISOString().slice(0, 10), txt: novoComentario.trim() };
    // ordem cronológica: mais antigo no topo, novo vai pro FINAL
    // PDF Site AVD 5 · item 21: marcar novidade para que GC, financeiro e líder vejam alerta
    setDraft(d => ({ ...d, comentarios: [...(d.comentarios || []), c], ...marcarNovidade('comentario') }));
    setNovoComentario('');
  }

  // Formato dd/mm/yyyy · aceita 'YYYY-MM-DD' ou ISO completo; cai pra string original se não parsear
  function fmtData(s) {
    if (!s) return '·';
    const m = String(s).match(/^(\d{4})-(\d{2})-(\d{2})/);
    if (m) return `${m[3]}/${m[2]}/${m[1]}`;
    return s;
  }

  function salvar() { onSave(draft); }

  const etapaAtual = etapas.find(e => e.id === draft.etapa) || etapas[0];
  const campos = MOV_FORM_DEF[tipo];
  const nomePrincipal = draft.dados.nomeColaborador || draft.dados.solicitante || '·';

  return (
    <Modal open onClose={onClose} title={`${MOV_LABEL[tipo]} · ${nomePrincipal}`} width={820}
      footer={<>
        {podeEditar && <Button variant="ghost" onClick={() => { if (confirm('Remover este card?')) { onDelete(draft.id); } }} style={{ color: '#C0392B', marginRight: 'auto' }}>Excluir</Button>}
        <Button variant="ghost" onClick={onClose}>Fechar</Button>
        {podeEditar && <Button variant="primary" onClick={salvar}>Salvar alterações</Button>}
      </>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        {/* Cabeçalho + seletor de etapa */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
          <div style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '6px 12px', borderRadius: 999, background: etapaAtual.bg, color: etapaAtual.color, fontWeight: 700, fontSize: 12.5, letterSpacing: '.04em', textTransform: 'uppercase' }}>
            <span style={{ width: 8, height: 8, borderRadius: 999, background: etapaAtual.color }} />
            {etapaAtual.label}
          </div>
          <span style={{ fontSize: 12, color: 'var(--escalab-mute)' }}>#{draft.id} · criado em {fmtData(draft.criadoEm)} por {draft.criadoPor}</span>
          <button onClick={() => {
            const link = `${window.location.origin}${window.location.pathname}?mov=${tipo}&id=${draft.id}`;
            navigator.clipboard?.writeText(link).then(() => alert('Link copiado!\n\n' + link)).catch(() => prompt('Copie o link:', link));
          }} style={{ marginLeft: 'auto', border: '1px solid var(--escalab-line)', background: '#fff', borderRadius: 8, padding: '5px 11px', cursor: 'pointer', fontSize: 12, color: 'var(--escalab-slate)', fontFamily: 'var(--font-sans)', display: 'inline-flex', alignItems: 'center', gap: 5 }}>
            <Icon name="send" size={11} /> Copiar link compartilhável
          </button>
          {draft.dados.email && (
            <a href={`mailto:${draft.dados.email}?subject=${encodeURIComponent(`[Escalab] ${MOV_LABEL[tipo]} #${draft.id} · ${nomePrincipal}`)}&body=${encodeURIComponent(`Olá!\n\nAcompanhe o andamento da movimentação #${draft.id} (${MOV_LABEL[tipo]}) de ${nomePrincipal}.\n\nEtapa atual: ${etapaAtual.label}\n\nAcesse: ${window.location.origin}${window.location.pathname}?mov=${tipo}&id=${draft.id}`)}`}
              style={{ border: '1px solid var(--escalab-brand-soft)', background: 'var(--escalab-brand-tint)', borderRadius: 8, padding: '5px 11px', fontSize: 12, color: 'var(--escalab-brand-deep)', textDecoration: 'none', fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 5 }}>
              <Icon name="bell" size={11} /> Avisar solicitante
            </a>
          )}
        </div>
        {podeEditar && (
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            <span style={{ fontSize: 11.5, fontWeight: 700, color: 'var(--escalab-mute)', alignSelf: 'center', letterSpacing: '.1em', textTransform: 'uppercase' }}>Mover para:</span>
            {etapas.map(et => {
              const ativo = draft.etapa === et.id;
              return (
                <button key={et.id} onClick={() => moverEtapa(et.id)} style={{
                  border: `1px solid ${ativo ? et.color : 'var(--escalab-line)'}`,
                  background: ativo ? et.color : '#fff',
                  color: ativo ? '#fff' : 'var(--escalab-slate)',
                  borderRadius: 999, padding: '6px 12px', cursor: 'pointer',
                  fontSize: 12.5, fontWeight: ativo ? 700 : 500, fontFamily: 'var(--font-sans)'
                }}>{et.label}</button>
              );
            })}
          </div>
        )}

        {/* Pessoas que podem ver · PDF Site AVD 5 · item 20 */}
        {(user?.perfil === 'admin' || user?.perfil === 'financeiro' || (user?.perfil === 'gestor' && (draft.marcadosIds || []).includes(user.id))) && (
          <div style={{ background: 'var(--escalab-paper)', border: '1px solid var(--escalab-line)', borderRadius: 10, padding: '12px 14px' }}>
            <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 10, marginBottom: 8, flexWrap: 'wrap' }}>
              <div style={{ fontSize: 11.5, fontWeight: 700, color: 'var(--escalab-mute)', letterSpacing: '.1em', textTransform: 'uppercase' }}>Pessoas que podem ver este card</div>
              <div style={{ fontSize: 11, color: 'var(--escalab-mute)' }}>GC e Financeiro veem sempre · Líder marcado também vê</div>
            </div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
              {(draft.marcadosIds || []).length === 0 && <span style={{ fontSize: 12, color: 'var(--escalab-mute)', fontStyle: 'italic' }}>Nenhum líder marcado.</span>}
              {(draft.marcadosIds || []).map(id => {
                const c = COLABORADORES.find(x => x.id === id);
                if (!c) return null;
                return (
                  <span key={id} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, background: '#fff', border: '1px solid var(--escalab-line)', borderRadius: 999, padding: '3px 10px', fontSize: 12 }}>
                    {c.nome.split(' ').slice(0,2).join(' ')}
                    {podeEditar && <button onClick={() => toggleMarcado(id)} style={{ border: 0, background: 'transparent', cursor: 'pointer', color: 'var(--escalab-mute)', padding: 0, lineHeight: 1 }} title="Remover"><Icon name="close" size={11} /></button>}
                  </span>
                );
              })}
            </div>
            {podeEditar && (
              <div style={{ display: 'flex', gap: 8, marginTop: 10, alignItems: 'center' }}>
                <select onChange={e => { if (e.target.value) { toggleMarcado(Number(e.target.value)); e.target.value = ''; } }}
                  style={{ border: '1px solid var(--escalab-line)', borderRadius: 7, padding: '6px 10px', fontSize: 12.5, fontFamily: 'var(--font-sans)', outline: 0, background: '#fff' }}>
                  <option value="">+ Adicionar pessoa que pode ver</option>
                  {COLABORADORES
                    .filter(c => (c.nivel === 'lider' || c.nivel === 'diretor') && !(draft.marcadosIds || []).includes(c.id))
                    .map(c => <option key={c.id} value={c.id}>{c.nome}</option>)
                  }
                </select>
              </div>
            )}
          </div>
        )}

        {/* Tabs */}
        <Tabs
          tabs={[
            { id: 'form',     label: 'Formulário' },
            { id: 'tarefas',  label: `Subtarefas (${(draft.subtarefas || []).length})` },
            { id: 'coment',   label: `Comentários (${(draft.comentarios || []).length})` },
          ]}
          active={aba}
          onChange={setAba}
        />

        {/* Conteúdo da aba */}
        {aba === 'form' && (
          <div>
            {podeEditar ? (
              <FormularioMov campos={campos} dados={draft.dados} onChange={setDadosCampo} />
            ) : (
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 12 }} className="mobile-col1">
                {campos.map(c => (
                  <div key={c.id} style={{ background: 'var(--escalab-paper)', border: '1px solid var(--escalab-line)', borderRadius: 8, padding: '10px 12px' }}>
                    <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '.1em', textTransform: 'uppercase', color: 'var(--escalab-mute)', marginBottom: 4 }}>{c.label}</div>
                    <div style={{ fontSize: 13.5, color: 'var(--escalab-ink)' }}>{draft.dados[c.id] || '·'}</div>
                  </div>
                ))}
              </div>
            )}
          </div>
        )}

        {aba === 'tarefas' && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {(draft.subtarefas || []).length === 0 && (
              <Banner tone="info">Nenhuma subtarefa ainda. Use o botão abaixo para criar checklist com prazo e responsável.</Banner>
            )}
            {(draft.subtarefas || []).map(s => {
              const respColab = s.resp ? COLABORADORES.find(c => c.nome.toLowerCase().includes(s.resp.toLowerCase()) || s.resp.toLowerCase().includes(c.nome.toLowerCase().split(' ')[0])) : null;
              const mailToResp = respColab ? `mailto:${respColab.email}?subject=${encodeURIComponent(`[Escalab] Tarefa atribuída: ${s.txt || 'Movimentação #' + draft.id}`)}&body=${encodeURIComponent(`Olá ${respColab.nome.split(' ')[0]},\n\nVocê foi designado(a) como responsável pela tarefa:\n"${s.txt}"\n\nPrazo: ${s.prazo ? fmtData(s.prazo) : 'sem prazo definido'}\nReferente à ${MOV_LABEL[tipo]} #${draft.id} (${nomePrincipal}).\n\nAbra: ${window.location.origin}${window.location.pathname}?mov=${tipo}&id=${draft.id}`)}` : null;
              return (
                <div key={s.id} style={{ display: 'grid', gridTemplateColumns: '28px 2fr 1fr 130px 28px 24px', gap: 8, alignItems: 'center', border: '1px solid var(--escalab-line)', borderRadius: 10, padding: '8px 12px', background: s.feita ? 'var(--escalab-brand-tint)' : '#fff' }} className="mobile-col1">
                  <input type="checkbox" checked={!!s.feita} onChange={e => setSubtarefa(s.id, { feita: e.target.checked })} style={{ width: 18, height: 18, cursor: 'pointer' }} disabled={!podeEditar} />
                  <Input value={s.txt} onChange={v => setSubtarefa(s.id, { txt: v })} placeholder="O que precisa ser feito?" disabled={!podeEditar} />
                  <Input value={s.resp} onChange={v => setSubtarefa(s.id, { resp: v })} placeholder="Responsável" disabled={!podeEditar} />
                  <Input type="date" value={s.prazo} onChange={v => setSubtarefa(s.id, { prazo: v })} disabled={!podeEditar} />
                  {mailToResp ? (
                    <a href={mailToResp} title={`Avisar ${respColab.nome.split(' ')[0]} por e-mail`} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--escalab-brand-tint)', border: '1px solid var(--escalab-brand-soft)', borderRadius: 6, width: 28, height: 28, color: 'var(--escalab-brand-deep)', textDecoration: 'none' }}>
                      <Icon name="bell" size={12} />
                    </a>
                  ) : <span />}
                  {podeEditar ? (
                    <button onClick={() => rmSubtarefa(s.id)} style={{ border: 0, background: 'transparent', cursor: 'pointer', color: 'var(--escalab-mute)' }} title="Remover"><Icon name="close" size={14} /></button>
                  ) : <span />}
                </div>
              );
            })}
            {podeEditar && (
              <button onClick={addSubtarefa} style={{ alignSelf: 'flex-start', border: '1px dashed var(--escalab-line)', background: 'transparent', borderRadius: 10, padding: '8px 14px', cursor: 'pointer', fontSize: 13, color: 'var(--escalab-brand-deep)', fontFamily: 'var(--font-sans)', fontWeight: 600 }}>+ Adicionar subtarefa</button>
            )}
          </div>
        )}

        {aba === 'coment' && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            {/* Lista cronológica: mais antigo no topo, mais recente embaixo */}
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              {(draft.comentarios || []).length === 0 ? (
                <div style={{ fontSize: 13, color: 'var(--escalab-mute)', textAlign: 'center', padding: '24px 0' }}>Nenhum comentário ainda.</div>
              ) : (draft.comentarios || []).map((c, i) => (
                <div key={i} style={{ display: 'flex', gap: 8 }}>
                  <Avatar nome={c.autor} size={28} />
                  <div style={{ flex: 1, background: 'var(--escalab-paper)', border: '1px solid var(--escalab-line)', borderRadius: 10, padding: '8px 12px' }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 4 }}>
                      <span style={{ fontSize: 13, fontWeight: 700, color: 'var(--escalab-ink)' }}>{c.autor}</span>
                      <span style={{ fontSize: 11, color: 'var(--escalab-mute)' }}>{fmtData(c.em)}</span>
                    </div>
                    <div style={{ fontSize: 13.5, color: 'var(--escalab-charcoal)', whiteSpace: 'pre-wrap' }}>{c.txt}</div>
                  </div>
                </div>
              ))}
            </div>
            {/* Novo comentário · sempre embaixo da lista */}
            <div style={{ display: 'flex', gap: 8, alignItems: 'flex-start', borderTop: '1px solid var(--escalab-line)', paddingTop: 12 }}>
              <Avatar nome={user?.nome || 'Usuário'} size={32} />
              <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 8 }}>
                <textarea value={novoComentario} onChange={e => setNovoComentario(e.target.value)} rows={2} placeholder="Comentar como GC, Financeiro ou Líder da vaga…" style={{ width: '100%', border: '1px solid var(--escalab-line)', borderRadius: 8, padding: '10px 12px', fontSize: 14, fontFamily: 'var(--font-sans)', outline: 0, resize: 'vertical', boxSizing: 'border-box' }} />
                <Button variant="primary" onClick={addComentario} disabled={!novoComentario.trim()} style={{ alignSelf: 'flex-end' }}>Comentar</Button>
              </div>
            </div>
          </div>
        )}
      </div>
    </Modal>
  );
};

// ── Kanban com drag-and-drop (PDF Site AVD 5 · item 44) ─────────
const KanbanMovDnD = ({ etapas, sols, podeEditar, onMoverCard, onAbrir, tipo }) => {
  const [arrastando, setArrastando] = useState(null);
  const [hoverEtapa, setHoverEtapa] = useState(null);
  return (
    <div style={{ display: 'grid', gridTemplateColumns: `repeat(${etapas.length}, minmax(220px, 1fr))`, gap: 14, overflowX: 'auto' }} className="kanban-mov">
      {etapas.map(et => {
        const cards = sols.filter(s => s.etapa === et.id);
        const dropAtivo = hoverEtapa === et.id && arrastando;
        return (
          <div key={et.id}
            onDragOver={e => { if (podeEditar) { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; setHoverEtapa(et.id); } }}
            onDragLeave={() => setHoverEtapa(h => h === et.id ? null : h)}
            onDrop={e => {
              if (!podeEditar) return;
              e.preventDefault();
              const id = e.dataTransfer.getData('text/plain') || arrastando;
              if (id) onMoverCard(id, et.id);
              setHoverEtapa(null);
              setArrastando(null);
            }}
            style={{ background: dropAtivo ? et.bg : 'var(--escalab-paper)', border: dropAtivo ? `2px dashed ${et.color}` : '2px dashed transparent', borderRadius: 14, padding: 12, display: 'flex', flexDirection: 'column', gap: 10, minWidth: 220, transition: 'background .15s, border-color .15s' }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '4px 6px' }}>
              <div style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                <span style={{ width: 8, height: 8, borderRadius: 999, background: et.color }} />
                <span style={{ fontSize: 11.5, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: et.color }}>{et.label}</span>
              </div>
              <span style={{ fontSize: 12, fontWeight: 700, color: 'var(--escalab-mute)' }}>{cards.length}</span>
            </div>
            {cards.length === 0 ? (
              <div style={{ fontSize: 12, color: 'var(--escalab-mute)', textAlign: 'center', padding: '20px 0', fontStyle: 'italic' }}>
                {dropAtivo ? 'Solte aqui para mover' : 'vazio'}
              </div>
            ) : cards.map(s => (
              <CardMov key={s.id} tipo={tipo} sol={s} etapas={etapas}
                onClick={() => onAbrir(s.id)}
                podeArrastar={podeEditar}
                onDragStart={id => setArrastando(id)}
                onDragEnd={() => { setArrastando(null); setHoverEtapa(null); }}
              />
            ))}
          </div>
        );
      })}
    </div>
  );
};

// ── Card do kanban ───────────────────────────────────────────────
const CardMov = ({ tipo, sol, etapas, onClick, podeArrastar, onDragStart, onDragEnd }) => {
  const etapa = etapas.find(e => e.id === sol.etapa) || etapas[0];
  const nome = sol.dados.nomeColaborador || sol.dados.solicitante || sol.id;
  const subtitulo =
    tipo === 'admissao'    ? (sol.dados.projetoSetor || '') :
    tipo === 'promocao'    ? (sol.dados.tipo || '') :
    /* desligamento */        (sol.dados.cargo || sol.dados.setor || '');
  const feitas = (sol.subtarefas || []).filter(s => s.feita).length;
  const total  = (sol.subtarefas || []).length;
  const ncoment = (sol.comentarios || []).length;
  function fmtBR(s) {
    if (!s) return '';
    const m = String(s).match(/^(\d{4})-(\d{2})-(\d{2})/);
    if (m) return `${m[3]}/${m[2]}/${m[1]}`;
    return s;
  }
  return (
    <button onClick={onClick}
      draggable={!!podeArrastar}
      onDragStart={e => { if (podeArrastar) { e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', sol.id); onDragStart?.(sol.id); } }}
      onDragEnd={() => onDragEnd?.()}
      style={{
      textAlign: 'left', width: '100%', cursor: podeArrastar ? 'grab' : 'pointer',
      background: '#fff', border: '1px solid var(--escalab-line)', borderRadius: 12,
      padding: '12px 14px', boxShadow: 'var(--shadow-sm)', fontFamily: 'var(--font-sans)',
      transition: 'transform .15s, box-shadow .15s, border-color .15s',
      display: 'flex', flexDirection: 'column', gap: 8,
    }}
    onMouseOver={e => { e.currentTarget.style.transform = 'translateY(-2px)'; e.currentTarget.style.boxShadow = 'var(--shadow-md)'; e.currentTarget.style.borderColor = etapa.color; }}
    onMouseOut={e => { e.currentTarget.style.transform = 'none'; e.currentTarget.style.boxShadow = 'var(--shadow-sm)'; e.currentTarget.style.borderColor = 'var(--escalab-line)'; }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 8 }}>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--escalab-ink)', lineHeight: 1.25, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{nome}</div>
          {subtitulo && <div style={{ fontSize: 12, color: 'var(--escalab-slate)', marginTop: 2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{subtitulo}</div>}
        </div>
        {sol.origem === 'auto-desligamento' && (
          <span title="Criado automaticamente pelo botão de desligar" style={{ fontSize: 9.5, fontWeight: 700, letterSpacing: '.1em', textTransform: 'uppercase', color: etapa.color, background: etapa.bg, padding: '2px 6px', borderRadius: 4 }}>auto</span>
        )}
      </div>
      {/* Desligamento: mostrar aviso prévio, data saída, motivo resumido no próprio card */}
      {tipo === 'desligamento' && (
        <div style={{ background: 'var(--escalab-paper)', borderRadius: 8, padding: '7px 10px', display: 'flex', flexDirection: 'column', gap: 3 }}>
          {sol.dados.tipoDesligamento && (
            <div style={{ fontSize: 11.5, color: '#C0392B', fontWeight: 600 }}>{sol.dados.tipoDesligamento}</div>
          )}
          {sol.dados.avisoPrevio && (
            <div style={{ fontSize: 11, color: 'var(--escalab-slate)' }}>
              <span style={{ color: 'var(--escalab-mute)' }}>Aviso prévio:</span> <strong>{sol.dados.avisoPrevio}</strong>
              {sol.dados.avisoPrevioInicio && <> · {fmtBR(sol.dados.avisoPrevioInicio)}{sol.dados.avisoPrevioFim ? ` → ${fmtBR(sol.dados.avisoPrevioFim)}` : ''}</>}
            </div>
          )}
          {sol.dados.dataSaida && (
            <div style={{ fontSize: 11, color: 'var(--escalab-slate)' }}>
              <span style={{ color: 'var(--escalab-mute)' }}>Saída:</span> <strong>{fmtBR(sol.dados.dataSaida)}</strong>
            </div>
          )}
          {(sol.dados.feriasVencidas || sol.dados.saldoDayOff != null) && (
            <div style={{ fontSize: 11, color: 'var(--escalab-mute)' }}>
              {sol.dados.feriasVencidas && <>Férias: {sol.dados.feriasVencidas}</>}
              {sol.dados.saldoDayOff != null && sol.dados.saldoDayOff !== '' && <> · DayOff: <strong>{sol.dados.saldoDayOff}d</strong></>}
            </div>
          )}
          {sol.dados.motivo && (
            <div style={{ fontSize: 11, color: 'var(--escalab-slate)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontStyle: 'italic' }} title={sol.dados.motivo}>
              "{sol.dados.motivo}"
            </div>
          )}
        </div>
      )}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 11.5, color: 'var(--escalab-mute)' }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
          <Icon name="calendar" size={11} /> {fmtBR(sol.criadoEm) || sol.criadoEm}
        </span>
        {total > 0 && (
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
            <Icon name="check" size={11} /> {feitas}/{total}
          </span>
        )}
        {ncoment > 0 && (
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
            <Icon name="send" size={11} /> {ncoment}
          </span>
        )}
      </div>
    </button>
  );
};

// ── Kanban de uma subguia ───────────────────────────────────────
const KanbanMov = ({ tipo, user, podeCriar, podeEditar, version, onBump }) => {
  const etapas = MOV_ETAPAS[tipo];
  const [solsRaw, setSols] = useState(() => getMovSolicitacoes(tipo));
  const [modalNova, setModalNova] = useState(false);
  const [aberto, setAberto] = useState(null); // sol id

  // re-sync quando o user troca de aba
  useEffect(() => { setSols(getMovSolicitacoes(tipo)); }, [tipo, version]);

  // PDF Site AVD 5 · item 20: gestor só vê cards onde foi marcado (ou onde é responsável/solicitante).
  // Admin e financeiro continuam vendo tudo.
  const sols = (() => {
    if (user?.perfil !== 'gestor') return solsRaw;
    return solsRaw.filter(s =>
      (s.marcadosIds || []).includes(user.id) ||
      s.criadoPor === user.nome ||
      s.dados?.solicitante === user.nome ||
      s.dados?.email === user.email
    );
  })();

  // PDF Site AVD 5 · item 21: alerta de novidades para GC/financeiro/líder
  const novidadesNum = (() => {
    if (!['admin','financeiro','gestor'].includes(user?.perfil)) return 0;
    return solsRaw.filter(s => {
      const nov = s.novidade;
      if (!nov || !nov.ts) return false;
      const visto = (s.vistoPor || {})[user.id];
      return !visto || visto < nov.ts;
    }).length;
  })();

  function refreshLocal() { setSols(getMovSolicitacoes(tipo)); onBump && onBump(); }

  function salvarNova(sol) {
    salvarMovSolicitacao(tipo, sol);
    setModalNova(false);
    refreshLocal();
  }
  function salvarEdit(sol) {
    salvarMovSolicitacao(tipo, sol);
    setAberto(null);
    refreshLocal();
  }
  function excluir(id) {
    removerMovSolicitacao(tipo, id);
    setAberto(null);
    refreshLocal();
  }

  const ativo = aberto ? sols.find(s => s.id === aberto) : null;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, flexWrap: 'wrap' }}>
        <div>
          <div style={{ fontSize: 19, fontWeight: 700, color: 'var(--escalab-ink)', fontFamily: 'var(--font-display)', letterSpacing: '.01em' }}>
            {MOV_LABEL[tipo]} · {sols.length} {sols.length === 1 ? 'solicitação' : 'solicitações'}
          </div>
          <div style={{ fontSize: 13, color: 'var(--escalab-slate)', marginTop: 4 }}>
            {tipo === 'admissao' && 'Gestor abre solicitação de vaga → GC conduz documentação, bolsa e fundação até admissão.'}
            {tipo === 'promocao' && 'Gestor solicita mudança de cargo/valor/projeto → GC e Financeiro implementam.'}
            {tipo === 'desligamento' && 'Cards criados automaticamente pelo botão Desligar (em Colaboradores) ou abertos manualmente aqui.'}
          </div>
        </div>
        {podeCriar && <Button variant="primary" onClick={() => setModalNova(true)} icon="plus">Nova solicitação</Button>}
      </div>

      {/* Alerta de novidades · GC + financeiro + líder (PDF Site AVD 5 · item 21) */}
      {novidadesNum > 0 && (
        <Banner tone="warn">
          <strong>{novidadesNum}</strong> card{novidadesNum > 1 ? 's' : ''} com comentário ou movimentação nova{novidadesNum > 1 ? 's' : ''}. Abra para ver e marcar como visto.
        </Banner>
      )}

      {/* PDF Site AVD 5 · item 44: Kanban arrastável (HTML5 drag-and-drop) */}
      <KanbanMovDnD
        etapas={etapas}
        sols={sols}
        podeEditar={podeEditar}
        onMoverCard={(solId, novaEtapa) => {
          const sol = solsRaw.find(s => s.id === solId);
          if (!sol || sol.etapa === novaEtapa) return;
          const atualizado = { ...sol, etapa: novaEtapa, novidade: { ts: Date.now(), autor: user?.nome || 'Sistema', kind: 'mov' }, vistoPor: { ...(sol.vistoPor || {}), [user?.id]: Date.now() } };
          salvarMovSolicitacao(tipo, atualizado);
          refreshLocal();
        }}
        onAbrir={id => setAberto(id)}
        tipo={tipo}
      />

      {modalNova && <ModalNovaSolMov tipo={tipo} user={user} onClose={() => setModalNova(false)} onSalvar={salvarNova} />}
      {ativo && <ModalDetalheMov tipo={tipo} sol={ativo} etapas={etapas} user={user} podeEditar={podeEditar} onClose={() => setAberto(null)} onSave={salvarEdit} onDelete={excluir} />}
    </div>
  );
};

// ── Screen principal ────────────────────────────────────────────
const ScreenMovimentacao = ({ user, route, navigate }) => {
  // Hash route format: movimentacao | movimentacao#promocao | movimentacao#desligamento
  const tipoUrl = (() => {
    const h = (window.location.hash || '').replace(/^#/, '').split('?')[0];
    if (h === 'promocao' || h === 'desligamento' || h === 'admissao') return h;
    return 'admissao';
  })();
  const [tipo, setTipo] = useState(tipoUrl);
  const [version, setVersion] = useState(0);

  // GC (admin) e Gestor podem criar/editar.
  // Financeiro tem acesso (vê tudo, pode comentar, mas não move/exclui cards).
  const isAdmin     = user?.perfil === 'admin';
  const isGestor    = user?.perfil === 'gestor';
  const isFinanc    = user?.perfil === 'financeiro';
  const podeCriar   = isAdmin || isGestor;
  const podeEditar  = isAdmin || isGestor;

  return (
    <div style={{ padding: '24px 28px', display: 'flex', flexDirection: 'column', gap: 18, maxWidth: 1400, margin: '0 auto' }}>
      <div>
        <div style={{ fontSize: 11.5, fontWeight: 700, letterSpacing: '.14em', textTransform: 'uppercase', color: 'var(--escalab-brand)' }}>Pessoas · Fluxos</div>
        <h1 style={{ fontSize: 28, margin: '4px 0 6px', fontFamily: 'var(--font-display)', letterSpacing: '.015em' }}>Movimentação Profissional</h1>
        <p style={{ fontSize: 14, color: 'var(--escalab-slate)', maxWidth: 720, margin: 0 }}>
          Painel único para admissões, promoções/movimentações e desligamentos.
          GC, Financeiro e Líder da vaga acompanham cada card por etapas, conferem o formulário, marcam subtarefas e conversam pelos comentários.
        </p>
      </div>

      <div style={{ display: 'flex', gap: 8, borderBottom: '1px solid var(--escalab-line)', overflowX: 'auto' }} className="tabs-scroll">
        {['admissao', 'promocao', 'desligamento'].map(t => {
          const ativo = tipo === t;
          return (
            <button key={t} onClick={() => setTipo(t)} style={{
              border: 0, background: 'transparent', cursor: 'pointer',
              padding: '12px 18px', fontSize: 14.5, fontFamily: 'var(--font-sans)',
              fontWeight: ativo ? 700 : 500,
              color: ativo ? 'var(--escalab-brand-deep)' : 'var(--escalab-slate)',
              borderBottom: ativo ? '2px solid var(--escalab-brand)' : '2px solid transparent',
              marginBottom: -1,
              whiteSpace: 'nowrap',
            }}>{MOV_LABEL[t]}</button>
          );
        })}
      </div>

      <KanbanMov key={tipo} tipo={tipo} user={user} podeCriar={podeCriar} podeEditar={podeEditar} version={version} onBump={() => setVersion(v => v + 1)} />
    </div>
  );
};
