// Tela: Oportunidades — pipeline + tabela / kanban

const { useState: useOpState } = React;

/* ─── Modal criar / editar oportunidade ─────────────────── */
function OportunidadeModal({ stages, onClose, onCreate, onUpdate, initialData }) {
  const isEdit = !!initialData;
  const [conta, setConta] = useOpState(initialData?.conta  || '');
  const [valor, setValor] = useOpState(initialData?.valor  ? String(initialData.valor) : '');
  const [etapa, setEtapa] = useOpState(initialData?.etapa  || 'Qualificado');
  const [prob,  setProb]  = useOpState(initialData?.prob   ?? 50);
  const [fecha, setFecha] = useOpState(initialData?.fecha  || '');
  const toast = useToast();

  const valid = conta.trim().length > 0;

  const submit = () => {
    if (!valid) return;
    const dados = {
      conta: conta.trim(),
      valor: parseInt(String(valor).replace(/\D/g,'')) || 0,
      etapa, prob,
      fecha: fecha || 'A definir',
      dono:  initialData?.dono || CONTATOS[0],
    };
    if (isEdit) {
      if (onUpdate) onUpdate(dados);
      toast(`"${conta.trim()}" atualizada ✓`);
    } else {
      if (onCreate) onCreate({ ...dados, id: Date.now() });
      toast(`Oportunidade "${conta.trim()}" criada ✓`);
    }
    onClose();
  };

  return (
    <div className="modal-wrap" onClick={onClose}>
      <div className="card modal-card" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <div className="modal-title">
              {isEdit ? <>Editar <em>Oportunidade</em></> : <>Nova <em>Oportunidade</em></>}
            </div>
            <div className="modal-sub muted">
              {isEdit ? `Editando: ${initialData.conta}` : 'Adicione um negócio ao pipeline'}
            </div>
          </div>
          <div className="mini-btn" onClick={onClose}>{ICN.x}</div>
        </div>

        <div className="form-grid">
          <div className="field" style={{gridColumn:'1/-1'}}>
            <label className="field-lbl">Conta / Empresa *</label>
            <input className="ezz-input" placeholder="Ex: Indústria Aurora"
              value={conta} onChange={e => setConta(e.target.value)} autoFocus
              onKeyDown={e => e.key === 'Enter' && submit()} />
          </div>
          <div className="field">
            <label className="field-lbl">Valor estimado</label>
            <div className="ezz-input ezz-input-prefix">
              <span className="muted" style={{fontSize:13,fontWeight:600}}>R$</span>
              <input placeholder="0" value={valor} onChange={e => setValor(e.target.value)}
                style={{border:0,outline:0,flex:1,fontFamily:'inherit',fontSize:13,background:'transparent'}} />
            </div>
          </div>
          <div className="field">
            <label className="field-lbl">Etapa</label>
            <select className="ezz-input" value={etapa} onChange={e => setEtapa(e.target.value)} style={{appearance:'auto'}}>
              {stages.map(s => <option key={s}>{s}</option>)}
            </select>
          </div>
          <div className="field">
            <label className="field-lbl">Probabilidade de fechar · {prob}%</label>
            <input type="range" min="0" max="100" step="5" value={prob}
              onChange={e => setProb(+e.target.value)} className="op-range" />
          </div>
          <div className="field">
            <label className="field-lbl">Data de fechamento prevista</label>
            <input className="ezz-input" placeholder="Ex: 30/06"
              value={fecha} onChange={e => setFecha(e.target.value)} />
          </div>
        </div>

        <div className="modal-actions">
          <button className="btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn-primary" onClick={submit} disabled={!valid} style={{opacity: valid ? 1 : 0.5}}>
            {isEdit ? <>{ICN.edit} Salvar alterações</> : <>{ICN.plus} Criar oportunidade</>}
          </button>
        </div>
      </div>
    </div>
  );
}

/* ─── Modal atribuir responsável ────────────────────────── */
function AtribuirOpModal({ op, onClose, onAtribuir }) {
  const [sel, setSel] = useOpState(op.dono?.id ?? 0);
  const toast = useToast();
  const submit = () => {
    const c = CONTATOS.find(ct => ct.id === sel) || CONTATOS[0];
    onAtribuir(c);
    toast(`Atribuído para ${c.nome.split(' ')[0]} ✓`);
    onClose();
  };
  return (
    <div className="modal-wrap" onClick={onClose}>
      <div className="card modal-card" onClick={e => e.stopPropagation()} style={{width: 440}}>
        <div className="modal-head">
          <div>
            <div className="modal-title">Atribuir <em>responsável</em></div>
            <div className="modal-sub muted">{op.conta}</div>
          </div>
          <div className="mini-btn" onClick={onClose}>{ICN.x}</div>
        </div>
        <div className="field-lbl" style={{marginBottom: 10}}>Selecionar responsável</div>
        <div className="col" style={{gap: 6, maxHeight: 320, overflowY: 'auto'}}>
          {CONTATOS.slice(0, 8).map(ct => (
            <div key={ct.id}
              onClick={() => setSel(ct.id)}
              style={{
                display:'flex', alignItems:'center', gap:12,
                padding:'10px 12px', borderRadius:12, cursor:'default',
                background: sel === ct.id ? 'oklch(0.95 0.05 250 / 0.5)' : 'transparent',
              }}>
              <img src={ct.avatar} style={{width:36,height:36,borderRadius:'50%',objectFit:'cover'}} alt="" />
              <div className="col" style={{flex:1}}>
                <div style={{fontSize:13,fontWeight:600}}>{ct.nome.split(' ').slice(0,2).join(' ')}</div>
                <div className="muted" style={{fontSize:11.5}}>{ct.cargo}</div>
              </div>
              {sel === ct.id && <span style={{color:'oklch(0.55 0.16 250)'}}>{ICN.check}</span>}
            </div>
          ))}
        </div>
        <div className="modal-actions">
          <button className="btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn-primary" onClick={submit}>{ICN.check} Confirmar</button>
        </div>
      </div>
    </div>
  );
}

/* ─── Modal reagendar fechamento ────────────────────────── */
function ReagendarModal({ op, onClose, onSave }) {
  const [data, setData] = useOpState('');
  const toast = useToast();
  const valid = data.trim().length > 0;
  const submit = () => {
    onSave(data);
    toast(`Fechamento reagendado para ${data} ✓`);
    onClose();
  };
  return (
    <div className="modal-wrap" onClick={onClose}>
      <div className="card modal-card" onClick={e => e.stopPropagation()} style={{width: 400}}>
        <div className="modal-head">
          <div>
            <div className="modal-title">Reagendar <em>fechamento</em></div>
            <div className="modal-sub muted">{op.conta} · atual: {op.fecha}</div>
          </div>
          <div className="mini-btn" onClick={onClose}>{ICN.x}</div>
        </div>
        <div className="field" style={{marginBottom: 20}}>
          <label className="field-lbl">Nova data de fechamento *</label>
          <input className="ezz-input" placeholder="Ex: 15/07"
            value={data} onChange={e => setData(e.target.value)} autoFocus
            onKeyDown={e => e.key === 'Enter' && valid && submit()} />
        </div>
        <div className="modal-actions">
          <button className="btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn-primary" onClick={submit} disabled={!valid} style={{opacity: valid?1:0.5}}>
            {ICN.cal} Reagendar
          </button>
        </div>
      </div>
    </div>
  );
}

const opHeaders = () => { const t = localStorage.getItem('ezza_token'); return { 'Content-Type':'application/json', ...(t?{'Authorization':`Bearer ${t}`}:{}) }; };

function Oportunidades({ goto, onOpenContact }) {
  const stages = ["Qualificado", "Proposta", "Negociação", "Fechado"];
  const [localOps, setLocalOps] = useOpState([...OPORTUNIDADES]);

  React.useEffect(() => {
    fetch('/api/oportunidades', { headers: opHeaders() })
      .then(r => r.json())
      .then(d => { if (d.ok && d.oportunidades.length) setLocalOps(d.oportunidades.map(o => ({ ...o, valor: parseFloat(o.valor)||0, dono: { nome: o.dono_nome || 'Equipe', avatar: AVATAR_URLS[0] } }))); })
      .catch(() => {});
  }, []);
  const [view, setView] = useOpState('lista');
  const [stageFilter, setStageFilter] = useOpState(null);
  const [sort, setSort] = useOpState({ col: 'valor', dir: 'desc' });
  const [filterOpen, setFilterOpen] = useOpState(false);
  const [exportOpen, setExportOpen] = useOpState(false);
  const [novoOpen, setNovoOpen] = useOpState(false);
  const [editFor,      setEditFor]      = useOpState(null);
  const [atribuirFor,  setAtribuirFor]  = useOpState(null);
  const [reagendarFor, setReagendarFor] = useOpState(null);
  const [probMin, setProbMin] = useOpState(0);
  const [valMin, setValMin] = useOpState(0);
  const [donoFilter, setDonoFilter] = useOpState('Todos');
  const toast = useToast();


  // Fecha painéis flutuantes ao clicar fora (setTimeout evita que o próprio clique que abriu feche imediatamente)
  React.useEffect(() => {
    if (!exportOpen && !filterOpen) return;
    const h = () => { setExportOpen(false); setFilterOpen(false); };
    const timer = setTimeout(() => window.addEventListener('click', h), 0);
    return () => { clearTimeout(timer); window.removeEventListener('click', h); };
  }, [exportOpen, filterOpen]);

  const donos = ['Todos', ...new Set(localOps.map(o => o.dono.nome.split(' ').slice(0,2).join(' ')))];

  let filtradas = localOps.filter(o => {
    if (stageFilter && o.etapa !== stageFilter) return false;
    if (o.prob < probMin) return false;
    if (o.valor < valMin) return false;
    if (donoFilter !== 'Todos' && o.dono.nome.split(' ').slice(0,2).join(' ') !== donoFilter) return false;
    return true;
  });

  filtradas = [...filtradas].sort((a, b) => {
    const dir = sort.dir === 'asc' ? 1 : -1;
    if (sort.col === 'conta') return dir * a.conta.localeCompare(b.conta);
    if (sort.col === 'valor') return dir * (a.valor - b.valor);
    if (sort.col === 'etapa') return dir * stages.indexOf(a.etapa) - stages.indexOf(b.etapa) * dir + (a.valor - b.valor) * 0; // simple
    if (sort.col === 'prob')  return dir * (a.prob - b.prob);
    if (sort.col === 'fecha') return dir * a.fecha.localeCompare(b.fecha);
    return 0;
  });

  const totalsByStage = stages.map(s => localOps.filter(o => o.etapa === s).reduce((sum, o) => sum + o.valor, 0));
  const grandTotal = localOps.reduce((s, o) => s + o.valor, 0);
  const totalFiltrado = filtradas.reduce((s, o) => s + o.valor, 0);

  const filtrosAtivos = (stageFilter ? 1 : 0) + (probMin > 0 ? 1 : 0) + (valMin > 0 ? 1 : 0) + (donoFilter !== 'Todos' ? 1 : 0);

  const exportOps = (format) => {
    setExportOpen(false);
    const rows = filtradas;
    const header = ['Conta', 'Valor (R$)', 'Etapa', 'Probabilidade (%)', 'Fecha em', 'Responsável'];
    const data = rows.map(o => [
      o.conta,
      o.valor,
      o.etapa,
      o.prob,
      o.fecha,
      o.dono.nome,
    ]);
    if (format === 'csv') {
      const bom = '﻿';
      const csv = bom + [header, ...data].map(r => r.map(v => `"${String(v).replace(/"/g,'""')}"`).join(',')).join('\n');
      const a = Object.assign(document.createElement('a'), { href: URL.createObjectURL(new Blob([csv], {type:'text/csv;charset=utf-8'})), download: 'oportunidades.csv' });
      a.click(); URL.revokeObjectURL(a.href);
      toast('CSV baixado ✓');
    } else if (format === 'xls') {
      const tbl = `<table><tr>${header.map(h=>`<th>${h}</th>`).join('')}</tr>${data.map(r=>`<tr>${r.map(c=>`<td>${c}</td>`).join('')}</tr>`).join('')}</table>`;
      const xls = `<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel"><head><meta charset="utf-8"/></head><body>${tbl}</body></html>`;
      const a = Object.assign(document.createElement('a'), { href: URL.createObjectURL(new Blob([xls], {type:'application/vnd.ms-excel'})), download: 'oportunidades.xls' });
      a.click(); URL.revokeObjectURL(a.href);
      toast('Excel baixado ✓');
    } else if (format === 'pdf') {
      const w = window.open('', '_blank');
      w.document.write(`<html><head><title>Oportunidades</title><style>
        body{font-family:sans-serif;padding:24px;color:#1a1a2e}
        h2{margin-bottom:4px}p{color:#666;margin:0 0 16px}
        table{border-collapse:collapse;width:100%}
        th{background:#f0f2f8;padding:8px 12px;text-align:left;font-size:12px;text-transform:uppercase;letter-spacing:.05em}
        td{padding:8px 12px;border-bottom:1px solid #eee;font-size:13px}
        .money{font-weight:700}
        @media print{@page{margin:1cm}}
      </style></head><body>
        <h2>Oportunidades em andamento</h2>
        <p>${rows.length} negócios · exportado em ${new Date().toLocaleDateString('pt-BR')}</p>
        <table><tr>${header.map(h=>`<th>${h}</th>`).join('')}</tr>
        ${data.map(r=>`<tr>${r.map((c,i)=>`<td${i===1?' class="money"':''}>${i===1?'R$ '+Number(c).toLocaleString('pt-BR'):c}</td>`).join('')}</tr>`).join('')}
        </table>
      </body></html>`);
      w.document.close();
      setTimeout(() => { w.focus(); w.print(); }, 400);
      toast('PDF abrindo para impressão ✓');
    } else if (format === 'email') {
      const subject = encodeURIComponent(`Oportunidades Ezza CRM — ${new Date().toLocaleDateString('pt-BR')}`);
      const body = encodeURIComponent(`Segue o resumo das ${rows.length} oportunidades:\n\n` +
        rows.map(o => `• ${o.conta} — R$ ${o.valor.toLocaleString('pt-BR')} (${o.etapa}, ${o.prob}%, fecha ${o.fecha})`).join('\n'));
      window.open(`mailto:leticia.andrade@ezza.com.br?subject=${subject}&body=${body}`);
      toast('Abrindo e-mail ✓');
    }
  };

  return (
    <>
      <PageHead
        title={<>Oportunidades <em>em andamento</em></>}
        subtitle={`${filtradas.length} negócios ativos · pipeline filtrado R$ ${(totalFiltrado/1000).toFixed(0)}k`}
        right={
          <div className="row">
            <div className="pill pill-yellow">Meta do trimestre 78%</div>

            <div style={{position: 'relative'}}>
              <button className={`icon-btn ${filterOpen || filtrosAtivos > 0 ? '' : ''}`} onClick={(e) => { e.stopPropagation(); setFilterOpen(o => !o); setExportOpen(false); }}>
                {ICN.filter}
                {filtrosAtivos > 0 && <span className="filter-badge">{filtrosAtivos}</span>}
              </button>
              {filterOpen && (
                <div className="op-filter-panel" onClick={(e) => e.stopPropagation()}>
                  <div className="op-filter-head">
                    <strong>Filtros</strong>
                    <div className="row" style={{gap: 6}}>
                      {filtrosAtivos > 0 && (
                        <button className="btn-ghost" style={{padding:'4px 10px', fontSize:11}} onClick={(e) => { e.stopPropagation(); setStageFilter(null); setProbMin(0); setValMin(0); setDonoFilter('Todos'); }}>Limpar</button>
                      )}
                      <button className="mini-btn" onClick={(e) => { e.stopPropagation(); setFilterOpen(false); }} title="Fechar">{ICN.x}</button>
                    </div>
                  </div>
                  <div className="op-filter-field">
                    <div className="field-lbl">Etapa</div>
                    <div className="op-filter-chips">
                      {stages.map(s => (
                        <span key={s}
                          className={`pill ${stageFilter === s ? 'pill-dark' : ''}`}
                          onClick={() => setStageFilter(stageFilter === s ? null : s)}>
                          {s}
                        </span>
                      ))}
                    </div>
                  </div>
                  <div className="op-filter-field">
                    <div className="field-lbl">Probabilidade mínima · {probMin}%</div>
                    <input type="range" min="0" max="100" step="5" value={probMin} onChange={(e) => setProbMin(+e.target.value)} className="op-range" />
                  </div>
                  <div className="op-filter-field">
                    <div className="field-lbl">Valor mínimo · R$ {(valMin/1000).toFixed(0)}k</div>
                    <input type="range" min="0" max="1300000" step="50000" value={valMin} onChange={(e) => setValMin(+e.target.value)} className="op-range" />
                  </div>
                  <div className="op-filter-field">
                    <div className="field-lbl">Responsável</div>
                    <div className="op-filter-chips">
                      {donos.map(d => (
                        <span key={d}
                          className={`pill ${donoFilter === d ? 'pill-dark' : ''}`}
                          style={{fontSize:11}}
                          onClick={() => setDonoFilter(d)}>
                          {d}
                        </span>
                      ))}
                    </div>
                  </div>
                </div>
              )}
            </div>

            <div style={{position:'relative'}}>
              <button className="icon-btn" onClick={(e) => { e.stopPropagation(); setExportOpen(o => !o); setFilterOpen(false); }}>{ICN.upload}</button>
              {exportOpen && (
                <div className="op-export-panel" onClick={(e) => e.stopPropagation()}>
                  <div className="op-filter-head">
                    <strong>Exportar</strong>
                    <div className="row" style={{gap: 8}}>
                      <span className="muted" style={{fontSize: 11, fontFamily:'var(--font-mono)'}}>{filtradas.length} registros</span>
                      <button className="mini-btn" onClick={(e) => { e.stopPropagation(); setExportOpen(false); }} title="Fechar">{ICN.x}</button>
                    </div>
                  </div>
                  <div className="op-export-list">
                    <div className="op-export-item" onClick={() => exportOps('pdf')}>
                      <div className="op-export-ic op-export-ic-pdf">PDF</div>
                      <div className="col" style={{flex:1, minWidth:0}}>
                        <div className="op-export-lbl">Relatório em PDF</div>
                        <div className="op-export-sub muted">Tabela para impressão · {filtradas.length} registros</div>
                      </div>
                      <span className="muted">{ICN.arrowRight}</span>
                    </div>
                    <div className="op-export-item" onClick={() => exportOps('csv')}>
                      <div className="op-export-ic op-export-ic-csv">CSV</div>
                      <div className="col" style={{flex:1, minWidth:0}}>
                        <div className="op-export-lbl">Dados em CSV</div>
                        <div className="op-export-sub muted">Para importar em outro CRM · {filtradas.length} linhas</div>
                      </div>
                      <span className="muted">{ICN.arrowRight}</span>
                    </div>
                    <div className="op-export-item" onClick={() => exportOps('xls')}>
                      <div className="op-export-ic op-export-ic-xls">XLS</div>
                      <div className="col" style={{flex:1, minWidth:0}}>
                        <div className="op-export-lbl">Planilha do Excel</div>
                        <div className="op-export-sub muted">{filtradas.length} oportunidades em .xls</div>
                      </div>
                      <span className="muted">{ICN.arrowRight}</span>
                    </div>
                  </div>
                  <div className="op-export-divider" />
                  <div className="op-export-item op-export-item-alt" onClick={() => exportOps('email')}>
                    <div className="op-export-ic op-export-ic-mail">{ICN.mail}</div>
                    <div className="col" style={{flex:1, minWidth:0}}>
                      <div className="op-export-lbl">Enviar por e-mail</div>
                      <div className="op-export-sub muted">leticia.andrade@ezza.com.br</div>
                    </div>
                    <span className="muted">{ICN.arrowRight}</span>
                  </div>
                </div>
              )}
            </div>

            <button className="btn-primary" onClick={() => setNovoOpen(true)}>{ICN.plus} Nova oportunidade</button>
          </div>
        }
      />

      <div className="op-stage-grid">
        {stages.map((s, i) => {
          const active = stageFilter === s;
          return (
            <div key={s}
              className={`card op-stage ${active ? 'op-stage-active' : ''}`}
              onClick={() => setStageFilter(active ? null : s)}>
              <div className="op-stage-head">
                <div className="pill" style={{background: `var(--acc-${['blue','yellow','pink','mint'][i]})`, color: 'oklch(0.22 0.05 250)'}}>{s}</div>
                <div className="muted" style={{fontSize: 11}}>{localOps.filter(o => o.etapa === s).length} negócios</div>
              </div>
              <div className="op-stage-val money">R$ {(totalsByStage[i] / 1000).toFixed(0)}k</div>
              <div className="op-stage-bar">
                <div style={{
                  width: `${(totalsByStage[i] / grandTotal * 100).toFixed(0)}%`,
                  background: `var(--acc-${['blue','yellow','pink','mint'][i]})`,
                }} />
              </div>
              {active && <div className="op-stage-mark">{ICN.check} filtro ativo</div>}
            </div>
          );
        })}
      </div>

      <div className="card" style={{marginTop: 14}}>
        <div className="card-head">
          <div className="card-title">
            {stageFilter ? `Oportunidades · ${stageFilter}` : 'Todas as Oportunidades'}
            <span className="muted" style={{fontSize: 12, fontWeight: 500, marginLeft: 8}}>({filtradas.length})</span>
          </div>
          <div className="row" style={{gap: 6}}>
            <div className="op-view-toggle">
              <button
                className={`op-view-btn ${view === 'lista' ? 'op-view-on' : ''}`}
                onClick={() => setView('lista')}
                title="Visualização em lista"
              >
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round">
                  <line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="20" y2="18"/>
                </svg>
                Lista
              </button>
              <button
                className={`op-view-btn ${view === 'kanban' ? 'op-view-on' : ''}`}
                onClick={() => setView('kanban')}
                title="Visualização Kanban"
              >
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round">
                  <rect x="3" y="3" width="5" height="18" rx="1.5"/><rect x="10" y="3" width="5" height="13" rx="1.5"/><rect x="17" y="3" width="5" height="16" rx="1.5"/>
                </svg>
                Kanban
              </button>
            </div>
            <button className="mini-btn" onClick={(e) => { e.stopPropagation(); setExportOpen(o => !o); setFilterOpen(false); }} title="Exportar">{ICN.upload}</button>
          </div>
        </div>

        {view === 'lista' ? (
          <table className="tbl op-tbl">
            <thead>
              <tr>
                <SortTh col="conta" sort={sort} setSort={setSort}>Conta</SortTh>
                <SortTh col="valor" sort={sort} setSort={setSort}>Valor</SortTh>
                <SortTh col="etapa" sort={sort} setSort={setSort}>Etapa</SortTh>
                <SortTh col="prob"  sort={sort} setSort={setSort}>Prob.</SortTh>
                <SortTh col="fecha" sort={sort} setSort={setSort}>Fecha em</SortTh>
                <th>Responsável</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {filtradas.map(o => {
                const stagePill = { Qualificado: 'pill-blue', Proposta: 'pill-yellow', Negociação: 'pill-pink', Fechado: 'pill-mint' }[o.etapa];
                return (
                  <tr key={o.id}>
                    <td><strong>{o.conta}</strong></td>
                    <td className="money" style={{fontWeight:600}}>R$ {o.valor.toLocaleString('pt-BR')}</td>
                    <td><span className={`pill ${stagePill}`}>{o.etapa}</span></td>
                    <td>
                      <div className="row" style={{gap: 8}}>
                        <div style={{width: 60, height: 6, borderRadius: 99, background: 'oklch(0.94 0.01 250)', overflow:'hidden'}}>
                          <div style={{width: `${o.prob}%`, height: '100%', background: 'var(--acc-blue)'}} />
                        </div>
                        <span style={{fontSize: 12, fontWeight: 600}}>{o.prob}%</span>
                      </div>
                    </td>
                    <td>{o.fecha}</td>
                    <td>
                      <div className="row" title={`Ver contato: ${o.dono.nome.split(' ')[0]}`}
                        onClick={() => onOpenContact && onOpenContact(o.dono.id)}
                        style={{cursor: onOpenContact ? 'pointer' : 'default'}}>
                        <img src={o.dono.avatar} style={{width: 26, height: 26, borderRadius: '50%', transition:'transform .12s'}}
                          onMouseEnter={e => { if(onOpenContact) e.currentTarget.style.transform='scale(1.15)'; }}
                          onMouseLeave={e => e.currentTarget.style.transform=''}
                          alt="" />
                        <span style={{fontSize: 12.5}}>{o.dono.nome.split(' ').slice(0,2).join(' ')}</span>
                      </div>
                    </td>
                    <td>
                      <MoreMenu placement="bottom" align="right" items={[
                        {
                          ic: ICN.check,
                          label: o.etapa === 'Fechado' ? 'Já fechada' : 'Marcar como ganha',
                          onClick: () => { setLocalOps(prev => prev.map(x => x.id===o.id ? {...x, etapa:'Fechado'} : x)); toast(`"${o.conta}" marcada como ganha ✓`); },
                        },
                        {
                          ic: ICN.x,
                          label: 'Marcar como perdida',
                          danger: true,
                          onClick: () => { setLocalOps(prev => prev.filter(x => x.id !== o.id)); toast(`"${o.conta}" marcada como perdida`); },
                        },
                        {
                          ic: ICN.arrowRight,
                          label: 'Avançar etapa',
                          onClick: () => { const idx = stages.indexOf(o.etapa); const next = stages[Math.min(idx+1, stages.length-1)]; setLocalOps(prev => prev.map(x => x.id===o.id ? {...x, etapa:next} : x)); toast(`Etapa → "${next}"`); },
                        },
                        { divider: true },
                        { ic: ICN.edit,  label: 'Editar negócio',       onClick: () => setEditFor(o) },
                        { ic: ICN.users, label: 'Atribuir a alguém',    onClick: () => setAtribuirFor(o) },
                        { ic: ICN.cal,   label: 'Reagendar fechamento', onClick: () => setReagendarFor(o) },
                        { ic: ICN.share, label: 'Compartilhar link',    onClick: () => { navigator.clipboard?.writeText(`https://app.ezza.com.br/oportunidades/${o.id}`).catch(()=>{}); toast('Link copiado ✓'); } },
                        { divider: true },
                        {
                          ic: ICN.trash,
                          label: 'Excluir negócio',
                          danger: true,
                          onClick: () => { setLocalOps(prev => prev.filter(x => x.id !== o.id)); toast(`"${o.conta}" excluída`); },
                        },
                      ]} />
                    </td>
                  </tr>
                );
              })}
              {filtradas.length === 0 && (
                <tr><td colSpan="7" style={{padding: '32px', textAlign: 'center'}} className="muted">Nenhuma oportunidade bate com os filtros.</td></tr>
              )}
            </tbody>
          </table>
        ) : (
          <div className="op-kanban">
            {stages.map((s, i) => {
              const cards = filtradas.filter(o => o.etapa === s);
              const colColor = ['blue','yellow','pink','mint'][i];
              return (
                <div key={s} className={`op-kan-col op-kan-col-${colColor}`}>
                  <div className="op-kan-head">
                    <span className="op-kan-label">{s}</span>
                    <span className="op-kan-count">{cards.length}</span>
                  </div>
                  <div className="muted" style={{fontSize: 11, fontFamily:'var(--font-mono)', marginBottom: 10}}>R$ {(cards.reduce((s,o) => s+o.valor, 0)/1000).toFixed(0)}k</div>
                  <div className="col" style={{gap: 8}}>
                    {cards.map(o => (
                      <div key={o.id} className="op-kan-card">
                        <div style={{fontSize: 13, fontWeight: 600, letterSpacing: '-0.005em'}}>{o.conta}</div>
                        <div className="money" style={{fontSize: 16, fontWeight: 700, letterSpacing:'-0.015em', marginTop: 4}}>R$ {o.valor.toLocaleString('pt-BR')}</div>
                        <div className="row" style={{justifyContent:'space-between', alignItems:'center', marginTop: 10}}>
                          <span className="muted" style={{fontSize: 10.5, fontWeight: 600}}>{o.prob}% · fecha {o.fecha}</span>
                          <img src={o.dono.avatar} style={{width: 22, height: 22, borderRadius:'50%'}} alt="" />
                        </div>
                      </div>
                    ))}
                    {cards.length === 0 && <div style={{fontSize: 11, padding: '24px 8px', textAlign:'center', color:'var(--ink-faint)'}}>Vazio</div>}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      {novoOpen && (
        <OportunidadeModal
          stages={stages}
          onClose={() => setNovoOpen(false)}
          onCreate={(nova) => setLocalOps(prev => [{ ...nova, id: Date.now() }, ...prev])}
        />
      )}

      {editFor && (
        <OportunidadeModal
          stages={stages}
          initialData={editFor}
          onClose={() => setEditFor(null)}
          onUpdate={(dados) => {
            setLocalOps(prev => prev.map(x => x.id === editFor.id ? { ...x, ...dados } : x));
            setEditFor(null);
          }}
        />
      )}

      {atribuirFor && (
        <AtribuirOpModal
          op={atribuirFor}
          onClose={() => setAtribuirFor(null)}
          onAtribuir={(c) => {
            setLocalOps(prev => prev.map(x => x.id === atribuirFor.id ? { ...x, dono: c } : x));
            setAtribuirFor(null);
          }}
        />
      )}

      {reagendarFor && (
        <ReagendarModal
          op={reagendarFor}
          onClose={() => setReagendarFor(null)}
          onSave={(data) => {
            setLocalOps(prev => prev.map(x => x.id === reagendarFor.id ? { ...x, fecha: data } : x));
            setReagendarFor(null);
          }}
        />
      )}

      <style>{`
        .op-stage-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
        .op-stage { padding: 16px 18px !important; cursor: default; transition: transform .15s, box-shadow .15s; position: relative; }
        .op-stage:hover { transform: translateY(-2px); }
        .op-stage-active { box-shadow: 0 0 0 2px var(--ink) inset, var(--card-shadow); }
        .op-stage-mark { font-size: 10px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink); margin-top: 8px; display: flex; align-items: center; gap: 4px; }
        .op-stage-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
        .op-stage-val { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }
        .op-stage-bar { margin-top: 10px; height: 6px; background: oklch(0.94 0.01 250); border-radius: 99px; overflow: hidden; }
        .op-stage-bar > div { height: 100%; border-radius: 99px; }
        .op-tbl td { padding: 14px 12px; }

        .filter-badge { position: absolute; top: 4px; right: 4px; min-width: 14px; height: 14px; padding: 0 3px; border-radius: 7px; background: var(--danger); color: white; font-size: 9px; font-weight: 700; display: grid; place-items: center; border: 1.5px solid white; }

        .op-filter-panel {
          position: absolute; top: calc(100% + 8px); right: 0;
          width: 320px;
          background: white;
          border: 0.5px solid oklch(0.92 0.01 250);
          border-radius: 16px;
          box-shadow: 0 16px 40px -12px rgba(20,30,60,.22);
          padding: 16px;
          z-index: 60;
          animation: fadein .15s ease;
        }
        .op-filter-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; padding-bottom: 10px; border-bottom: 1px solid oklch(0.93 0.01 255); }
        .op-filter-head strong { font-size: 14px; }
        .op-filter-field { margin-bottom: 14px; }
        .op-filter-field:last-child { margin-bottom: 0; }
        .op-filter-field .field-lbl { margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.08em; font-size: 10.5px; font-weight: 700; color: var(--ink-muted); }
        .op-filter-chips { display: flex; flex-wrap: wrap; gap: 6px; }
        .op-filter-chips .pill { cursor: default; }
        .op-range {
          width: 100%;
          -webkit-appearance: none; appearance: none;
          height: 6px; border-radius: 99px;
          background: oklch(0.93 0.01 250);
          outline: none;
        }
        .op-range::-webkit-slider-thumb {
          -webkit-appearance: none; appearance: none;
          width: 16px; height: 16px; border-radius: 50%;
          background: var(--ink);
          border: 2px solid white; box-shadow: 0 1px 4px rgba(0,0,0,.18);
          cursor: default;
        }
        .op-range::-moz-range-thumb {
          width: 16px; height: 16px; border-radius: 50%;
          background: var(--ink); border: 2px solid white;
          cursor: default;
        }

        .op-export-panel {
          position: absolute; top: calc(100% + 8px); right: 0;
          width: 340px;
          background: white;
          border: 0.5px solid oklch(0.92 0.01 250);
          border-radius: 16px;
          box-shadow: 0 16px 40px -12px rgba(20,30,60,.22);
          padding: 16px;
          z-index: 60;
          animation: fadein .15s ease;
        }
        .op-export-list { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
        .op-export-item {
          display: flex; align-items: center; gap: 12px;
          padding: 10px 10px;
          border-radius: 12px;
          cursor: default;
        }
        .op-export-item:hover { background: oklch(0.96 0.012 250); }
        .op-export-ic {
          width: 38px; height: 38px;
          border-radius: 10px;
          display: grid; place-items: center;
          font-size: 10px; font-weight: 800;
          letter-spacing: 0.04em;
          flex-shrink: 0;
        }
        .op-export-ic-pdf { background: oklch(0.93 0.07 18); color: oklch(0.42 0.16 18); }
        .op-export-ic-csv { background: oklch(0.93 0.07 160); color: oklch(0.40 0.14 160); }
        .op-export-ic-xls { background: oklch(0.94 0.10 95); color: oklch(0.40 0.13 80); }
        .op-export-ic-mail { background: oklch(0.93 0.06 250); color: oklch(0.40 0.16 250); font-size: 14px; }
        .op-export-lbl { font-size: 13px; font-weight: 600; }
        .op-export-sub { font-size: 11.5px; margin-top: 2px; line-height: 1.3; }
        .op-export-divider { height: 1px; background: oklch(0.93 0.01 255); margin: 8px 0; }

        .op-view-toggle {
          display: inline-flex;
          gap: 2px;
          background: oklch(0.94 0.01 250);
          border-radius: 12px;
          padding: 3px;
        }
        .op-view-btn {
          display: inline-flex; align-items: center; gap: 6px;
          padding: 5px 12px;
          border-radius: 10px;
          border: none;
          background: transparent;
          font-family: inherit;
          font-size: 12.5px;
          font-weight: 600;
          color: var(--ink-muted);
          cursor: default;
          transition: background .12s, color .12s;
        }
        .op-view-btn:hover { color: var(--ink); }
        .op-view-on {
          background: white;
          color: var(--ink);
          box-shadow: 0 1px 3px rgba(20,30,60,.10), 0 1px 0 rgba(255,255,255,.8) inset;
        }

        .sort-th { cursor: default; user-select: none; }
        .sort-th:hover { color: var(--ink) !important; }
        .sort-arrow { display: inline-flex; vertical-align: -2px; margin-left: 4px; opacity: 0.5; }
        .sort-arrow.sort-active { opacity: 1; color: var(--ink); }

        .op-kanban { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; padding-top: 4px; }
        .op-kan-col { border-radius: var(--radius-md); padding: 14px 12px; min-height: 320px; }
        .op-kan-col-blue   { background: linear-gradient(180deg, oklch(0.96 0.04 245) 0%, oklch(1 0 0 / 0.4) 100%); }
        .op-kan-col-yellow { background: linear-gradient(180deg, oklch(0.97 0.06 95) 0%, oklch(1 0 0 / 0.4) 100%); }
        .op-kan-col-pink   { background: linear-gradient(180deg, oklch(0.96 0.04 18) 0%, oklch(1 0 0 / 0.4) 100%); }
        .op-kan-col-mint   { background: linear-gradient(180deg, oklch(0.96 0.05 160) 0%, oklch(1 0 0 / 0.4) 100%); }
        .op-kan-head { display: flex; justify-content: space-between; align-items: center; }
        .op-kan-label { font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-soft); }
        .op-kan-count { font-size: 11px; font-weight: 700; min-width: 22px; height: 22px; border-radius: 50%; background: white; color: var(--ink); display: grid; place-items: center; box-shadow: 0 1px 2px rgba(20,30,60,.08); }
        .op-kan-card {
          background: white;
          border-radius: 12px;
          padding: 10px 12px;
          box-shadow: 0 1px 2px rgba(20,30,60,.04);
          cursor: default;
          transition: transform .12s, box-shadow .12s;
        }
        .op-kan-card:hover { transform: translateY(-1px); box-shadow: 0 8px 18px -12px rgba(20,30,60,.2); }
      `}</style>
    </>
  );
}

function SortTh({ col, sort, setSort, children }) {
  const active = sort.col === col;
  return (
    <th className="sort-th" onClick={() => setSort({ col, dir: active && sort.dir === 'asc' ? 'desc' : (active && sort.dir === 'desc' ? 'asc' : 'desc') })}>
      {children}
      <span className={`sort-arrow ${active ? 'sort-active' : ''}`}>
        {active && sort.dir === 'asc' ? ICN.arrowUp : <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m6 9 6 6 6-6"/></svg>}
      </span>
    </th>
  );
}

function Field({ label, full, children }) {
  return (
    <div className={`field ${full ? 'field-full' : ''}`}>
      <div className="field-lbl">{label}</div>
      {children}
    </div>
  );
}
function SelectMockOp({ value, muted }) {
  return (
    <div className="ezz-input ezz-select">
      <span style={{color: muted ? 'var(--ink-faint)' : 'var(--ink)', fontSize: 13, fontWeight: muted ? 400 : 600}}>{value}</span>
      <span className="muted">{ICN.chevron}</span>
    </div>
  );
}

window.Oportunidades = Oportunidades;
