// Adapter: status DB → UI
const REC_STATUS_DB_TO_UI = {
  pendente: 'Pendente', aprovado: 'Aprovado', recusado: 'Recusado',
};
const toUiReceiving = (row) => ({
  id: row.id,
  code: row.code,
  status: REC_STATUS_DB_TO_UI[row.status] || 'Pendente',
  status_db: row.status,
  divergence_count: row.divergence_count || 0,
  notes: row.notes,
  at: row.received_at ? new Date(row.received_at).toLocaleString('pt-BR', { dateStyle: 'short', timeStyle: 'short' }) : '—',
  approved_at: row.approved_at,
  order: row.order?.code || '—',
  order_id: row.order?.id,
  supplier: row.order?.supplier?.name || '—',
  itemsCount: row._itemsCount || 0,
});

function ScreenStock({ setRoute }) {
  const { CATEGORIES, BRL } = window.SCP;
  const [products, setProducts] = useState([]);
  const [receivings, setReceivings] = useState([]);
  const [loading, setLoading] = useState(true);
  const [loadErr, setLoadErr] = useState(null);
  const [showNewRec, setShowNewRec] = useState(false);
  const [activeRec, setActiveRec] = useState(null);          // recebimento "Conferência em andamento"
  const [activeRecItems, setActiveRecItems] = useState([]);  // itens da conferência atual
  const [approving, setApproving] = useState(false);

  useEffect(() => {
    let mounted = true;
    (async () => {
      try {
        const [prods, recs] = await Promise.all([
          window.scpDb.products.list(),
          window.scpDb.receivings.list(),
        ]);
        if (!mounted) return;
        // adapta para UI shape (com .min, .lastPrice etc.)
        const ui = prods.map(p => ({
          ...p,
          min: p.min_stock,
          lastPrice: Number(p.last_price ?? 0),
          supplier: p.preferred_supplier?.name || '—',
        }));
        setProducts(ui);
        setReceivings(recs.map(toUiReceiving));
      } catch (e) {
        if (mounted) setLoadErr(e.message || 'Falha ao carregar dados');
      } finally {
        if (mounted) setLoading(false);
      }
    })();
    return () => { mounted = false; };
  }, []);

  // Carrega o primeiro recebimento pendente como "Conferência em andamento"
  useEffect(() => {
    const pendente = receivings.find(r => r.status === 'Pendente');
    if (!pendente) { setActiveRec(null); setActiveRecItems([]); return; }
    (async () => {
      try {
        const full = await window.scpDb.receivings.getById(pendente.id);
        setActiveRec(full);
        setActiveRecItems(full.items || []);
      } catch (e) { /* ignore */ }
    })();
  }, [receivings]);

  const low = useMemo(
    () => products.filter(p => Number(p.stock) < Number(p.min)).sort((a, b) => (a.stock / Math.max(1, a.min)) - (b.stock / Math.max(1, b.min))),
    [products]
  );
  const stockValue = useMemo(
    () => products.reduce((s, p) => s + Number(p.stock) * Number(p.lastPrice), 0),
    [products]
  );

  const kpis = useMemo(() => {
    const pendentes = receivings.filter(r => r.status === 'Pendente').length;
    const divergencias = receivings.filter(r => r.status === 'Pendente' && r.divergence_count > 0).length;
    return {
      pendentes,
      divergencias,
      totalSKU: products.length,
    };
  }, [receivings, products]);

  const handleApprove = async () => {
    if (!activeRec) return;
    setApproving(true);
    try {
      await window.scpDb.receivings.approve(activeRec.id, { fallbackToOrdered: true });
      window.scpToast('Conferência aprovada', {
        kind: 'emerald',
        sub: `${activeRec.code} · entrada lançada no estoque`,
      });
      // recarrega receivings e produtos
      const [prods, recs] = await Promise.all([
        window.scpDb.products.list(),
        window.scpDb.receivings.list(),
      ]);
      setProducts(prods.map(p => ({ ...p, min: p.min_stock, lastPrice: Number(p.last_price ?? 0), supplier: p.preferred_supplier?.name || '—' })));
      setReceivings(recs.map(toUiReceiving));
    } catch (e) {
      window.scpToast('Erro ao aprovar', { kind: 'coral', sub: e.message });
    } finally {
      setApproving(false);
    }
  };

  const handleReject = async () => {
    if (!activeRec) return;
    if (!confirm(`Recusar lote ${activeRec.code}? Não entra no estoque.`)) return;
    try {
      await window.scpDb.receivings.reject(activeRec.id, 'Lote recusado pelo conferente');
      window.scpToast('Lote recusado', { kind: 'coral', sub: `${activeRec.code} · devolução agendada` });
      const recs = await window.scpDb.receivings.list();
      setReceivings(recs.map(toUiReceiving));
    } catch (e) {
      window.scpToast('Erro ao recusar', { kind: 'coral', sub: e.message });
    }
  };

  const handleAutoQuote = () => {
    window.scpToast('Cotação automática iniciada', { kind: 'emerald', sub: `${low.length} produtos abaixo do mínimo` });
    setTimeout(() => setRoute && setRoute('newQuotation'), 600);
  };

  const refreshReceivings = async () => {
    const recs = await window.scpDb.receivings.list();
    setReceivings(recs.map(toUiReceiving));
  };

  return (
    <div className="scp-screen scp-fade-in">
      <div className="scp-dash-grid">
        <Stat label="Valor em estoque" value={BRL(stockValue)} sub={`${kpis.totalSKU} SKUs ativos`} icon={<Icon.Stock size={16}/>}/>
        <Stat label="Itens abaixo do mín." value={String(low.length)} sub={low.length > 0 ? 'Sugerir cotação automática' : 'Tudo em dia'} delta={low.length > 0 ? 'reposição' : 'ok'} deltaTone={low.length > 0 ? 'amber' : 'emerald'} icon={<Icon.Warning size={16}/>}/>
        <Stat label="Recebimentos pendentes" value={String(kpis.pendentes)} sub={kpis.divergencias > 0 ? `${kpis.divergencias} com divergência` : 'Sem divergências'} icon={<Icon.Box size={16}/>}/>
        <Stat label="Recebimentos no mês" value={String(receivings.filter(r => { const d = new Date(r.approved_at || 0); return d.getMonth() === new Date().getMonth(); }).length)} sub="Aprovados/conferidos" icon={<Icon.Trend size={16}/>}/>
      </div>

      {loadErr && (
        <Card style={{ padding: 14, borderColor: 'oklch(0.42 0.10 25 / .55)', background: 'oklch(0.26 0.08 25 / .25)' }}>
          <strong style={{ color: 'oklch(0.88 0.14 25)' }}>Falha ao carregar estoque:</strong>{' '}
          <span style={{ color: 'var(--fg-2)', fontSize: 13 }}>{loadErr}</span>
        </Card>
      )}

      <div className="scp-row scp-row-2-1">
        <Card style={{ padding: 0, overflow: 'hidden' }}>
          <div style={{ padding: 22, paddingBottom: 0 }}>
            <SectionHead
              title="Recebimentos recentes"
              sub="Conferência de mercadoria vs. pedido emitido"
              right={<Btn kind="primary" size="sm" icon={<Icon.Plus size={14}/>} onClick={() => setShowNewRec(true)}>Novo Recebimento</Btn>}
            />
          </div>
          <table className="scp-table">
            <thead>
              <tr>
                <th>Recebimento</th>
                <th>Pedido</th>
                <th>Fornecedor</th>
                <th>Itens</th>
                <th>Divergências</th>
                <th>Status</th>
                <th>Quando</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {loading && (
                <tr><td colSpan={8} style={{ padding: 32, textAlign: 'center', color: 'var(--fg-3)' }}>Carregando recebimentos…</td></tr>
              )}
              {!loading && receivings.length === 0 && (
                <tr><td colSpan={8} style={{ padding: 32, textAlign: 'center', color: 'var(--fg-3)' }}>
                  Nenhum recebimento registrado. Crie um quando o pedido chegar.
                </td></tr>
              )}
              {!loading && receivings.map(r => (
                <tr key={r.id} className="clickable">
                  <td className="em num">{r.code}</td>
                  <td className="num" style={{ color: 'var(--fg-3)' }}>{r.order}</td>
                  <td>{r.supplier}</td>
                  <td className="num">{r.divergence_count}</td>
                  <td>
                    {r.divergence_count === 0
                      ? <Pill tone="emerald">Sem divergências</Pill>
                      : <Pill tone="amber">{r.divergence_count} {r.divergence_count === 1 ? 'item' : 'itens'}</Pill>}
                  </td>
                  <td><Badge tone={r.status === 'Aprovado' ? 'emerald' : r.status === 'Recusado' ? 'coral' : 'amber'}>{r.status}</Badge></td>
                  <td className="num" style={{ color: 'var(--fg-3)' }}>{r.at}</td>
                  <td><IconBtn icon={<Icon.Chevron size={14}/>} size="sm"/></td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>

        {/* Receiving in-progress card */}
        <Card style={{ padding: 22 }}>
          <SectionHead
            title="Conferência em andamento"
            sub={activeRec ? `${activeRec.code} · ${activeRec.order?.supplier?.name || '—'}` : 'Sem recebimento pendente'}
          />
          {!activeRec ? (
            <div style={{ padding: 30, textAlign: 'center', color: 'var(--fg-3)', fontSize: 13 }}>
              Nenhuma conferência aberta. Crie um novo recebimento quando um pedido chegar.
            </div>
          ) : (
            <>
              <div className="scp-receive">
                {activeRecItems.length === 0 && (
                  <div style={{ padding: 14, color: 'var(--fg-3)', fontSize: 12.5, textAlign: 'center' }}>
                    Sem itens no recebimento.
                  </div>
                )}
                {activeRecItems.map((it, i) => {
                  const ordered = Number(it.qty_ordered);
                  const received = Number(it.qty_received);
                  const ok = it.ok || (received === ordered && received > 0);
                  return (
                    <div key={it.id} className={cls('row', ok && 'ok')}>
                      <span className="check">{ok && <Icon.Check size={14}/>}</span>
                      <div className="info">
                        <span className="n">Item · ID {it.product_id?.slice(0, 8)}</span>
                        <span className="m num">Pedido: {ordered} · Recebido: {received}</span>
                        {it.divergence && <span className="warn">⚠ {it.divergence}</span>}
                      </div>
                    </div>
                  );
                })}
              </div>
              {activeRec.status === 'aprovado' || activeRec.status === 'recusado' ? (
                <div style={{ marginTop: 14, padding: '10px 14px', background: 'oklch(0.22 0.04 160 / .35)', border: '1px solid oklch(0.34 0.06 160 / .55)', borderRadius: 10, fontSize: 12.5, color: 'oklch(0.92 0.13 160)', display: 'flex', alignItems: 'center', gap: 8 }}>
                  <Icon.Check size={14}/> Conferência finalizada
                </div>
              ) : (
                <div style={{ display: 'flex', gap: 8, marginTop: 14 }}>
                  <Btn kind="primary" size="sm" icon={<Icon.Check size={14}/>} onClick={handleApprove} disabled={approving}>
                    {approving ? 'Aprovando…' : 'Aprovar com ressalvas'}
                  </Btn>
                  <Btn kind="secondary" size="sm" onClick={handleReject} disabled={approving}>Recusar lote</Btn>
                </div>
              )}
            </>
          )}
        </Card>
      </div>

      <Card style={{ padding: 0, overflow: 'hidden' }}>
        <div style={{ padding: 22, paddingBottom: 0 }}>
          <SectionHead title="Estoque crítico" sub="Produtos abaixo do mínimo configurado" right={<Btn kind="primary" size="sm" icon={<Icon.Wand size={14}/>} onClick={handleAutoQuote}>Abrir cotação automática</Btn>}/>
        </div>
        <table className="scp-table">
          <thead>
            <tr>
              <th>Produto</th>
              <th>Categoria</th>
              <th style={{ textAlign: 'right' }}>Estoque</th>
              <th style={{ textAlign: 'right' }}>Mínimo</th>
              <th>Nível</th>
              <th>Sugestão de compra</th>
              <th>Melhor fornecedor</th>
            </tr>
          </thead>
          <tbody>
            {!loading && low.length === 0 && (
              <tr><td colSpan={7} style={{ padding: 30, textAlign: 'center', color: 'var(--fg-3)' }}>
                Nenhum produto abaixo do mínimo. Estoque saudável.
              </td></tr>
            )}
            {!loading && low.map(p => {
              const c = CATEGORIES.find(c => c.key === p.cat);
              const r = p.min > 0 ? p.stock / p.min : 0;
              const need = Math.max(0, p.min * 2 - p.stock);
              return (
                <tr key={p.id}>
                  <td>
                    <div className="em">{p.name}</div>
                    <div className="num" style={{ fontSize: 11, color: 'var(--fg-3)' }}>{p.code}</div>
                  </td>
                  <td><Badge tone={c.tone}>{c.label}</Badge></td>
                  <td className="num" style={{ textAlign: 'right', color: 'oklch(0.84 0.14 78)', fontWeight: 700 }}>{p.stock} {p.unit}</td>
                  <td className="num" style={{ textAlign: 'right', color: 'var(--fg-3)' }}>{p.min}</td>
                  <td>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                      <div className="scp-stock-bar"><span style={{ width: Math.min(100, r * 100) + '%' }} /></div>
                      <span className="num" style={{ fontSize: 11.5, color: 'oklch(0.84 0.14 78)' }}>{Math.round(r * 100)}%</span>
                    </div>
                  </td>
                  <td className="num em">{need} {p.unit}</td>
                  <td style={{ color: 'var(--fg-2)' }}>{p.supplier}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </Card>

      {showNewRec && <NewReceivingModal onClose={() => setShowNewRec(false)} onCreated={refreshReceivings} />}
    </div>
  );
}

function NewReceivingModal({ onClose, onCreated }) {
  const [orderId, setOrderId] = useState('');
  const [note, setNote] = useState('');
  const [orders, setOrders] = useState([]);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    let mounted = true;
    (async () => {
      const rows = await window.scpDb.orders.list();
      // só pedidos em trânsito/confirmado/emitido (que faz sentido conferir)
      const filtered = rows.filter(o => ['em_transito', 'confirmado', 'emitido'].includes(o.status));
      if (mounted) setOrders(filtered);
    })();
    return () => { mounted = false; };
  }, []);

  const selected = orders.find(o => o.id === orderId);
  const canSubmit = !!orderId && !saving;

  const submit = async () => {
    if (!canSubmit) return;
    setSaving(true);
    try {
      const created = await window.scpDb.receivings.create({ order_id: orderId, notes: note });
      window.scpToast('Recebimento registrado', { kind: 'emerald', sub: `${created.code} · aguardando conferência` });
      onCreated && (await onCreated());
      onClose();
    } catch (e) {
      window.scpToast('Erro ao criar recebimento', { kind: 'coral', sub: e.message });
    } finally {
      setSaving(false);
    }
  };

  return ReactDOM.createPortal((
    <div className="scp-modal-mask" onClick={onClose}>
      <div className="scp-modal" style={{ width: 560 }} onClick={e => e.stopPropagation()}>
        <div className="scp-modal-head">
          <h3>Novo Recebimento</h3>
          <IconBtn icon={<Icon.X size={14}/>} size="sm" onClick={onClose}/>
        </div>
        <div className="scp-modal-body" style={{ padding: '18px 22px' }}>
          <div className="scp-wfield-list">
            <div className="scp-field">
              <span>Pedido de compra <em style={{ color: 'oklch(0.74 0.18 25)', fontStyle: 'normal' }}>*</em></span>
              <select className="scp-select" value={orderId} onChange={e => setOrderId(e.target.value)}>
                <option value="">Selecione um pedido em trânsito…</option>
                {orders.map(o => {
                  const supName = o.supplier?.name || '—';
                  return (
                    <option key={o.id} value={o.id}>{o.code} · {supName} · {window.SCP.BRL(o.total)}</option>
                  );
                })}
              </select>
              {orders.length === 0 && <small style={{ fontSize: 11, color: 'var(--fg-3)' }}>Nenhum pedido aguardando conferência.</small>}
            </div>
            {selected && (
              <div className="scp-detail-list">
                <div className="scp-detail-list-row">
                  <div>
                    <div className="n">{selected.supplier?.name}</div>
                    <div className="s">{selected.itemsCount} itens · ETA {selected.eta ? new Date(selected.eta).toLocaleDateString('pt-BR') : '—'}</div>
                  </div>
                  <span className="v">{window.SCP.BRL(selected.total)}</span>
                </div>
              </div>
            )}
            <div className="scp-field">
              <span>Observação (opcional)</span>
              <textarea className="scp-textarea" rows={3} value={note} onChange={e => setNote(e.target.value)} placeholder="Ex.: Caixa amassada, validade curta, etc." />
            </div>
          </div>
        </div>
        <div className="scp-modal-foot">
          <span>Será criado um registro de conferência</span>
          <div style={{ display: 'flex', gap: 8 }}>
            <Btn kind="ghost" onClick={onClose}>Cancelar</Btn>
            <Btn kind="primary" disabled={!canSubmit} onClick={submit} icon={<Icon.Check size={14}/>}>
              {saving ? 'Registrando…' : 'Registrar recebimento'}
            </Btn>
          </div>
        </div>
      </div>
    </div>
  ), document.body);
}

(function() {
  if (document.getElementById('scp-stock-css')) return;
  const s = document.createElement('style'); s.id = 'scp-stock-css';
  s.textContent = `
    .scp-receive { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
    .scp-receive .row { display: grid; grid-template-columns: 24px 1fr; gap: 10px; padding: 10px; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--border-soft); }
    .scp-receive .row.ok { background: oklch(0.22 0.04 160 / .35); border-color: oklch(0.34 0.06 160 / .55); }
    .scp-receive .check { width: 22px; height: 22px; border-radius: 6px; display: grid; place-items: center; background: var(--surface-3); border: 1px solid var(--border); color: white; }
    .scp-receive .row.ok .check { background: oklch(0.55 0.13 160); border-color: oklch(0.55 0.13 160); }
    .scp-receive .info { display: flex; flex-direction: column; gap: 2px; }
    .scp-receive .info .n { font-size: 12.5px; color: var(--fg); font-weight: 600; }
    .scp-receive .info .m { font-size: 11px; color: var(--fg-3); }
    .scp-receive .info .warn { font-size: 11px; color: oklch(0.86 0.14 78); margin-top: 2px; }

    .scp-stock-bar { width: 100px; height: 5px; background: var(--surface-2); border-radius: 999px; overflow: hidden; }
    .scp-stock-bar > span { display: block; height: 100%; background: linear-gradient(90deg, oklch(0.78 0.18 25), oklch(0.84 0.14 78)); border-radius: 999px; }
  `;
  document.head.appendChild(s);
})();

window.ScreenStock = ScreenStock;
