// ═══════════════════════════════════════════════════════
// BAUKO CRM — Pipeline Kanban Screen
// ═══════════════════════════════════════════════════════
/* global React, CRM_DATA, Badge, fR, fDate */
const { useState: usePipeState, useEffect: usePipeEffect } = React;

const ETAPAS = [
  { id: "lead",               label: "Lead",               color: "var(--tx-3)",    bg: "var(--surface-2)" },
  { id: "qualificacao",       label: "Qualificação",        color: "var(--info)",    bg: "var(--info-050)"  },
  { id: "proposta",           label: "Proposta enviada",    color: "#8a5a00",        bg: "var(--warn-050)"  },
  { id: "pedido",             label: "Pedido",              color: "var(--grn-600)", bg: "var(--grn-050)"   },
  { id: "credito",            label: "Crédito",             color: "#5a3f8a",        bg: "#f0eaff"          },
  { id: "fechamento_parcial", label: "Fech. Parcial",       color: "#8a5a00",        bg: "var(--warn-050)"  },
  { id: "fechado",            label: "Fechado",             color: "var(--ok)",      bg: "var(--ok-050)"    },
];
// Compat: ops antigas mapeiam para colunas equivalentes
const ETAPA_COMPAT = { negociacao: "proposta", fechado_ganho: "fechado", fechado_perdido: "fechamento_parcial" };
// Retorna o melhor valor disponível para a op no kanban:
// op.valor quando > 0; senão, o maior valor dentre suas propostas.
function getValorCard(op) {
  if (op.valor > 0) return op.valor;
  var _props = (window.CRM_DATA && CRM_DATA.propostas) || [];
  return _props.filter(function(p){ return p.op_id === op.id; })
               .reduce(function(mx, p){ return Math.max(mx, p.valor || 0); }, 0);
}

function PipelineCard({ op, onOpen }) {
  const cli = CRM_DATA.getCliente(op.cliente_id);
  const vend = CRM_DATA.getUsuario(op.vendedor_id);
  const priorColor = { alta: "var(--danger)", media: "var(--warn)", baixa: "var(--tx-3)" }[op.prioridade];
  const cancelada = !!op.cancelada_em;

  return (
    <div className="pipe-card" onClick={() => onOpen(op.id)}
      title={cancelada && op.motivo_cancelamento ? 'Cancelada · ' + op.motivo_cancelamento : ''}
      style={cancelada ? { opacity: 0.55, borderLeft: '3px solid var(--danger)' } : {}}>
      <div className="pipe-card__header">
        <span className="mono tx3" style={{ fontSize: 10 }}>{op.id}{cancelada && ' · ⊘'}</span>
        <span style={{ width: 8, height: 8, borderRadius: "50%", background: priorColor, flexShrink: 0, marginTop: 1 }} title={"Prioridade " + op.prioridade}></span>
      </div>
      <div className="pipe-card__title">{op.titulo}</div>
      <div className="pipe-card__client">{cli?.razao?.split(" ").slice(0, 3).join(" ")}</div>
      <div className="pipe-card__footer">
        <span className="pipe-card__value">{fR(getValorCard(op))}</span>
        <div style={{ display: "flex", alignItems: "center", gap: 4 }}>
          <div style={{
            width: 20, height: 20, borderRadius: "50%",
            background: vend?.avatar_color,
            display: "flex", alignItems: "center", justifyContent: "center",
            font: "600 8px/1 var(--ff-body)", color: "#fff",
          }}>{vend?.iniciais}</div>
        </div>
      </div>
      {/* Prob bar */}
      <div style={{ marginTop: 8, height: 3, background: "var(--border)", borderRadius: 2, overflow: "hidden" }}>
        <div style={{
          height: "100%", borderRadius: 2,
          background: op.probabilidade >= 70 ? "var(--ok)" : op.probabilidade >= 40 ? "var(--warn)" : "var(--tx-3)",
          width: op.probabilidade + "%",
          transition: "width .3s"
        }}></div>
      </div>
      <div style={{ marginTop: 4, font: "400 10px/1 var(--ff-mono)", color: "var(--tx-3)", display: "flex", justifyContent: "space-between" }}>
        <span>Prob. {op.probabilidade}%</span>
        <span>{fDate(op.previsao_fechamento)}</span>
      </div>
    </div>
  );
}

function Pipeline({ onOpenOp, onNav, extraOps }) {
  const [ops, setOps] = usePipeState(CRM_DATA.oportunidades);

  // Sincroniza estado local sempre que extraOps mudar
  usePipeEffect(() => {
    if (extraOps && extraOps.length > 0) {
      // Exclui de CRM_DATA os ids que já estão em extraOps (evita duplicata durante confirmação SP)
      var extraIds = new Set(extraOps.map(function(o){ return o.id; }));
      var base = CRM_DATA.oportunidades.filter(function(o){ return !extraIds.has(o.id); });
      setOps(base.concat(extraOps));
    } else {
      // extraOps esvaziou (SP confirmou e op migrou para CRM_DATA) — re-sincroniza com CRM_DATA
      setOps(CRM_DATA.oportunidades.slice());
    }
  }, [extraOps]);
  const [dragId, setDragId] = usePipeState(null);
  const [dragOver, setDragOver] = usePipeState(null);
  const [filter, setFilter] = usePipeState("todos");
  const [showCanceladas, setShowCanceladas] = usePipeState(false);
  const [viewMode,       setViewMode]       = usePipeState(function() {
    // No celular (< 600px) começa em lista — kanban é inutilizável em tela pequena
    return (typeof window !== 'undefined' && window.innerWidth < 600) ? 'lista' : 'kanban';
  }); // 'kanban' | 'lista'

  const vendedores = CRM_DATA.usuarios;

  // ── Visibilidade por papel (CRM_USER) ────────────────────────
  // Comercial (vendedor) só vê as próprias oportunidades.
  // BDR/Admin/Gerente veem todas (com filtro opcional via dropdown).
  const podeVerTodos = !!(window.CRM_USER && window.CRM_USER.podeVerOpAlheia);
  const meuUserId    = (window.CRM_USER && window.CRM_USER.userId) || null;
  const opsAutorizadas = podeVerTodos
    ? ops
    : ops.filter(o => o.vendedor_id === meuUserId);

  // Esconde canceladas por default — toggle revela
  const opsVisiveis = showCanceladas ? opsAutorizadas : opsAutorizadas.filter(o => !o.cancelada_em);
  // Para comercial: dropdown não aparece → filter sempre "todos" (= todas as autorizadas dele)
  const filtered = (!podeVerTodos || filter === "todos")
    ? opsVisiveis
    : opsVisiveis.filter(o => o.vendedor_id === filter);
  const nCanceladas = opsAutorizadas.filter(o => !!o.cancelada_em).length;

  function handleDragStart(e, id) {
    setDragId(id);
    e.dataTransfer.effectAllowed = "move";
  }
  function handleDragOver(e, etapa) {
    e.preventDefault();
    setDragOver(etapa);
  }
  const isGerente = !!(window.CRM_USER && window.CRM_USER.isGerente);
  const ETAPAS_FECHADAS_SET = new Set(['fechamento_parcial', 'fechado']);

  function handleDrop(e, etapa) {
    e.preventDefault();
    if (dragId) {
      const op = ops.find(o => o.id === dragId);
      // Lock: oportunidades fechadas só gerentes podem reabrir
      if (op && ETAPAS_FECHADAS_SET.has(op.etapa) && !ETAPAS_FECHADAS_SET.has(etapa) && !isGerente) {
        window.CRM_TOAST('Esta oportunidade está fechada. Apenas gerentes podem reabri-la.', 'warn');
        setDragId(null); setDragOver(null); return;
      }
      // Guard: apenas o dono ou gerente pode mover o card
      if (op && op.vendedor_id !== meuUserId && !isGerente) {
        window.CRM_TOAST('Você não pode mover oportunidades de outros vendedores.', 'warn');
        setDragId(null); setDragOver(null); return;
      }
      // J-D1: não permite drag retrocedendo de credito/fechamento se há pedido assinado
      if (op) {
        const ETAPAS_ORDER = ['lead','qualificacao','proposta','pedido','credito','fechamento_parcial','fechado'];
        const novaIdx = ETAPAS_ORDER.indexOf(etapa);
        const credIdx = ETAPAS_ORDER.indexOf('credito');
        const propsDaOp = (CRM_DATA.propostas || []).filter(p => p.op_id === op.id);
        const temPedAssinado = propsDaOp.some(p => p.status === 'pedido_assinado');
        if (temPedAssinado && novaIdx >= 0 && novaIdx < credIdx) {
          window.CRM_TOAST('Existe um pedido assinado nesta oportunidade. Para corrigir, cancele o pedido dentro da proposta e reemita.', 'warn');
          setDragId(null); setDragOver(null); return;
        }
      }
      const etapaAnterior = op?.etapa;
      setOps(prev => prev.map(o => o.id === dragId ? { ...o, etapa } : o));
      // Persiste mudança de etapa no SP — rollback visual se falhar
      if (op?._spId && typeof CRM_API !== 'undefined') {
        CRM_API.updateItem('Oportunidades', op._spId, { etapa }).catch(e => {
          console.warn('[CRM] etapa update:', e.message);
          window.CRM_TOAST('Falha ao salvar nova etapa. Revertendo...', 'error');
          setOps(prev => prev.map(o => o.id === dragId ? { ...o, etapa: etapaAnterior } : o));
          const _ri = CRM_DATA.oportunidades.findIndex(o => o.id === dragId);
          if (_ri >= 0) CRM_DATA.oportunidades[_ri] = { ...CRM_DATA.oportunidades[_ri], etapa: etapaAnterior };
        });
      }
      // Atualiza CRM_DATA.oportunidades in-place para que navegação interna não reverta
      const idx = CRM_DATA.oportunidades.findIndex(o => o.id === dragId);
      if (idx >= 0) CRM_DATA.oportunidades[idx] = { ...CRM_DATA.oportunidades[idx], etapa };
    }
    setDragId(null);
    setDragOver(null);
  }
  function handleDragEnd() {
    setDragId(null);
    setDragOver(null);
  }

  const ETAPAS_FECHADAS = new Set(["fechamento_parcial","fechado"]);
  const totalPipe = filtered.filter(o => !ETAPAS_FECHADAS.has(o.etapa)).reduce((s,o) => s + getValorCard(o), 0);

  return (
    <div data-screen-label="02 Pipeline">
      {/* Toolbar */}
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 18, flexWrap: "wrap" }}>
        {/* Dropdown de vendedor — só para quem pode ver oportunidades alheias */}
        {podeVerTodos && (
          <select value={filter} onChange={function(e){ setFilter(e.target.value); }}
                  style={{ padding: "7px 10px", border: "1px solid var(--border)", borderRadius: "var(--r-sm)",
                           background: "var(--surface)", fontFamily: "var(--ff-body)", fontSize: 13,
                           color: "var(--tx)", cursor: "pointer", minWidth: 160 }}>
            <option value="todos">Todos os vendedores</option>
            {vendedores.map(function(v) { return <option key={v.id} value={v.id}>{v.nome}</option>; })}
          </select>
        )}

        <div style={{ marginLeft: "auto", display: "flex", gap: 8, alignItems: "center" }}>
          <span style={{ font: "400 12px/1 var(--ff-mono)", color: "var(--tx-3)" }}>Pipeline ativo: <strong style={{ color: "var(--grn)" }}>{fR(totalPipe)}</strong></span>
          {nCanceladas > 0 && (
            <label style={{ display: "flex", alignItems: "center", gap: 6, font: "400 11px/1 var(--ff-body)", color: "var(--tx-3)", cursor: "pointer", padding: "6px 10px", border: "1px solid var(--border)", borderRadius: "var(--r-sm)", background: showCanceladas ? "var(--surface-2)" : "var(--surface)" }}>
              <input type="checkbox" checked={showCanceladas} onChange={function(e){ setShowCanceladas(e.target.checked); }}
                style={{ accentColor: "var(--warn)", margin: 0 }} />
              Mostrar canceladas ({nCanceladas})
            </label>
          )}
          {/* Toggle kanban / lista — oculto no mobile */}
          <div className="mob-hide" style={{ display: "flex", gap: 2, background: "var(--surface-2)", borderRadius: "var(--r-sm)", padding: 2 }}>
            {[{ id: "kanban", icon: "layout-dashboard", title: "Kanban" }, { id: "lista", icon: "list", title: "Lista" }].map(function(m) {
              var ativo = viewMode === m.id;
              return (
                <button key={m.id} onClick={function(){ setViewMode(m.id); }} title={m.title}
                        style={{ padding: "5px 8px", borderRadius: 4, border: "none", cursor: "pointer",
                                 background: ativo ? "var(--surface)" : "transparent",
                                 boxShadow: ativo ? "0 1px 3px rgba(0,0,0,0.1)" : "none",
                                 color: ativo ? "var(--tx)" : "var(--tx-3)" }}>
                  <i data-lucide={m.icon} style={{ width: 14, height: 14, display: "block" }}></i>
                </button>
              );
            })}
          </div>
          <button className="btn btn-primary mob-hide" onClick={onOpenOp}>
            <i data-lucide="plus"></i> Nova oportunidade
          </button>
        </div>
      </div>

      {/* Modo lista */}
      {viewMode === 'lista' && (
        <div>
          {/* ── Tabela (desktop) ── */}
          <div className="dt-wrap mob-hide">
            <table className="dt">
              <thead>
                <tr>
                  <th>Oportunidade</th>
                  <th>Cliente</th>
                  <th>Etapa</th>
                  <th style={{ textAlign: 'right' }}>Valor</th>
                  <th style={{ textAlign: 'right' }}>Prob.</th>
                  <th>Previsão</th>
                  <th>Vendedor</th>
                  <th>Prior.</th>
                </tr>
              </thead>
              <tbody>
                {filtered.map(function(op) {
                  var cli  = CRM_DATA.getCliente(op.cliente_id);
                  var vend = CRM_DATA.getUsuario(op.vendedor_id);
                  var etapaId  = ETAPA_COMPAT[op.etapa] || op.etapa;
                  var etapaObj = ETAPAS.find(function(et) { return et.id === etapaId; });
                  var priorColor = { alta: 'var(--danger)', media: 'var(--warn)', baixa: 'var(--tx-3)' }[op.prioridade] || 'var(--tx-3)';
                  var cancelada  = !!op.cancelada_em;
                  return (
                    <tr key={op.id}
                        onClick={function(){ onNav('oportunidade', op.id); }}
                        style={Object.assign({ cursor: 'pointer' }, cancelada ? { opacity: 0.55 } : {})}>
                      <td>
                        <div style={{ font: '500 13px/1.2 var(--ff-body)', color: 'var(--tx)' }}>{op.titulo}</div>
                        <div style={{ font: '400 10px/1 var(--ff-mono)', color: 'var(--tx-3)', marginTop: 2 }}>{op.id}{cancelada && ' · ⊘'}</div>
                      </td>
                      <td style={{ font: '400 12px/1.3 var(--ff-body)', color: 'var(--tx-2)' }}>
                        {cli ? cli.razao.split(' ').slice(0, 3).join(' ') : '—'}
                      </td>
                      <td>
                        {etapaObj && (
                          <span style={{ padding: '2px 8px', borderRadius: 99, fontSize: 11, whiteSpace: 'nowrap',
                                         background: etapaObj.bg, color: etapaObj.color,
                                         fontFamily: 'var(--ff-body)', fontWeight: 600 }}>
                            {etapaObj.label}
                          </span>
                        )}
                      </td>
                      <td className="num">{fR(getValorCard(op))}</td>
                      <td style={{ textAlign: 'right', font: '400 12px/1 var(--ff-mono)',
                                   color: op.probabilidade >= 70 ? 'var(--ok)' : op.probabilidade >= 40 ? 'var(--warn)' : 'var(--tx-3)' }}>
                        {op.probabilidade}%
                      </td>
                      <td style={{ font: '400 11px/1 var(--ff-mono)', color: 'var(--tx-3)' }}>{fDate(op.previsao_fechamento)}</td>
                      <td>
                        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                          <div style={{ width: 20, height: 20, borderRadius: '50%', background: vend ? vend.avatar_color : 'var(--tx-3)',
                                       display: 'flex', alignItems: 'center', justifyContent: 'center',
                                       font: '600 8px/1 var(--ff-body)', color: '#fff', flexShrink: 0 }}>
                            {vend ? vend.iniciais : '?'}
                          </div>
                          <span style={{ font: '400 12px/1 var(--ff-body)', color: 'var(--tx-2)' }}>
                            {vend ? vend.nome.split(' ')[0] : '—'}
                          </span>
                        </div>
                      </td>
                      <td>
                        <span style={{ display: 'inline-block', width: 8, height: 8, borderRadius: '50%', background: priorColor }}
                              title={'Prioridade ' + op.prioridade}></span>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>

          {/* ── Cards verticais (mobile) ── */}
          <div className="mob-only">
          <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
            {filtered.map(function(op) {
              var cli      = CRM_DATA.getCliente(op.cliente_id);
              var vend     = CRM_DATA.getUsuario(op.vendedor_id);
              var etapaId  = ETAPA_COMPAT[op.etapa] || op.etapa;
              var etapaObj = ETAPAS.find(function(et) { return et.id === etapaId; });
              var cancelada = !!op.cancelada_em;
              return (
                <div key={op.id}
                     onClick={function(){ onNav('oportunidade', op.id); }}
                     style={{ background:'var(--surface)', border:'1px solid var(--border)',
                              borderRadius:'var(--r-md)', padding:'14px', cursor:'pointer',
                              opacity: cancelada ? 0.55 : 1 }}>
                  {/* Linha 1: etapa + valor */}
                  <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:8 }}>
                    {etapaObj
                      ? <span style={{ padding:'3px 10px', borderRadius:99, fontSize:11, fontWeight:600,
                                       background:etapaObj.bg, color:etapaObj.color, fontFamily:'var(--ff-body)' }}>
                          {etapaObj.label}
                        </span>
                      : <span/>}
                    <span style={{ font:'400 18px/1 var(--ff-display)', color:'var(--grn)', letterSpacing:'.02em' }}>
                      {fR(getValorCard(op))}
                    </span>
                  </div>
                  {/* Linha 2: título */}
                  <div style={{ font:'500 14px/1.3 var(--ff-body)', color:'var(--tx)', marginBottom:4 }}>
                    {op.titulo}{cancelada && <span style={{ color:'var(--tx-3)', fontWeight:400 }}> · ⊘</span>}
                  </div>
                  {/* Linha 3: cliente */}
                  <div style={{ font:'400 12px/1.3 var(--ff-body)', color:'var(--tx-2)', marginBottom:10 }}>
                    {cli ? cli.razao.split(' ').slice(0,4).join(' ') : '—'}
                  </div>
                  {/* Linha 4: vendedor + previsão + prob */}
                  <div style={{ display:'flex', alignItems:'center', gap:8 }}>
                    {vend && (
                      <div style={{ width:22, height:22, borderRadius:'50%', background:vend.avatar_color,
                                    display:'flex', alignItems:'center', justifyContent:'center',
                                    font:'600 8px/1 var(--ff-body)', color:'#fff', flexShrink:0 }}>
                        {vend.iniciais}
                      </div>
                    )}
                    <span style={{ font:'400 11px/1 var(--ff-body)', color:'var(--tx-3)', flex:1 }}>
                      {vend ? vend.nome.split(' ')[0] : '—'}
                    </span>
                    {op.previsao_fechamento && (
                      <span style={{ font:'400 11px/1 var(--ff-mono)', color:'var(--tx-3)' }}>
                        {fDate(op.previsao_fechamento)}
                      </span>
                    )}
                    <span style={{ font:'500 11px/1 var(--ff-mono)',
                                   color: op.probabilidade >= 70 ? 'var(--ok)' : op.probabilidade >= 40 ? 'var(--warn)' : 'var(--tx-3)' }}>
                      {op.probabilidade}%
                    </span>
                  </div>
                </div>
              );
            })}
            {filtered.length === 0 && (
              <div style={{ textAlign:'center', color:'var(--tx-3)', padding:'40px 0',
                            font:'400 13px/1.5 var(--ff-body)' }}>
                Nenhuma oportunidade encontrada.
              </div>
            )}
          </div>
          </div>{/* /mob-only */}
        </div>
      )}

      {/* Kanban board */}
      {viewMode === 'kanban' && <div className="kanban-board">
        {ETAPAS.map(etapa => {
          const cards = filtered.filter(o => (ETAPA_COMPAT[o.etapa] || o.etapa) === etapa.id);
          const total = cards.reduce((s, o) => s + getValorCard(o), 0);
          const isDragTarget = dragOver === etapa.id;
          return (
            <div
              key={etapa.id}
              className={"kanban-col " + (isDragTarget ? "kanban-col--over" : "")}
              onDragOver={e => handleDragOver(e, etapa.id)}
              onDrop={e => handleDrop(e, etapa.id)}
            >
              {/* Column header */}
              <div className="kanban-col__hd">
                <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                  <span className="kanban-col__label" style={{ color: etapa.color, background: etapa.bg }}>{etapa.label}</span>
                  <span className="kanban-col__count">{cards.length}</span>
                </div>
                {total > 0 && (
                  <span style={{ font: "400 11px/1 var(--ff-mono)", color: "var(--tx-3)" }}>{fR(total)}</span>
                )}
              </div>

              {/* Cards */}
              <div className="kanban-col__body">
                {cards.map(op => {
                  const isCancelada = !!op.cancelada_em;
                  const bloqueado = isCancelada || (ETAPAS_FECHADAS_SET.has(op.etapa) && !isGerente);
                  return (
                  <div
                    key={op.id}
                    draggable={!bloqueado}
                    onDragStart={e => !bloqueado ? handleDragStart(e, op.id) : e.preventDefault()}
                    onDragEnd={handleDragEnd}
                    style={{ opacity: dragId === op.id ? 0.5 : 1, cursor: bloqueado ? "default" : "grab" }}
                  >
                    <PipelineCard op={op} onOpen={id => onNav("oportunidade", id)} />
                  </div>
                  );
                })}
                {cards.length === 0 && (
                  <div style={{ padding: "24px 0", textAlign: "center", color: "var(--tx-3)", font: "400 12px/1.4 var(--ff-body)" }}>
                    <i data-lucide="inbox" style={{ width: 20, height: 20, marginBottom: 6, display: "block", margin: "0 auto 8px" }}></i>
                    Sem oportunidades
                  </div>
                )}
              </div>
            </div>
          );
        })}
      </div>}

    </div>
  );
}

window.Pipeline = Pipeline;
