/* ================================================================
   Khronus — Clientes
   ----------------------------------------------------------------
   O cadastro de clientes é DO KHRONUS, por estúdio. Isso é o que faz
   a tela funcionar inteira para quem nunca vai assinar o Blindagem.

   Quem também usa o Blindagem ganha duas coisas de graça:

     1. os clientes de lá aparecem em "Trazer do Blindagem", e vêm pra
        cá com um clique, guardando o vínculo de origem;
     2. o que você cria ou edita aqui aparece lá sozinho.

   O espelho mora no banco (gatilho em shared_clients), não nesta tela.
   Assim vale pra qualquer caminho que crie cliente, e não depende de
   cada tela lembrar de gravar nos dois lugares.

   Arquivo inteiro dentro de IIFE: sem empacotador, dois arquivos que
   declarem o mesmo nome no topo derrubam o app todo.
   ================================================================ */
(function () {
  const { useState, useEffect, useMemo } = React;
  const { LucideIcon, Btn } = window;
  /* Formas vêm do sistema, não desta tela. Ver a camada de componentes
     no shared.jsx e as medidas no design-system.md. */
  const { PageContainer, PageHeader, Card, Campo, Modal, EstadoVazio,
          Carregando, estiloInput } = window.DS;

  function soDigitos(v) { return String(v || '').replace(/\D/g, ''); }

  function formatarWhats(tel) {
    const d = soDigitos(tel);
    if (d.length === 13 && d.startsWith('55')) return `(${d.slice(2,4)}) ${d.slice(4,9)}-${d.slice(9)}`;
    if (d.length === 11) return `(${d.slice(0,2)}) ${d.slice(2,7)}-${d.slice(7)}`;
    return tel || '';
  }

  function ModalCliente({ item, onFechar, onSalvo }) {
    const [nome, setNome] = useState(item?.nome || '');
    const [whatsapp, setWhatsapp] = useState(item?.whatsapp || '');
    const [email, setEmail] = useState(item?.email || '');
    const [aniversario, setAniversario] = useState(item?.data_aniversario || '');
    const [indicadoPor, setIndicadoPor] = useState(item?.indicado_por || '');
    const [obs, setObs] = useState(item?.observacoes || '');
    /* Campos que o CONTRATO precisa. Ficam aqui para o cliente nascer
       pronto: preenchido uma vez no Khronus, o contrato no Blindagem já
       sai completo, sem ter que redigitar CPF e endereço na hora em que
       o cliente está esperando pra assinar.

       'pf' e 'pj' são os valores que o Blindagem aceita, não invenção
       nossa: ele tem uma regra no banco que recusa qualquer outro. */
    const [tipoPessoa, setTipoPessoa] = useState(item?.tipo_pessoa || 'pf');
    const [cpf, setCpf] = useState(item?.cpf || '');
    const [cnpj, setCnpj] = useState(item?.cnpj || '');
    const [razaoSocial, setRazaoSocial] = useState(item?.razao_social || '');
    const [endereco, setEndereco] = useState(item?.endereco || '');
    const [bairro, setBairro] = useState(item?.bairro || '');
    const [cidadeEstado, setCidadeEstado] = useState(item?.cidade_estado || '');
    const [salvando, setSalvando] = useState(false);

    const ehPJ = tipoPessoa === 'pj';

    async function salvar() {
      if (!nome.trim()) return;
      setSalvando(true);
      const dados = {
        nome: nome.trim(),
        whatsapp: soDigitos(whatsapp) || null,
        email: email.trim() || null,
        data_aniversario: aniversario || null,
        indicado_por: indicadoPor.trim() || null,
        observacoes: obs.trim() || null,
        tipo_pessoa: tipoPessoa,
        // Guarda só o documento do tipo escolhido: manter os dois
        // preenchidos deixaria o contrato sem saber qual usar.
        cpf: ehPJ ? null : (cpf.trim() || null),
        cnpj: ehPJ ? (cnpj.trim() || null) : null,
        razao_social: ehPJ ? (razaoSocial.trim() || null) : null,
        endereco: endereco.trim() || null,
        bairro: bairro.trim() || null,
        cidade_estado: cidadeEstado.trim() || null,
      };
      const { error } = item?.id
        ? await window.db.from('shared_clients').update(dados).eq('id', item.id)
        : await window.db.from('shared_clients').insert(dados);
      setSalvando(false);
      if (error) { alert('Não consegui salvar: ' + error.message); return; }
      onSalvo();
    }

    /* Excluir tira o cliente dos dois lados, para os cadastros não
       divergirem. A exceção é cliente com contrato assinado: o banco
       recusa, e o motivo aparece aqui. Não é capricho de tela, é
       proteção real — a ligação do contrato com o cliente é do tipo que
       some em silêncio, e você só descobriria quando precisasse dela. */
    async function excluir() {
      if (!item?.id) return;
      if (!confirm(`Excluir ${item.nome}?\n\n`
        + 'Ele sai do Khronus e também do Blindagem. Cliente com contrato '
        + 'assinado não pode ser excluído.')) return;
      const { error } = await window.db.from('shared_clients').delete().eq('id', item.id);
      if (error) { alert(error.message); return; }
      onSalvo();
    }

    return (
      <Modal titulo={item?.id ? 'Editar cliente' : 'Novo cliente'} onClose={onFechar}
        rodape={<>
          {item?.id && <Btn variant="danger" icon="trash-2" onClick={excluir}>Excluir</Btn>}
          <span style={{ flex: 1 }} />
          <Btn onClick={onFechar}>Cancelar</Btn>
          <Btn variant="primary" onClick={salvar} disabled={!nome.trim() || salvando}>
            {salvando ? 'Salvando…' : 'Salvar'}
          </Btn>
        </>}>
        <Campo label="Nome">
          <input autoFocus style={estiloInput} value={nome} onChange={e => setNome(e.target.value)} />
        </Campo>
        <Campo label="WhatsApp">
          <input style={estiloInput} value={whatsapp} onChange={e => setWhatsapp(e.target.value)}
            placeholder="(48) 99999-0000" />
        </Campo>
        <Campo label="E-mail">
          <input style={estiloInput} value={email} onChange={e => setEmail(e.target.value)} />
        </Campo>
        <Campo label="Aniversário">
          <input type="date" style={estiloInput} value={aniversario || ''}
            onChange={e => setAniversario(e.target.value)} />
        </Campo>
        <Campo label="Indicado por">
          <input style={estiloInput} value={indicadoPor}
            onChange={e => setIndicadoPor(e.target.value)} />
        </Campo>
        <Campo label="Observações">
          <textarea rows={3} style={{ ...estiloInput, resize: 'vertical' }} value={obs}
            onChange={e => setObs(e.target.value)} />
        </Campo>

        <div style={{ margin: '18px 0 12px', paddingTop: 14,
          borderTop: '1px solid var(--app-border)' }}>
          <div style={{ fontSize: 'var(--fs-xs)', fontFamily: 'Roboto,sans-serif', fontWeight: 900,
            letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--text-3)' }}>
            Dados para contrato
          </div>
          <div style={{ fontSize: 'var(--fs-sm)', fontFamily: 'Roboto,sans-serif', color: 'var(--text-3)',
            marginTop: 4 }}>
            Preenchendo aqui, o contrato no Blindagem já sai completo.
          </div>
        </div>

        <Campo label="Tipo">
          <div style={{ display: 'flex', gap: 6 }}>
            {[{ id: 'pf', label: 'Pessoa física' }, { id: 'pj', label: 'Pessoa jurídica' }].map(t => (
              <button key={t.id} onClick={() => setTipoPessoa(t.id)}
                style={{ flex: 1, padding: '8px 12px', borderRadius: 'var(--r-sm)', cursor: 'pointer',
                  fontSize: 'var(--fs-md)', fontFamily: 'Roboto,sans-serif', fontWeight: 700,
                  background: tipoPessoa === t.id ? 'rgba(234,170,65,.15)' : 'var(--app-surface-2)',
                  border: `1px solid ${tipoPessoa === t.id ? 'rgba(234,170,65,.4)' : 'var(--app-border)'}`,
                  color: tipoPessoa === t.id ? 'var(--accent)' : 'var(--text-2)' }}>
                {t.label}
              </button>
            ))}
          </div>
        </Campo>

        {ehPJ ? (
          <>
            <Campo label="CNPJ">
              <input style={estiloInput} value={cnpj} onChange={e => setCnpj(e.target.value)}
                placeholder="00.000.000/0001-00" />
            </Campo>
            <Campo label="Razão social">
              <input style={estiloInput} value={razaoSocial}
                onChange={e => setRazaoSocial(e.target.value)} />
            </Campo>
          </>
        ) : (
          <Campo label="CPF">
            <input style={estiloInput} value={cpf} onChange={e => setCpf(e.target.value)}
              placeholder="000.000.000-00" />
          </Campo>
        )}

        <Campo label="Endereço">
          <input style={estiloInput} value={endereco} onChange={e => setEndereco(e.target.value)}
            placeholder="Rua, número, complemento" />
        </Campo>
        <Campo label="Bairro">
          <input style={estiloInput} value={bairro} onChange={e => setBairro(e.target.value)} />
        </Campo>
        <Campo label="Cidade e estado">
          <input style={estiloInput} value={cidadeEstado}
            onChange={e => setCidadeEstado(e.target.value)} placeholder="Florianópolis - SC" />
        </Campo>

        {item?.blindagem_client_id && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 'var(--fs-sm)',
            fontFamily: 'Roboto,sans-serif', color: 'var(--text-3)' }}>
            <LucideIcon icon="link" size={12} />
            Ligado ao cadastro do Blindagem. O que mudar aqui muda lá.
          </div>
        )}
      </Modal>
    );
  }

  function ClientesScreen() {
    const [lista, setLista] = useState([]);
    const [doBlindagem, setDoBlindagem] = useState([]);
    const [temBlindagem, setTemBlindagem] = useState(false);
    const [contratos, setContratos] = useState({});
    const [busca, setBusca] = useState('');
    const [modal, setModal] = useState(null);
    const [importando, setImportando] = useState(null);
    const [carregando, setCarregando] = useState(true);

    async function carregar() {
      const { data } = await window.db.from('shared_clients').select('*').order('nome');
      setLista(data || []);

      /* Os clientes do Blindagem vêm de uma view que já filtra pelo
         próprio usuário. Se a pessoa não usa o Blindagem, a consulta
         simplesmente volta vazia — e aí a seção nem aparece, em vez de
         mostrar um espaço morto. */
      const { data: bl, error } = await window.db.from('clientes_blindagem')
        .select('*').order('nome');
      setDoBlindagem(bl || []);
      setTemBlindagem(!error && (bl || []).length > 0);

      /* Contagem de contratos, o mesmo selo que a tela de Clientes do
         Blindagem mostra. É o dado que diz de relance quem já virou
         trabalho e quem ainda é só cadastro. */
      const { data: ct } = await window.db.from('contratos_do_cliente').select('*');
      const mapa = {};
      for (const linha of ct || []) mapa[linha.blindagem_client_id] = linha.contratos;
      setContratos(mapa);

      setCarregando(false);
    }

    useEffect(() => { carregar(); }, []);

    const jaVinculados = useMemo(
      () => new Set(lista.map(c => c.blindagem_client_id).filter(Boolean)), [lista]);

    const pendentesDoBlindagem = useMemo(
      () => doBlindagem.filter(c => !jaVinculados.has(c.id)), [doBlindagem, jaVinculados]);

    const filtrados = useMemo(() => {
      const t = busca.trim().toLowerCase();
      if (!t) return lista;
      return lista.filter(c => `${c.nome || ''} ${c.email || ''} ${c.whatsapp || ''}`
        .toLowerCase().includes(t));
    }, [lista, busca]);

    /* Traz um cliente do Blindagem. O vínculo vai preenchido no insert,
       e é isso que impede o gatilho de criar uma cópia nova lá. */
    async function importar(cliente) {
      setImportando(cliente.id);
      const { error } = await window.db.from('shared_clients').insert({
        nome: cliente.nome,
        whatsapp: soDigitos(cliente.telefone) || null,
        email: cliente.email || null,
        observacoes: cliente.notas || null,
        // Traz também o que o contrato usa. Sem isto, um cliente que já
        // estava completo no Blindagem chegaria pela metade aqui, e a
        // primeira edição feita no Khronus apagaria os dados de lá.
        tipo_pessoa: cliente.tipo_pessoa || null,
        cpf: cliente.cpf || null,
        cnpj: cliente.cnpj || null,
        razao_social: cliente.razao_social || null,
        endereco: cliente.endereco || null,
        bairro: cliente.bairro || null,
        cidade_estado: cliente.cidade_estado || null,
        blindagem_client_id: cliente.id,
      });
      setImportando(null);
      if (error) { alert('Não consegui trazer: ' + error.message); return; }
      carregar();
    }

    async function importarTodos() {
      for (const c of pendentesDoBlindagem) await importar(c);
    }

    return (
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
        {/* Cabeçalho no formato do Blindagem: título grande com subtítulo
            dentro do conteúdo, e as ações à direita na mesma linha. A
            barra fina de antes economizava altura, mas fazia as duas
            telas parecerem produtos diferentes já no primeiro olhar. */}
        <PageContainer>
          <PageHeader title="Clientes"
            description="Todos os seus clientes em um lugar."
            actions={
              <Btn variant="primary" icon="plus" onClick={() => setModal({})}>Novo cliente</Btn>
            } />

          {/* Busca de largura total com a lupa dentro, igual à de lá */}
          <div style={{ position: 'relative', marginBottom: 24 }}>
            <span style={{ position: 'absolute', left: 14, top: '50%', transform: 'translateY(-50%)',
              display: 'flex', pointerEvents: 'none', color: 'var(--text-3)' }}>
              <LucideIcon icon="search" size={15} />
            </span>
            <input value={busca} onChange={e => setBusca(e.target.value)}
              placeholder="Buscar por nome, CPF/CNPJ, e-mail ou WhatsApp"
              style={{ ...estiloInput, padding: '12px 14px 12px 40px',
                borderRadius: 'var(--r-md)' }} />
          </div>

          {carregando ? (
            <Carregando />
          ) : (
            <>
              {lista.length === 0 && (
                <EstadoVazio icone="users"
                  mensagem={temBlindagem
                    ? 'Nenhum cliente aqui ainda. Traga os do Blindagem abaixo, ou crie um novo.'
                    : 'Nenhum cliente ainda. Cadastre o primeiro.'}
                  acao={<Btn variant="primary" icon="plus"
                    onClick={() => setModal({})}>Novo cliente</Btn>} />
              )}

              {/* Cards em grade, como no Blindagem. A lista em linha
                  cabia mais gente na tela, mas cliente não é item de
                  planilha: com avatar, selo de contrato e cidade, você
                  reconhece a pessoa antes de ler o nome inteiro. */}
              <div style={{ display: 'grid', gap: 16,
                gridTemplateColumns: 'repeat(auto-fill, minmax(320px, 1fr))' }}>
                {filtrados.map(c => {
                  const qtd = contratos[c.blindagem_client_id] || 0;
                  const doc = c.tipo_pessoa === 'pj' ? c.cnpj : c.cpf;
                  const linha2 = [doc || formatarWhats(c.whatsapp), c.email]
                    .filter(Boolean).join(' · ');
                  return (
                    <div key={c.id} onClick={() => setModal(c)}
                      style={{ cursor: 'pointer', padding: 16, borderRadius: 'var(--r-lg)',
                        background: 'var(--app-surface)', border: '1px solid var(--app-border)' }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 12,
                        marginBottom: 12 }}>
                        <div style={{ width: 40, height: 40, borderRadius: 'var(--r-full)',
                          background: 'var(--app-surface-2)', display: 'flex', flexShrink: 0,
                          alignItems: 'center', justifyContent: 'center', color: 'var(--text-3)' }}>
                          <LucideIcon icon="user" size={18} />
                        </div>
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                            <span style={{ fontSize: 'var(--fs-xl)', fontFamily: 'Roboto,sans-serif',
                              fontWeight: 700, color: 'var(--text-1)', overflow: 'hidden',
                              textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{c.nome}</span>
                            {c.blindagem_client_id && (
                              <span title="Ligado ao Blindagem"
                                style={{ display: 'flex', flexShrink: 0, color: 'var(--text-3)' }}>
                                <LucideIcon icon="link" size={11} />
                              </span>
                            )}
                          </div>
                          <div style={{ fontSize: 'var(--fs-sm)', fontFamily: 'Roboto,sans-serif',
                            color: 'var(--text-3)', overflow: 'hidden', textOverflow: 'ellipsis',
                            whiteSpace: 'nowrap' }}>
                            {linha2 || '—'}
                          </div>
                        </div>
                      </div>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                        {qtd > 0 && (
                          <span style={{ padding: '4px 8px', borderRadius: 'var(--r-sm)',
                            background: 'var(--accent-soft)', border: '1px solid var(--accent-line)',
                            color: 'var(--accent)', fontSize: 'var(--fs-xs)',
                            fontFamily: 'Roboto,sans-serif', fontWeight: 700 }}>
                            {qtd} {qtd === 1 ? 'contrato' : 'contratos'}
                          </span>
                        )}
                        <span style={{ marginLeft: 'auto', fontSize: 'var(--fs-sm)',
                          fontFamily: 'Roboto,sans-serif', color: 'var(--text-3)' }}>
                          {c.cidade_estado || ''}
                        </span>
                      </div>
                    </div>
                  );
                })}
              </div>

              {temBlindagem && pendentesDoBlindagem.length > 0 && (
                <div style={{ marginTop: 26 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
                    <div style={{ fontSize: 'var(--fs-xs)', fontFamily: 'Roboto,sans-serif', fontWeight: 900,
                      letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--text-3)' }}>
                      Trazer do Blindagem · {pendentesDoBlindagem.length}
                    </div>
                    <Btn icon="download" onClick={importarTodos}>Trazer todos</Btn>
                  </div>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                    {pendentesDoBlindagem.map(c => (
                      <div key={c.id} style={{ display: 'flex', alignItems: 'center', gap: 12,
                        padding: '10px 12px', borderRadius: 'var(--r-md)', background: 'var(--overlay-05)',
                        border: '1px dashed var(--app-border)' }}>
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <div style={{ fontSize: 'var(--fs-md)', fontFamily: 'Roboto,sans-serif',
                            fontWeight: 700, color: 'var(--text-2)' }}>{c.nome}</div>
                          <div style={{ fontSize: 'var(--fs-sm)', fontFamily: 'Roboto,sans-serif',
                            color: 'var(--text-3)' }}>
                            {[formatarWhats(c.telefone), c.email].filter(Boolean).join(' · ') || '—'}
                          </div>
                        </div>
                        <Btn icon="plus" onClick={() => importar(c)}
                          disabled={importando === c.id}>
                          {importando === c.id ? 'Trazendo…' : 'Trazer'}
                        </Btn>
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </>
          )}
        </PageContainer>

        {modal && (
          <ModalCliente item={modal.id ? modal : null} onFechar={() => setModal(null)}
            onSalvo={() => { setModal(null); carregar(); }} />
        )}
      </div>
    );
  }

  window.ClientesScreen = ClientesScreen;
})();
