// Publicações Astrea — sincronização por usuário via API Astrea

// ============================================================
// Helpers
// ============================================================

function fmtDate(d) {
  if (!d) return '—';
  const [y, m, day] = d.split('-');
  return `${day}/${m}/${y}`;
}

function truncate(text, max = 300) {
  if (!text) return '';
  return text.length > max ? text.slice(0, max) + '…' : text;
}

function diasAte(dateStr) {
  if (!dateStr) return null;
  const hoje = new Date();
  hoje.setHours(0, 0, 0, 0);
  const alvo = new Date(`${dateStr}T00:00:00`);
  return Math.round((alvo - hoje) / 86400000);
}

function PrazoBadge({ pub, detalhado }) {
  if (!pub.data_limite) return null;
  const dias = diasAte(pub.data_limite);
  let bg, color, label;
  if (dias < 0) {
    bg = 'rgba(220,38,38,.1)'; color = '#DC2626';
    label = `Prazo vencido há ${Math.abs(dias)} dia(s)`;
  } else if (dias === 0) {
    bg = 'rgba(220,38,38,.1)'; color = '#DC2626';
    label = 'Prazo vence HOJE';
  } else if (dias <= 3) {
    bg = 'rgba(234,88,12,.12)'; color = '#EA580C';
    label = `Prazo em ${dias} dia(s)`;
  } else {
    bg = 'rgba(30,64,175,.08)'; color = '#1E40AF';
    label = `Prazo em ${dias} dias`;
  }
  return (
    <span
      title={`${pub.prazo_dias} dias · base: ${pub.prazo_base_legal || '—'} · limite sugerido: ${fmtDate(pub.data_limite)} — confira antes de protocolar (feriados não considerados)`}
      style={{ fontSize: 11, fontWeight: 700, padding: '2px 9px', borderRadius: 5, background: bg, color, whiteSpace: 'nowrap' }}
    >
      ⏱ {label}{detalhado ? ` · ${fmtDate(pub.data_limite)} (sugerido)` : ''}
    </span>
  );
}

function Toast({ msg, type, onClose }) {
  React.useEffect(() => {
    const t = setTimeout(onClose, 8000);
    return () => clearTimeout(t);
  }, []);
  if (!msg) return null;
  const bg = type === 'erro' ? '#DC2626' : '#157F3D';
  return (
    <div style={{
      position: 'fixed', bottom: 24, right: 24, zIndex: 9999,
      background: bg, color: '#fff',
      padding: '12px 16px 12px 20px', borderRadius: 10, maxWidth: 400,
      boxShadow: '0 4px 20px rgba(0,0,0,.25)', fontSize: 13, fontWeight: 500,
      display: 'flex', alignItems: 'flex-start', gap: 12,
    }}>
      <span style={{ flex: 1, lineHeight: 1.4 }}>{msg}</span>
      <button
        onClick={onClose}
        title="Fechar"
        style={{
          flexShrink: 0, background: 'rgba(255,255,255,0.25)', border: 'none',
          color: '#fff', cursor: 'pointer', borderRadius: 6,
          width: 24, height: 24, display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 16, lineHeight: 1, padding: 0, marginTop: 1,
        }}
      >×</button>
    </div>
  );
}

// ============================================================
// Modal — Cadastrar/Editar Usuário Astrea
// ============================================================

function AstreaUserModal({ astreaUser, onSave, onClose }) {
  React.useEffect(() => {
    const h = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', h);
    return () => document.removeEventListener('keydown', h);
  }, [onClose]);
  const isEdit = !!astreaUser?.id;
  const [name, setName] = React.useState(astreaUser?.name || '');
  const [email, setEmail] = React.useState(astreaUser?.email || '');
  const [password, setPassword] = React.useState('');
  const [active, setActive] = React.useState(astreaUser?.active !== false);
  const [saving, setSaving] = React.useState(false);
  const [erro, setErro] = React.useState('');

  const handleSave = async () => {
    if (!name.trim() || !email.trim() || (!isEdit && !password.trim())) {
      setErro('Preencha nome, e-mail e senha.');
      return;
    }
    setSaving(true);
    setErro('');
    try {
      const payload = { name: name.trim(), active };
      if (!isEdit) { payload.email = email.trim(); payload.password = password; }
      else if (password.trim()) payload.password = password;
      await onSave(payload);
      onClose();
    } catch (e) {
      setErro(e.message || 'Erro ao salvar.');
    } finally {
      setSaving(false);
    }
  };

  return (
    <div style={{
      position: 'fixed', inset: 0, background: 'rgba(13,13,107,.45)',
      zIndex: 1200, display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      <div style={{
        background: '#fff', borderRadius: 16, padding: 28, width: 420,
        boxShadow: '0 16px 60px rgba(13,13,107,.18)',
      }}>
        <div style={{ fontWeight: 700, fontSize: 16, marginBottom: 20, color: '#0D0D6B' }}>
          {isEdit ? 'Editar Usuário Astrea' : 'Cadastrar Usuário Astrea'}
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          <div>
            <label style={{ fontSize: 12, fontWeight: 600, color: '#374151', display: 'block', marginBottom: 4 }}>Nome completo</label>
            <input
              value={name}
              onChange={e => setName(e.target.value)}
              placeholder="Ex: Fernando Peracini"
              style={{ width: '100%', padding: '8px 12px', border: '1.5px solid #E5E7EB', borderRadius: 8, fontSize: 14, boxSizing: 'border-box' }}
            />
          </div>
          <div>
            <label style={{ fontSize: 12, fontWeight: 600, color: '#374151', display: 'block', marginBottom: 4 }}>E-mail (login Astrea)</label>
            <input
              value={email}
              onChange={e => setEmail(e.target.value)}
              placeholder="Ex: peracinif@gmail.com"
              disabled={isEdit}
              style={{ width: '100%', padding: '8px 12px', border: '1.5px solid #E5E7EB', borderRadius: 8, fontSize: 14, boxSizing: 'border-box', background: isEdit ? '#F9FAFB' : '#fff' }}
            />
          </div>
          <div>
            <label style={{ fontSize: 12, fontWeight: 600, color: '#374151', display: 'block', marginBottom: 4 }}>
              Senha Astrea {isEdit && '(deixe em branco para manter)'}
            </label>
            <input
              type="password"
              value={password}
              onChange={e => setPassword(e.target.value)}
              placeholder={isEdit ? '••••••••' : 'Senha do Astrea'}
              style={{ width: '100%', padding: '8px 12px', border: '1.5px solid #E5E7EB', borderRadius: 8, fontSize: 14, boxSizing: 'border-box' }}
            />
          </div>
          {isEdit && (
            <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 14, cursor: 'pointer' }}>
              <input type="checkbox" checked={active} onChange={e => setActive(e.target.checked)} />
              <span>Ativo (sincronizar publicações)</span>
            </label>
          )}
          {erro && <div style={{ fontSize: 12, color: '#DC2626' }}>{erro}</div>}
        </div>

        <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end', marginTop: 24 }}>
          <button onClick={onClose} style={{ padding: '8px 18px', borderRadius: 8, border: '1.5px solid #E5E7EB', background: '#fff', cursor: 'pointer', fontSize: 14 }}>Cancelar</button>
          <button
            onClick={handleSave}
            disabled={saving}
            style={{ padding: '8px 20px', borderRadius: 8, border: 'none', background: '#0D0D6B', color: '#fff', cursor: saving ? 'not-allowed' : 'pointer', fontSize: 14, fontWeight: 600, opacity: saving ? 0.7 : 1 }}
          >
            {saving ? 'Salvando…' : 'Salvar'}
          </button>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// Modal — Detalhe da Publicação
// ============================================================

const CASE_AREAS = ['Contencioso', 'Contratos', 'Societário', 'M&A', 'Franchising', 'Venture Capital', 'Propriedade Intelectual', 'Tributário', 'Trabalhista', 'Outros'];

function PublicacaoDetalhe({ pub, onClose, onMarcarLida, onVincular, onCriarTarefa, cases }) {
  React.useEffect(() => {
    const h = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', h);
    return () => document.removeEventListener('keydown', h);
  }, [onClose]);
  const [busca, setBusca] = React.useState('');
  const [criandoCaso, setCriandoCaso] = React.useState(false);
  const [clientes, setClientes] = React.useState([]);
  const [novoCaso, setNovoCaso] = React.useState({ title: '', client_id: '', area: 'Contencioso' });
  const [salvandoCaso, setSalvandoCaso] = React.useState(false);
  const [criandoTarefa, setCriandoTarefa] = React.useState(false);
  const [erro, setErro] = React.useState('');

  React.useEffect(() => {
    if (criandoCaso && clientes.length === 0) {
      window.PACApi.clients.list().then(setClientes).catch(() => {});
    }
  }, [criandoCaso]);

  const abrirCriarCaso = () => {
    setNovoCaso({
      title: pub.numero_processo ? `Processo ${pub.numero_processo}` : (pub.tipo_comunicacao || 'Novo caso'),
      client_id: '',
      area: 'Contencioso',
    });
    setCriandoCaso(true);
  };

  const salvarNovoCaso = async () => {
    if (!novoCaso.title.trim() || !novoCaso.client_id) {
      setErro('Informe título e cliente.');
      return;
    }
    setSalvandoCaso(true);
    setErro('');
    try {
      const caso = await window.PACApi.cases.create({
        title: novoCaso.title.trim(),
        client_id: novoCaso.client_id,
        area: novoCaso.area,
        numero_processo: pub.numero_processo || undefined,
        description: pub.conteudo ? pub.conteudo.slice(0, 500) : undefined,
      });
      await onVincular(pub.id, caso.id);
      setCriandoCaso(false);
    } catch (e) {
      setErro(e.message || 'Erro ao criar caso.');
    } finally {
      setSalvandoCaso(false);
    }
  };

  const handleCriarTarefa = async () => {
    setCriandoTarefa(true);
    setErro('');
    try {
      await onCriarTarefa(pub.id);
    } catch (e) {
      setErro(e.message || 'Erro ao criar tarefa.');
    } finally {
      setCriandoTarefa(false);
    }
  };

  const casosFiltrados = busca
    ? (cases || []).filter(c =>
        c.title?.toLowerCase().includes(busca.toLowerCase()) ||
        c.numero_processo?.includes(busca)
      )
    : (cases || []).slice(0, 8);

  return (
    <div style={{
      position: 'fixed', inset: 0, background: 'rgba(13,13,107,.45)',
      zIndex: 1200, display: 'flex', alignItems: 'flex-start', justifyContent: 'flex-end',
    }} onClick={onClose}>
      <div
        onClick={e => e.stopPropagation()}
        style={{
          width: Math.min(560, window.innerWidth - 20),
          height: '100vh', overflowY: 'auto',
          background: '#fff', boxShadow: '-8px 0 40px rgba(13,13,107,.15)',
          padding: 28, boxSizing: 'border-box',
        }}
      >
        {/* Header */}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 20 }}>
          <div>
            <div style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 1, color: '#6B7280', marginBottom: 4 }}>
              {pub.tipo_comunicacao || 'Publicação Astrea'}
            </div>
            <div style={{ fontWeight: 700, fontSize: 15, color: '#0D0D6B' }}>
              {pub.numero_processo || 'Sem número de processo'}
            </div>
          </div>
          <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 20, color: '#9CA3AF', padding: 4 }}>×</button>
        </div>

        {/* Prazo sugerido */}
        {pub.data_limite && (
          <div style={{ marginBottom: 16, display: 'flex', alignItems: 'center', gap: 10, background: '#FFFBEB', border: '1.5px solid #FDE68A', borderRadius: 10, padding: '10px 14px' }}>
            <PrazoBadge pub={pub} detalhado />
            <span style={{ fontSize: 11, color: '#92400E' }}>
              Contagem sugerida ({pub.prazo_dias} dias · base: {pub.prazo_base_legal}) — não considera feriados; confira antes de protocolar.
            </span>
          </div>
        )}

        {/* Metadados */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 20 }}>
          {[
            ['Tribunal', pub.court_formatted || pub.court],
            ['Classe', pub.classe],
            ['Data DJE', fmtDate(pub.release_date)],
            ['Caso (Astrea)', pub.case_title],
            ['Responsável', pub.case_responsible_name],
            ['Usuário Astrea', pub.astrea_user?.email],
          ].filter(([, v]) => v).map(([k, v]) => (
            <div key={k} style={{ background: '#F9FAFB', borderRadius: 8, padding: '8px 12px' }}>
              <div style={{ fontSize: 11, color: '#6B7280', fontWeight: 600, marginBottom: 2 }}>{k}</div>
              <div style={{ fontSize: 13, color: '#111827', fontWeight: 500 }}>{v}</div>
            </div>
          ))}
        </div>

        {/* Texto completo */}
        {pub.conteudo && (
          <div style={{ marginBottom: 20 }}>
            <div style={{ fontSize: 12, fontWeight: 700, color: '#374151', marginBottom: 8, textTransform: 'uppercase', letterSpacing: 0.5 }}>Conteúdo da Publicação</div>
            <div style={{ fontSize: 13, color: '#374151', lineHeight: 1.7, background: '#F9FAFB', borderRadius: 8, padding: '14px 16px', whiteSpace: 'pre-wrap' }}>
              {pub.conteudo}
            </div>
          </div>
        )}

        {/* Vinculação ao caso */}
        <div style={{ marginBottom: 20 }}>
          <div style={{ fontSize: 12, fontWeight: 700, color: '#374151', marginBottom: 8, textTransform: 'uppercase', letterSpacing: 0.5 }}>Caso Vinculado (PAC Sistema)</div>
          {pub.caso ? (
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, background: '#EFF6FF', borderRadius: 8, padding: '10px 14px' }}>
              <Icon name="briefcase" size={14} style={{ color: '#1E40AF' }} />
              <span style={{ fontSize: 13, fontWeight: 600, color: '#1E40AF' }}>{pub.caso.title}</span>
              {pub.caso.numero_processo && <span style={{ fontSize: 12, color: '#6B7280' }}>· {pub.caso.numero_processo}</span>}
              <button
                onClick={() => onVincular(pub.id, null)}
                style={{ marginLeft: 'auto', fontSize: 11, color: '#9CA3AF', background: 'none', border: 'none', cursor: 'pointer' }}
              >Desvincular</button>
            </div>
          ) : criandoCaso ? (
            <div style={{ border: '1.5px solid #BFDBFE', borderRadius: 10, padding: 14, background: '#F8FAFF' }}>
              <div style={{ fontSize: 12, fontWeight: 700, color: '#0D0D6B', marginBottom: 10 }}>Novo caso a partir desta publicação</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                <input
                  value={novoCaso.title}
                  onChange={e => setNovoCaso(p => ({ ...p, title: e.target.value }))}
                  placeholder="Título do caso"
                  style={{ padding: '8px 12px', border: '1.5px solid #E5E7EB', borderRadius: 8, fontSize: 13 }}
                />
                <select
                  value={novoCaso.client_id}
                  onChange={e => setNovoCaso(p => ({ ...p, client_id: e.target.value }))}
                  style={{ padding: '8px 10px', border: '1.5px solid #E5E7EB', borderRadius: 8, fontSize: 13, background: '#fff' }}
                >
                  <option value="">{clientes.length === 0 ? 'Carregando clientes…' : 'Selecione o cliente'}</option>
                  {clientes.map(cl => <option key={cl.id} value={cl.id}>{cl.name}</option>)}
                </select>
                <select
                  value={novoCaso.area}
                  onChange={e => setNovoCaso(p => ({ ...p, area: e.target.value }))}
                  style={{ padding: '8px 10px', border: '1.5px solid #E5E7EB', borderRadius: 8, fontSize: 13, background: '#fff' }}
                >
                  {CASE_AREAS.map(a => <option key={a} value={a}>{a}</option>)}
                </select>
                {pub.numero_processo && (
                  <div style={{ fontSize: 11, color: '#6B7280' }}>Nº do processo <strong>{pub.numero_processo}</strong> será gravado no caso.</div>
                )}
                <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
                  <button onClick={() => setCriandoCaso(false)} style={{ padding: '7px 14px', borderRadius: 8, border: '1.5px solid #E5E7EB', background: '#fff', cursor: 'pointer', fontSize: 12 }}>Cancelar</button>
                  <button
                    onClick={salvarNovoCaso}
                    disabled={salvandoCaso}
                    style={{ padding: '7px 16px', borderRadius: 8, border: 'none', background: '#0D0D6B', color: '#fff', cursor: salvandoCaso ? 'not-allowed' : 'pointer', fontSize: 12, fontWeight: 600, opacity: salvandoCaso ? 0.7 : 1 }}
                  >
                    {salvandoCaso ? 'Criando…' : 'Criar e vincular'}
                  </button>
                </div>
              </div>
            </div>
          ) : (
            <div>
              <div style={{ display: 'flex', gap: 8, marginBottom: 6 }}>
                <input
                  value={busca}
                  onChange={e => setBusca(e.target.value)}
                  placeholder="Buscar caso por nome ou número..."
                  style={{ flex: 1, padding: '8px 12px', border: '1.5px solid #E5E7EB', borderRadius: 8, fontSize: 13, boxSizing: 'border-box' }}
                />
                <button
                  onClick={abrirCriarCaso}
                  style={{ padding: '8px 14px', borderRadius: 8, border: '1.5px solid #BFDBFE', background: '#EFF6FF', color: '#1E40AF', cursor: 'pointer', fontSize: 12, fontWeight: 600, whiteSpace: 'nowrap' }}
                >
                  + Criar caso
                </button>
              </div>
              <div style={{ maxHeight: 160, overflowY: 'auto', border: '1px solid #E5E7EB', borderRadius: 8 }}>
                {casosFiltrados.length === 0 && (
                  <div style={{ padding: '10px 14px', fontSize: 13, color: '#9CA3AF' }}>Nenhum caso encontrado.</div>
                )}
                {casosFiltrados.map(c => (
                  <div
                    key={c.id}
                    onClick={() => onVincular(pub.id, c.id)}
                    style={{ padding: '8px 14px', cursor: 'pointer', fontSize: 13, borderBottom: '1px solid #F3F4F6', display: 'flex', flexDirection: 'column' }}
                    onMouseEnter={e => e.currentTarget.style.background = '#F3F4F6'}
                    onMouseLeave={e => e.currentTarget.style.background = ''}
                  >
                    <span style={{ fontWeight: 600, color: '#0D0D6B' }}>{c.title}</span>
                    {c.numero_processo && <span style={{ fontSize: 11, color: '#6B7280' }}>{c.numero_processo}</span>}
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>

        {erro && <div style={{ fontSize: 12, color: '#DC2626', marginBottom: 12 }}>{erro}</div>}

        {/* Ações */}
        <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
          <button
            onClick={() => onMarcarLida(pub.id, !pub.lida)}
            style={{
              flex: 1, padding: '10px 16px', borderRadius: 8,
              background: pub.lida ? '#F3F4F6' : '#0D0D6B',
              color: pub.lida ? '#374151' : '#fff',
              border: 'none', cursor: 'pointer', fontSize: 13, fontWeight: 600,
            }}
          >
            {pub.lida ? 'Marcar como não lida' : 'Marcar como lida'}
          </button>
          {pub.task_id ? (
            <div style={{
              flex: 1, padding: '10px 16px', borderRadius: 8,
              background: '#F0FDF4', color: '#157F3D',
              border: '1.5px solid #BBF7D0', fontSize: 13, fontWeight: 600, textAlign: 'center',
            }}>
              ✓ Tarefa criada
            </div>
          ) : (
            <button
              onClick={handleCriarTarefa}
              disabled={criandoTarefa}
              style={{
                flex: 1, padding: '10px 16px', borderRadius: 8,
                background: '#157F3D', color: '#fff',
                border: 'none', cursor: criandoTarefa ? 'not-allowed' : 'pointer',
                fontSize: 13, fontWeight: 600, opacity: criandoTarefa ? 0.7 : 1,
              }}
            >
              {criandoTarefa ? 'Criando…' : '+ Criar tarefa'}
            </button>
          )}
        </div>
      </div>
    </div>
  );
}

// ============================================================
// Aba — Publicações
// ============================================================

function AbaPublicacoesAstrea({ astreaUsers }) {
  const [publicacoes, setPublicacoes] = React.useState([]);
  const [total, setTotal] = React.useState(0);
  const [loading, setLoading] = React.useState(true);
  const [sincronizando, setSincronizando] = React.useState(false);
  const [detalhe, setDetalhe] = React.useState(null);
  const [cases, setCases] = React.useState([]);
  const [clients, setClients] = React.useState([]);
  const [users, setUsers] = React.useState([]);
  const [allTags, setAllTags] = React.useState([]);
  const [taskModalPub, setTaskModalPub] = React.useState(null);
  const [toast, setToast] = React.useState(null);
  const [ultimaSync, setUltimaSync] = React.useState(null);

  const loadUltimaSync = React.useCallback(() => {
    window.PACApi.astrea.ultimaSync().then(setUltimaSync).catch(() => {});
  }, []);

  const [filtros, setFiltros] = React.useState({
    astrea_user_id: '',
    data_inicio: '',
    data_fim: '',
    busca: '',
    lida: 'false', // padrão: só não lidas — ao marcar lida, some da lista
  });

  const filtrosRef = React.useRef(filtros);
  filtrosRef.current = filtros;

  const load = React.useCallback(async () => {
    setLoading(true);
    try {
      const f = filtrosRef.current;
      const params = {};
      if (f.astrea_user_id) params.astrea_user_id = f.astrea_user_id;
      if (f.data_inicio) params.data_inicio = f.data_inicio;
      if (f.data_fim) params.data_fim = f.data_fim;
      if (f.busca) params.busca = f.busca;
      if (f.lida !== '') params.lida = f.lida;

      const result = await window.PACApi.astrea.listPublicacoes(params);
      setPublicacoes(result.publicacoes || []);
      setTotal(result.total || 0);
    } catch (e) {
      setToast({ msg: e.message || 'Erro ao carregar publicações.', type: 'erro' });
    } finally {
      setLoading(false);
    }
  }, []);

  React.useEffect(() => {
    load();
    loadUltimaSync();
    window.PACApi.cases.list({}).then(data => setCases(data?.cases || data || [])).catch(() => {});
    window.PACApi.clients.list().then(d => setClients(d || [])).catch(() => {});
    window.PACApi.users.list().then(d => setUsers(d || [])).catch(() => {});
    window.PACApi.tags?.list?.().then(d => setAllTags(d || [])).catch(() => {});
  }, []);

  React.useEffect(() => { load(); }, [filtros.astrea_user_id, filtros.lida, filtros.data_inicio, filtros.data_fim]);

  // Sync roda no backend (login Astrea + busca de clippings server-side).
  const handleSincronizar = async () => {
    setSincronizando(true);
    setToast(null);
    try {
      const usersParaSincronizar = (astreaUsers || []).filter(u => u.active !== false);
      if (!usersParaSincronizar.length) {
        setToast({ msg: 'Nenhum usuário Astrea ativo cadastrado.', type: 'erro' });
        return;
      }

      const body = {};
      if (filtros.data_inicio) body.from_date = filtros.data_inicio;

      const result = await window.PACApi.astrea.sync(body);
      const usersResult = result.users || [];
      const totalNovas = usersResult.reduce((s, u) => s + (u.synced || 0), 0);
      const falhas = usersResult.filter(u => !u.success);

      const resumo = `${usersResult.length} usuário(s) — ${totalNovas} nova(s).`;
      const msg = falhas.length
        ? `Sync concluído com erros. ${resumo} Falhou: ${falhas.map(f => `${f.email}: ${f.erro}`).join('; ')}`
        : `Sync concluído — ${resumo}`;
      setToast({ msg, type: falhas.length && !totalNovas ? 'erro' : 'ok' });
      await load();
      loadUltimaSync();
    } catch (e) {
      setToast({ msg: e.message || 'Erro na sincronização.', type: 'erro' });
    } finally {
      setSincronizando(false);
    }
  };

  const handleMarcarLida = async (id, lida) => {
    try {
      const updated = await window.PACApi.astrea.marcarLida(id, lida);
      if (lida && filtrosRef.current.lida !== 'true') {
        setPublicacoes(prev => prev.filter(p => p.id !== id));
        setTotal(t => Math.max(0, t - 1));
        if (detalhe?.id === id) setDetalhe(null);
        setToast({ msg: 'Marcada como lida — disponível na timeline do caso.', type: 'ok' });
      } else {
        setPublicacoes(prev => prev.map(p => p.id === id ? { ...p, lida: updated.lida, data_leitura: updated.data_leitura } : p));
        if (detalhe?.id === id) setDetalhe(prev => ({ ...prev, lida: updated.lida }));
      }
    } catch (e) {
      setToast({ msg: e.message, type: 'erro' });
    }
  };

  const handleVincular = async (pubId, casoId) => {
    try {
      const updated = await window.PACApi.astrea.vincularCaso(pubId, casoId);
      setPublicacoes(prev => prev.map(p => p.id === pubId ? { ...p, caso_id: updated.caso_id, caso: updated.caso } : p));
      if (detalhe?.id === pubId) setDetalhe(prev => ({ ...prev, caso_id: updated.caso_id, caso: updated.caso }));
    } catch (e) {
      setToast({ msg: e.message, type: 'erro' });
    }
  };

  const handleCriarTarefa = async (pubId) => {
    const pub = publicacoes.find(p => p.id === pubId) || detalhe;
    if (!pub) return;
    setDetalhe(null);
    setTaskModalPub(pub);
  };

  const buildTaskPrefill = (pub) => {
    const tipo = pub.tipo_comunicacao || 'Publicação Astrea';
    const processo = pub.numero_processo ? ` — ${pub.numero_processo}` : '';
    const descricao = [
      pub.court_formatted && `Tribunal: ${pub.court_formatted}`,
      pub.classe && `Classe: ${pub.classe}`,
      pub.prazo_dias && `Prazo: ${pub.prazo_dias} dias (limite sugerido: ${pub.data_limite}, base: ${pub.prazo_base_legal})`,
      pub.conteudo && `\n${pub.conteudo}`,
    ].filter(Boolean).join('\n');
    const caseId = pub.caso_id || pub.caso?.id || '';
    const clientId = caseId ? (cases.find(c => c.id === caseId)?.client_id || '') : '';
    return {
      prefillTitle: `${tipo}${processo}`,
      prefillDescription: descricao,
      prefillCaseId: caseId,
      prefillClientId: clientId,
      prefillDueDate: pub.data_limite || '',
    };
  };

  const handleTarefaCriada = async (task) => {
    const pub = taskModalPub;
    setTaskModalPub(null);
    if (!pub || !task?.id) return;
    try {
      await window.PACApi.astrea.vincularTarefa(pub.id, task.id);
      await window.PACApi.astrea.marcarLida(pub.id, true);
      if (filtrosRef.current.lida !== 'true') {
        setPublicacoes(prev => prev.filter(p => p.id !== pub.id));
        setTotal(t => Math.max(0, t - 1));
      } else {
        setPublicacoes(prev => prev.map(p => p.id === pub.id ? { ...p, task_id: task.id, lida: true } : p));
      }
      setToast({ msg: `Tarefa "${task.title}" criada no Kanban e vinculada.`, type: 'ok' });
    } catch (e) {
      setToast({ msg: e.message || 'Tarefa criada, mas falhou ao vincular.', type: 'erro' });
    }
  };

  const setFiltro = (k, v) => setFiltros(prev => ({ ...prev, [k]: v }));

  const inputStyle = {
    padding: '7px 11px', border: '1.5px solid #E5E7EB', borderRadius: 8,
    fontSize: 13, background: '#fff', minWidth: 0,
  };

  const naoLidas = publicacoes.filter(p => !p.lida).length;

  const fmtDataHora = (iso) => {
    if (!iso) return '—';
    const d = new Date(iso);
    return `${String(d.getDate()).padStart(2, '0')}/${String(d.getMonth() + 1).padStart(2, '0')}/${d.getFullYear()} às ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
  };

  return (
    <div>
      {/* Última sincronização automática */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap',
        background: '#F8FAFF', border: '1.5px solid #E0E7FF', borderRadius: 10,
        padding: '9px 14px', marginBottom: 14, fontSize: 12.5, color: '#374151',
      }}>
        <Icon name="calendar" size={13} style={{ color: '#0D0D6B', flexShrink: 0 }} />
        {ultimaSync ? (
          <>
            <span>
              Última sincronização: <strong>{fmtDataHora(ultimaSync.data_sync)}</strong>
              {' · '}<strong>{ultimaSync.total_encontradas}</strong> publicação(ões) encontrada(s)
              {ultimaSync.total_novas > 0 && <> · <strong style={{ color: '#157F3D' }}>{ultimaSync.total_novas} nova(s)</strong></>}
            </span>
            {ultimaSync.houve_erro && (
              <span style={{ fontSize: 11, fontWeight: 700, background: 'rgba(220,38,38,.1)', color: '#DC2626', borderRadius: 5, padding: '1px 8px' }}>
                houve erro em parte da sincronização
              </span>
            )}
          </>
        ) : (
          <span style={{ color: '#9CA3AF' }}>Nenhuma sincronização realizada ainda — roda automaticamente às 07h (todos os dias).</span>
        )}
      </div>

      {/* Filtros */}
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 16, alignItems: 'center' }}>
        <input
          value={filtros.busca}
          onChange={e => setFiltro('busca', e.target.value)}
          onKeyDown={e => e.key === 'Enter' && load()}
          placeholder="Buscar no texto..."
          style={{ ...inputStyle, flex: '1 1 160px' }}
        />
        <select value={filtros.astrea_user_id} onChange={e => setFiltro('astrea_user_id', e.target.value)} style={{ ...inputStyle, flex: '0 0 190px' }}>
          <option value="">Todos os usuários</option>
          {astreaUsers.map(u => <option key={u.id} value={u.id}>{u.name}</option>)}
        </select>
        <input type="date" value={filtros.data_inicio} onChange={e => setFiltro('data_inicio', e.target.value)} style={{ ...inputStyle, flex: '0 0 140px' }} />
        <input type="date" value={filtros.data_fim} onChange={e => setFiltro('data_fim', e.target.value)} style={{ ...inputStyle, flex: '0 0 140px' }} />
        <select value={filtros.lida} onChange={e => setFiltro('lida', e.target.value)} style={{ ...inputStyle, flex: '0 0 120px' }}>
          <option value="">Todas</option>
          <option value="false">Não lidas</option>
          <option value="true">Lidas</option>
        </select>
        <button
          onClick={() => load()}
          style={{ padding: '7px 16px', background: '#0D0D6B', color: '#fff', border: 'none', borderRadius: 8, cursor: 'pointer', fontSize: 13, fontWeight: 600 }}
        >
          Filtrar
        </button>
        <button
          onClick={handleSincronizar}
          disabled={sincronizando}
          style={{
            padding: '7px 16px', background: sincronizando ? '#6B7280' : '#157F3D',
            color: '#fff', border: 'none', borderRadius: 8, cursor: sincronizando ? 'not-allowed' : 'pointer',
            fontSize: 13, fontWeight: 600, display: 'flex', alignItems: 'center', gap: 6,
          }}
        >
          <Icon name="search" size={13} />
          {sincronizando ? 'Sincronizando…' : 'Sincronizar agora'}
        </button>
      </div>

      {/* Stats */}
      <div style={{ display: 'flex', gap: 8, marginBottom: 16 }}>
        <div style={{ padding: '6px 14px', background: '#EFF6FF', borderRadius: 20, fontSize: 13, color: '#1E40AF', fontWeight: 600 }}>
          {total} publicação(ões)
        </div>
        {naoLidas > 0 && (
          <div style={{ padding: '6px 14px', background: '#FEF3C7', borderRadius: 20, fontSize: 13, color: '#D97706', fontWeight: 600 }}>
            {naoLidas} não lida(s)
          </div>
        )}
      </div>

      {/* Lista */}
      {loading ? (
        <div style={{ textAlign: 'center', padding: 40, color: '#9CA3AF', fontSize: 14 }}>Carregando publicações…</div>
      ) : publicacoes.length === 0 ? (
        <div style={{ textAlign: 'center', padding: 60, color: '#9CA3AF' }}>
          <Icon name="fileText" size={40} style={{ marginBottom: 12, opacity: 0.3 }} />
          <div style={{ fontSize: 15, fontWeight: 600, marginBottom: 4 }}>Nenhuma publicação encontrada</div>
          <div style={{ fontSize: 13 }}>Cadastre usuários Astrea e clique em "Sincronizar agora".</div>
        </div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {publicacoes.map(pub => (
            <div
              key={pub.id}
              onClick={() => setDetalhe(pub)}
              style={{
                background: pub.lida ? '#FAFAFA' : '#fff',
                border: `1.5px solid ${pub.lida ? '#E5E7EB' : '#BFDBFE'}`,
                borderLeft: `4px solid ${pub.lida ? '#9CA3AF' : '#0D0D6B'}`,
                borderRadius: 10, padding: '14px 18px', cursor: 'pointer',
                transition: 'box-shadow .15s',
              }}
              onMouseEnter={e => e.currentTarget.style.boxShadow = '0 4px 16px rgba(13,13,107,.1)'}
              onMouseLeave={e => e.currentTarget.style.boxShadow = ''}
            >
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 6 }}>
                <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
                  {pub.tipo_comunicacao && (
                    <span style={{ fontSize: 11, fontWeight: 700, background: '#EFF6FF', color: '#1E40AF', borderRadius: 5, padding: '2px 8px' }}>
                      {pub.tipo_comunicacao}
                    </span>
                  )}
                  {pub.court_formatted && (
                    <span style={{ fontSize: 11, color: '#6B7280', fontWeight: 600 }}>{pub.court_formatted}</span>
                  )}
                  <span style={{ fontSize: 11, color: '#9CA3AF' }}>{fmtDate(pub.release_date)}</span>
                </div>
                <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
                  <PrazoBadge pub={pub} />
                  {pub.task_id && (
                    <span style={{ fontSize: 11, background: '#EFF6FF', color: '#1E40AF', borderRadius: 5, padding: '2px 8px', fontWeight: 600 }}>
                      ✓ Tarefa
                    </span>
                  )}
                  {pub.caso && (
                    <span style={{ fontSize: 11, background: '#DCFCE7', color: '#157F3D', borderRadius: 5, padding: '2px 8px', fontWeight: 600 }}>
                      Caso vinculado
                    </span>
                  )}
                  <span style={{
                    fontSize: 11, fontWeight: 700, padding: '2px 8px', borderRadius: 5,
                    background: pub.lida ? '#F3F4F6' : '#FEF3C7',
                    color: pub.lida ? '#6B7280' : '#D97706',
                  }}>
                    {pub.lida ? 'Lida' : 'Nova'}
                  </span>
                </div>
              </div>

              {pub.numero_processo && (
                <div style={{ fontSize: 12, fontWeight: 700, color: '#0D0D6B', marginBottom: 6 }}>
                  {pub.numero_processo}
                </div>
              )}

              {pub.case_title && (
                <div style={{ fontSize: 12, color: '#6B7280', marginBottom: 6 }}>{pub.case_title}</div>
              )}

              {pub.conteudo && (
                <div style={{ fontSize: 13, color: '#374151', lineHeight: 1.6 }}>
                  {truncate(pub.conteudo, 300)}
                </div>
              )}

              {pub.astrea_user && (
                <div style={{ marginTop: 8, fontSize: 11, color: '#9CA3AF' }}>
                  Usuário Astrea: <strong>{pub.astrea_user.name}</strong>
                </div>
              )}
            </div>
          ))}
        </div>
      )}

      {/* Modal detalhe */}
      {detalhe && (
        <PublicacaoDetalhe
          pub={detalhe}
          cases={cases}
          onClose={() => setDetalhe(null)}
          onMarcarLida={handleMarcarLida}
          onVincular={handleVincular}
          onCriarTarefa={handleCriarTarefa}
        />
      )}

      {taskModalPub && window.NewTaskModal && (
        <window.NewTaskModal
          {...buildTaskPrefill(taskModalPub)}
          headerLabel="Nova tarefa — publicação Astrea"
          clients={clients}
          cases={cases}
          users={users}
          allTags={allTags}
          onClose={() => setTaskModalPub(null)}
          onCreated={handleTarefaCriada}
        />
      )}

      {toast && <Toast msg={toast.msg} type={toast.type} onClose={() => setToast(null)} />}
    </div>
  );
}

// ============================================================
// Aba — Usuários Astrea
// ============================================================

function AbaAstreaUsers({ astreaUsers, setAstreaUsers }) {
  const [modalOpen, setModalOpen] = React.useState(false);
  const [editando, setEditando] = React.useState(null);
  const [toast, setToast] = React.useState(null);

  const handleCreate = async (data) => {
    const novo = await window.PACApi.astrea.createUser(data);
    setAstreaUsers(prev => [...prev, novo].sort((a, b) => a.name.localeCompare(b.name)));
  };

  const handleUpdate = async (data) => {
    const updated = await window.PACApi.astrea.updateUser(editando.id, data);
    setAstreaUsers(prev => prev.map(u => u.id === editando.id ? updated : u));
  };

  const handleDelete = async (id, name) => {
    if (!confirm(`Desativar "${name}"? Ele deixará de ser sincronizado (as publicações já salvas permanecem).`)) return;
    try {
      await window.PACApi.astrea.deleteUser(id);
      setAstreaUsers(prev => prev.map(u => u.id === id ? { ...u, active: false } : u));
      setToast({ msg: 'Usuário desativado.', type: 'ok' });
    } catch (e) {
      setToast({ msg: e.message, type: 'erro' });
    }
  };

  const handleToggleAtivo = async (user) => {
    try {
      const updated = await window.PACApi.astrea.updateUser(user.id, { active: !user.active });
      setAstreaUsers(prev => prev.map(u => u.id === user.id ? updated : u));
    } catch (e) {
      setToast({ msg: e.message, type: 'erro' });
    }
  };

  const thStyle = { padding: '10px 14px', textAlign: 'left', fontSize: 11, fontWeight: 700, color: '#6B7280', textTransform: 'uppercase', letterSpacing: 0.5, borderBottom: '1.5px solid #E5E7EB' };
  const tdStyle = { padding: '12px 14px', fontSize: 13, borderBottom: '1px solid #F3F4F6', verticalAlign: 'middle' };

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 16 }}>
        <button
          onClick={() => { setEditando(null); setModalOpen(true); }}
          style={{ padding: '8px 18px', background: '#0D0D6B', color: '#fff', border: 'none', borderRadius: 8, cursor: 'pointer', fontSize: 13, fontWeight: 600 }}
        >
          + Cadastrar usuário Astrea
        </button>
      </div>

      {astreaUsers.length === 0 ? (
        <div style={{ textAlign: 'center', padding: 60, color: '#9CA3AF' }}>
          <Icon name="users" size={40} style={{ marginBottom: 12, opacity: 0.3 }} />
          <div style={{ fontSize: 15, fontWeight: 600, marginBottom: 4 }}>Nenhum usuário Astrea cadastrado</div>
          <div style={{ fontSize: 13 }}>Cadastre credenciais de login do Astrea para sincronizar publicações automaticamente.</div>
        </div>
      ) : (
        <div style={{ background: '#fff', border: '1.5px solid #E5E7EB', borderRadius: 12, overflow: 'hidden' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse' }}>
            <thead style={{ background: '#F9FAFB' }}>
              <tr>
                <th style={thStyle}>Nome</th>
                <th style={thStyle}>E-mail (login)</th>
                <th style={thStyle}>Última sincronização</th>
                <th style={thStyle}>Status</th>
                <th style={{ ...thStyle, textAlign: 'right' }}>Ações</th>
              </tr>
            </thead>
            <tbody>
              {astreaUsers.map(u => (
                <tr key={u.id} style={{ transition: 'background .1s' }}
                  onMouseEnter={e => e.currentTarget.style.background = '#FAFAFA'}
                  onMouseLeave={e => e.currentTarget.style.background = ''}
                >
                  <td style={tdStyle}>
                    <span style={{ fontWeight: 600, color: '#111827' }}>{u.name}</span>
                  </td>
                  <td style={tdStyle}>{u.email}</td>
                  <td style={tdStyle}>
                    {u.last_sync_at ? (
                      <span style={{ color: u.last_sync_ok === false ? '#DC2626' : '#374151' }}>
                        {new Date(u.last_sync_at).toLocaleString('pt-BR')}
                        {u.last_sync_ok === false && ' (erro)'}
                      </span>
                    ) : '—'}
                  </td>
                  <td style={tdStyle}>
                    <span style={{
                      fontSize: 11, fontWeight: 700, padding: '3px 10px', borderRadius: 20,
                      background: u.active ? '#DCFCE7' : '#F3F4F6',
                      color: u.active ? '#157F3D' : '#9CA3AF',
                    }}>
                      {u.active ? '✓ Ativo' : '✗ Inativo'}
                    </span>
                  </td>
                  <td style={{ ...tdStyle, textAlign: 'right' }}>
                    <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
                      <button
                        onClick={() => { setEditando(u); setModalOpen(true); }}
                        style={{ padding: '4px 12px', border: '1.5px solid #E5E7EB', borderRadius: 6, background: '#fff', cursor: 'pointer', fontSize: 12 }}
                      >
                        Editar
                      </button>
                      <button
                        onClick={() => handleToggleAtivo(u)}
                        style={{ padding: '4px 12px', border: '1.5px solid #E5E7EB', borderRadius: 6, background: '#fff', cursor: 'pointer', fontSize: 12 }}
                      >
                        {u.active ? 'Desativar' : 'Ativar'}
                      </button>
                      <button
                        onClick={() => handleDelete(u.id, u.name)}
                        style={{ padding: '4px 12px', border: '1.5px solid #FCA5A5', borderRadius: 6, background: '#FEF2F2', cursor: 'pointer', fontSize: 12, color: '#DC2626' }}
                      >
                        Remover
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {modalOpen && (
        <AstreaUserModal
          astreaUser={editando}
          onSave={editando ? handleUpdate : handleCreate}
          onClose={() => { setModalOpen(false); setEditando(null); }}
        />
      )}

      {toast && <Toast msg={toast.msg} type={toast.type} onClose={() => setToast(null)} />}
    </div>
  );
}

// ============================================================
// Componente Principal — PublicacoesAstrea
// ============================================================

const PublicacoesAstrea = () => {
  const [aba, setAba] = React.useState('publicacoes');
  const [astreaUsers, setAstreaUsers] = React.useState([]);
  const [loadingUsers, setLoadingUsers] = React.useState(true);

  React.useEffect(() => {
    window.PACApi.astrea.listUsers()
      .then(list => setAstreaUsers(list || []))
      .catch(() => {})
      .finally(() => setLoadingUsers(false));
  }, []);

  const tabStyle = (key) => ({
    padding: '8px 20px', border: 'none', cursor: 'pointer',
    borderBottom: aba === key ? '2.5px solid #0D0D6B' : '2.5px solid transparent',
    color: aba === key ? '#0D0D6B' : '#6B7280',
    fontWeight: aba === key ? 700 : 500,
    background: 'none', fontSize: 14, transition: 'color .15s',
  });

  return (
    <div style={{ padding: '24px 28px', maxWidth: 960, margin: '0 auto' }}>
      {/* Header */}
      <div style={{ marginBottom: 24 }}>
        <h1 style={{ fontSize: 22, fontWeight: 800, color: '#0D0D6B', margin: 0 }}>Publicações Astrea</h1>
        <p style={{ fontSize: 13, color: '#6B7280', margin: '4px 0 0' }}>
          Sincronização automática via API do Astrea · Sync automático às 07h (todos os dias)
        </p>
      </div>

      {/* Tabs */}
      <div style={{ display: 'flex', gap: 0, borderBottom: '1.5px solid #E5E7EB', marginBottom: 24 }}>
        <button style={tabStyle('publicacoes')} onClick={() => setAba('publicacoes')}>
          Publicações
        </button>
        <button style={tabStyle('usuarios')} onClick={() => setAba('usuarios')}>
          Usuários Astrea
          <span style={{
            marginLeft: 8, fontSize: 11, background: '#E5E7EB',
            borderRadius: 10, padding: '1px 7px', fontWeight: 700, color: '#374151',
          }}>
            {astreaUsers.length}
          </span>
        </button>
      </div>

      {loadingUsers ? (
        <div style={{ textAlign: 'center', padding: 40, color: '#9CA3AF' }}>Carregando…</div>
      ) : (
        <>
          {aba === 'publicacoes' && <AbaPublicacoesAstrea astreaUsers={astreaUsers} />}
          {aba === 'usuarios' && <AbaAstreaUsers astreaUsers={astreaUsers} setAstreaUsers={setAstreaUsers} />}
        </>
      )}
    </div>
  );
};

Object.assign(window, { PublicacoesAstrea });
