/* global React */
/* =====================================================
   VendusCopilot — CAMADA DE DADOS DO COPILOTO (seam VIRADO)
   -----------------------------------------------------
   Esta é a versão de PRODUÇÃO do seam: chama a API real (/api/*).
   As ASSINATURAS são idênticas à versão mock — por isso nenhuma página
   (Copiloto, Mensagens, TopBar) precisou mudar ao virar mock → API.

   Princípio "nunca inventar número": em erro/sem dado, devolvemos vazio
   (e a UI mostra estados honestos: "aguardando", "conecte sua conta").
   NÃO há fallback para dados mock.
===================================================== */

// O id da conta conectada. Em produção vem da sessão/conta do vendedor;
// aqui aceitamos via window global ou ?account=... na URL.
// Multi-loja: a seleção ativa fica no localStorage — um id de loja OU "todas" (consolidado).
// "todas" → manda x-scope; uma loja → manda x-account-id. (Fase 2.)
try {
  const _sel = typeof localStorage !== "undefined" && localStorage.getItem("vendus_account");
  if (_sel === "todas") window.VENDUS_SCOPE = "todas";
  else if (_sel) window.VENDUS_ACCOUNT_ID = _sel;
} catch {}

function accountId() {
  return (
    window.VENDUS_ACCOUNT_ID ||
    new URLSearchParams(window.location.search).get("account") ||
    ""
  );
}

// As páginas (escritas na fase mock) passam o placeholder "demo". No seam real
// isso significa "use a conta de verdade" — assim não foi preciso mudar as páginas.
function resolveAccount(account) {
  return account && account !== "demo" ? account : accountId();
}

// Cabeçalhos com o token do usuário logado (multitenant). Sem login → sem header.
async function authHeaders(extra) {
  const h = Object.assign({ accept: "application/json" }, extra || {});
  try {
    const t = window.VendusAuth && (await window.VendusAuth.getToken());
    if (t) h.authorization = "Bearer " + t;
  } catch {}
  if (window.VENDUS_SCOPE === "todas") h["x-scope"] = "todas";              // consolidado (todas as lojas)
  else if (window.VENDUS_ACCOUNT_ID) h["x-account-id"] = window.VENDUS_ACCOUNT_ID; // loja ativa
  return h;
}

async function getJSON(url) {
  try {
    const r = await fetch(url, { headers: await authHeaders() });
    if (!r.ok) return null;
    return await r.json();
  } catch {
    return null;
  }
}

// GET /api/digest
async function getDigest(account, periodo = "diario") {
  account = resolveAccount(account);
  const data = await getJSON(`/api/digest?account=${encodeURIComponent(account)}&periodo=${periodo}`);
  if (!data || typeof data.resumo !== "string") {
    return {
      resumo:
        "Ainda não há uma análise para mostrar. Conecte sua conta do Mercado Livre — assim que os dados chegarem, o Copiloto monta seu resumo.",
      findings: [],
    };
  }
  return { resumo: data.resumo, findings: Array.isArray(data.findings) ? data.findings : [], atualizado_em: data.atualizado_em || null };
}

// GET /api/alerts
async function getAlerts(account) {
  account = resolveAccount(account);
  const data = await getJSON(`/api/alerts?account=${encodeURIComponent(account)}`);
  return Array.isArray(data) ? data : [];
}

// GET /api/messages
async function getMessages(account) {
  account = resolveAccount(account);
  const data = await getJSON(`/api/messages?account=${encodeURIComponent(account)}`);
  return Array.isArray(data) ? data : [];
}

// POST /api/messages/send — aprovação SEMPRE humana (botão "Aprovar e enviar")
async function sendMessage(messageId, texto) {
  try {
    const r = await fetch("/api/messages/send", {
      method: "POST",
      headers: await authHeaders({ "content-type": "application/json" }),
      body: JSON.stringify({ message_id: messageId, texto }),
    });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) return { ok: false, error: data.error || "Falha ao enviar." };
    return { ok: true, id: messageId };
  } catch (e) {
    return { ok: false, error: String(e.message || e) };
  }
}

// GET /api/score — score de qualidade da loja (objeto honesto se sem dado)
async function getScore(account, periodo = "diario") {
  account = resolveAccount(account);
  const data = await getJSON(`/api/score?account=${encodeURIComponent(account)}&periodo=${periodo}`);
  return data && typeof data === "object" ? data : null;
}

// POST /api/acoes/aplicar — executa a ação aprovada (Workstream D). Só com clique humano.
async function aplicarAcao(acaoId, para, confirmar) {
  try {
    const r = await fetch("/api/acoes/aplicar", { method: "POST", headers: await authHeaders({ "content-type": "application/json" }), body: JSON.stringify({ acao_id: acaoId, para, confirmar }) });
    const data = await r.json().catch(() => ({}));
    if (data && data.gated) return { ok: false, gated: true, error: data.error };
    if (!r.ok) return { ok: false, error: data.error || "Não consegui aplicar a ação.", precisa_confirmar: !!data.precisa_confirmar };
    return { ok: true, ...data };
  } catch (e) { return { ok: false, error: String(e.message || e) }; }
}
// POST /api/acoes/desfazer — reverte uma execução (restaura o estado anterior).
async function desfazerAcao(logId) {
  try {
    const r = await fetch("/api/acoes/desfazer", { method: "POST", headers: await authHeaders({ "content-type": "application/json" }), body: JSON.stringify({ log_id: logId }) });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) return { ok: false, error: data.error || "Não consegui desfazer." };
    return { ok: true };
  } catch (e) { return { ok: false, error: String(e.message || e) }; }
}
// GET /api/actions-log — histórico de ações executadas.
async function getActionsLog() {
  const data = await getJSON(`/api/actions-log?account=${encodeURIComponent(resolveAccount())}`);
  return Array.isArray(data) ? data : [];
}

// GET /api/ads — dados da aba Anúncios (resumo + campanhas + gated + recomendações).
async function getAds(marketplace) {
  const acc = resolveAccount();
  const mk = marketplace || "mercado_livre";
  const data = await getJSON(`/api/ads?account=${encodeURIComponent(acc)}&marketplace=${encodeURIComponent(mk)}`);
  return data && typeof data === "object" ? data : { conectado: false };
}
// POST /api/ads/aplicar — aplica uma ação de Ads direto da aba (gated → manual).
async function aplicarAds(payload) {
  try {
    const r = await fetch("/api/ads/aplicar", { method: "POST", headers: await authHeaders({ "content-type": "application/json" }), body: JSON.stringify({ account_id: resolveAccount(), ...payload }) });
    const data = await r.json().catch(() => ({}));
    if (data && data.gated) return { ok: false, gated: true, error: data.error };
    if (!r.ok) return { ok: false, error: data.error || "Não consegui aplicar.", precisa_confirmar: !!data.precisa_confirmar };
    return { ok: true, ...data };
  } catch (e) { return { ok: false, error: String(e.message || e) }; }
}
// POST /api/analyze {skill:"ads"} — (re)gera as recomendações de Ads da skill vendus-ads.
async function analisarAds() {
  try {
    const r = await fetch("/api/analyze", { method: "POST", headers: await authHeaders({ "content-type": "application/json" }), body: JSON.stringify({ account_id: resolveAccount(), skill: "ads", periodo: "diario" }) });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) return { ok: false, error: data.detalhe || data.error || "Não consegui analisar os anúncios." };
    return { ok: true, ...data };
  } catch (e) { return { ok: false, error: String(e.message || e) }; }
}

// GET /api/saude-conta — reputação/saúde da conta (termômetro + 3 indicadores). Fatos do ML.
async function getSaudeConta(account) {
  account = resolveAccount(account);
  const data = await getJSON(`/api/saude-conta?account=${encodeURIComponent(account)}`);
  return data && typeof data === "object" ? data : { conectado: false, reputacao: null };
}

// POST /api/analyze — refaz a análise AGORA, em 2º plano + polling (não trava num request de 60s).
async function runAnalysisNow(account, periodo = "diario") {
  account = resolveAccount(account);
  // "antes": timestamp da última análise, para detectar quando a nova ficar pronta
  let before = null;
  try { const d0 = await getDigest(account, periodo); before = d0 && d0.atualizado_em; } catch {}
  // dispara a análise em segundo plano (responde 202 na hora)
  try {
    const r = await fetch("/api/analyze", {
      method: "POST",
      headers: await authHeaders({ "content-type": "application/json" }),
      body: JSON.stringify({ account_id: account, periodo, background: true }),
    });
    if (!r.ok && r.status !== 202) {
      const e = await r.json().catch(() => ({}));
      if (r.status === 429) return { ok: false, limite: true, error: e.detalhe || "Você atingiu o limite de análises do mês." };
      return { ok: false, error: e.detalhe || e.error || "Não consegui iniciar a análise." };
    }
  } catch (e) {
    return { ok: false, error: String(e.message || e) };
  }
  // polling: espera a análise nova aparecer (até ~2 min)
  for (let i = 0; i < 30; i++) {
    await new Promise((res) => setTimeout(res, 4000));
    try {
      const d = await getDigest(account, periodo);
      if (d && d.atualizado_em && d.atualizado_em !== before) return { ok: true, digest: d };
    } catch {}
  }
  return { ok: false, error: "A análise está demorando mais que o normal. Recarregue a página em instantes — ela deve aparecer." };
}

// GET /api/schedule — configuração de agendamento do vendedor
async function getSchedule(account) {
  account = resolveAccount(account);
  const data = await getJSON(`/api/schedule?account=${encodeURIComponent(account)}`);
  return data || { enabled: false, periodo: "diario", cadence: { type: "daily", times: ["08:00"] } };
}

// PUT /api/schedule — salva a configuração de agendamento
async function saveSchedule(account, config) {
  account = resolveAccount(account);
  try {
    const r = await fetch("/api/schedule", {
      method: "PUT",
      headers: await authHeaders({ "content-type": "application/json" }),
      body: JSON.stringify({ account_id: account, ...config }),
    });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) return { ok: false, error: data.error || "Falha ao salvar." };
    return { ok: true };
  } catch (e) {
    return { ok: false, error: String(e.message || e) };
  }
}

// GET /api/ml/status — loja ATIVA do usuário
async function getStatus() {
  const data = await getJSON("/api/ml/status");
  return data || { connected: false };
}
// ===== Multi-loja (Fase 1): listar, renomear, alternar, conectar outra =====
async function getAccounts() { const d = await getJSON("/api/ml/accounts"); return Array.isArray(d) ? d : []; }
async function renameAccount(id, apelido) { return _send("PATCH", "/api/ml/accounts", { id, apelido }); }
function getActiveAccount() { return window.VENDUS_SCOPE === "todas" ? "todas" : (window.VENDUS_ACCOUNT_ID || ""); }
function setActiveAccount(id) {
  try { localStorage.setItem("vendus_account", id || ""); } catch {}
  if (id === "todas") { window.VENDUS_SCOPE = "todas"; window.VENDUS_ACCOUNT_ID = ""; }
  else { window.VENDUS_SCOPE = ""; window.VENDUS_ACCOUNT_ID = id || ""; }
  window.location.reload(); // recarrega as telas no contexto escolhido (loja ou consolidado)
}
async function connectStore() {
  try {
    const r = await fetch("/api/ml/connect", { headers: await authHeaders() });
    const d = await r.json().catch(() => ({}));
    if (r.ok && d.url) { window.location.assign(d.url); return { ok: true }; }
    return { ok: false, error: d.error || "Conexão com o Mercado Livre indisponível." };
  } catch (e) { return { ok: false, error: String(e.message || e) }; }
}
// GET /api/products
async function getProducts() {
  const data = await getJSON("/api/products");
  return Array.isArray(data) ? data : [];
}
// GET /api/sales
async function getSales() {
  const data = await getJSON("/api/sales");
  return data && typeof data === "object" ? data : { orders: [], kpis: null };
}
// POST /api/ml/sync-now — puxa produtos/pedidos atuais do ML
async function syncNow() {
  try {
    const r = await fetch("/api/ml/sync-now", { method: "POST", headers: await authHeaders({ "content-type": "application/json" }), body: "{}" });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) return { ok: false, error: data.error || "Falha ao sincronizar." };
    return { ok: true, ...data };
  } catch (e) {
    return { ok: false, error: String(e.message || e) };
  }
}

// POST /api/products/costs — salva custos (manual ou planilha)
async function saveCosts(costs) {
  try {
    const r = await fetch("/api/products/costs", { method: "POST", headers: await authHeaders({ "content-type": "application/json" }), body: JSON.stringify({ costs }) });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) return { ok: false, error: data.error || "Falha ao salvar custos." };
    return { ok: true, ...data };
  } catch (e) {
    return { ok: false, error: String(e.message || e) };
  }
}

// GET /api/acoes — lista as ações (objetos acionáveis) do vendedor
async function getAcoes(status) {
  const acc = resolveAccount();
  const params = new URLSearchParams({ account: acc });
  if (status) params.set("status", status);
  const data = await getJSON(`/api/acoes?${params.toString()}`);
  return Array.isArray(data) ? data : [];
}
// PATCH /api/acoes — muda o status de uma ação
async function updateAcao(id, status, lembrarAte) {
  try {
    const r = await fetch("/api/acoes", { method: "PATCH", headers: await authHeaders({ "content-type": "application/json" }), body: JSON.stringify({ id, status, lembrar_ate: lembrarAte }) });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) return { ok: false, error: data.error || "Falha ao atualizar a ação." };
    return { ok: true, ...data };
  } catch (e) {
    return { ok: false, error: String(e.message || e) };
  }
}

// ===== Fornecedores e Compras (CRUD) =====
async function _send(method, url, body) {
  try {
    const r = await fetch(url, { method, headers: await authHeaders({ "content-type": "application/json" }), body: body ? JSON.stringify(body) : undefined });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) return { ok: false, error: data.error || "Falha na operação." };
    return { ok: true, ...data };
  } catch (e) { return { ok: false, error: String(e.message || e) }; }
}
async function getSuppliers() { const d = await getJSON(`/api/suppliers?account=${encodeURIComponent(resolveAccount())}`); return Array.isArray(d) ? d : []; }
async function saveSupplier(s) { return s.id ? _send("PATCH", "/api/suppliers", s) : _send("POST", "/api/suppliers", s); }
async function deleteSupplier(id) { return _send("DELETE", `/api/suppliers?account=${encodeURIComponent(resolveAccount())}&id=${id}`); }
async function getPurchases() { const d = await getJSON(`/api/purchases?account=${encodeURIComponent(resolveAccount())}`); return Array.isArray(d) ? d : []; }
// ===== Financeiro Fase 1: contas a pagar + pagamentos parciais =====
async function getLancamentos(tipo = "pagar") { const d = await getJSON(`/api/lancamentos?account=${encodeURIComponent(resolveAccount())}&tipo=${tipo}`); return Array.isArray(d) ? d : []; }
async function saveLancamento(l) { return l.id ? _send("PATCH", "/api/lancamentos", l) : _send("POST", "/api/lancamentos", l); }
async function deleteLancamento(id) { return _send("DELETE", `/api/lancamentos?account=${encodeURIComponent(resolveAccount())}&id=${id}`); }
async function getMovimentos(lancamentoId) { const d = await getJSON(`/api/movimentos?account=${encodeURIComponent(resolveAccount())}&lancamento_id=${lancamentoId}`); return Array.isArray(d) ? d : []; }
async function pagarLancamento(m) { return _send("POST", "/api/movimentos", m); }
async function deleteMovimento(id) { return _send("DELETE", `/api/movimentos?account=${encodeURIComponent(resolveAccount())}&id=${id}`); }
// Resultado (Fase 2): lucro real (receita líq − CMV − despesas) + separação Caixa × Resultado.
async function getResultado(competencia) {
  const c = competencia ? `&competencia=${competencia}` : "";
  const d = await getJSON(`/api/resultado?account=${encodeURIComponent(resolveAccount())}${c}`);
  return d && typeof d === "object" ? d : null;
}
// Contas a receber (Fase 3): a receber por marketplace + recebimento em lote + Antecipe; caixa real.
async function getRecebiveis() {
  const d = await getJSON(`/api/recebiveis?account=${encodeURIComponent(resolveAccount())}`);
  return d && typeof d === "object" ? d : { por_marketplace: [], total: 0, proxima_semana: 0, historico: [] };
}
async function receberLote(payload) { return _send("POST", "/api/recebiveis/receber", { account_id: resolveAccount(), ...payload }); }
async function getCaixa(meses) {
  const d = await getJSON(`/api/caixa?account=${encodeURIComponent(resolveAccount())}${meses ? `&meses=${meses}` : ""}`);
  return d && typeof d === "object" ? d : { series: [], entradas_mes: 0, saidas_mes: 0, saldo_mes: 0 };
}
async function savePurchase(p) { return _send("POST", "/api/purchases", p); }
async function updatePurchaseStatus(id, status) { return _send("PATCH", "/api/purchases", { id, status }); }
async function deletePurchase(id) { return _send("DELETE", `/api/purchases?account=${encodeURIComponent(resolveAccount())}&id=${id}`); }

// GET /api/analyses — histórico de análises (Relatórios)
async function getAnalysesHistory() {
  const acc = resolveAccount();
  const data = await getJSON(`/api/analyses?account=${encodeURIComponent(acc)}`);
  return Array.isArray(data) ? data : [];
}

// GET /api/strategic — baseline real do Modo Estratégico
async function getStrategic() {
  const acc = resolveAccount();
  const data = await getJSON(`/api/strategic?account=${encodeURIComponent(acc)}`);
  return data && typeof data === "object" ? data : { conectado: false };
}
// GET /api/strategic/ads — só os Ads (carregado em 2º plano para a página abrir rápido)
async function getStrategicAds() {
  const acc = resolveAccount();
  const data = await getJSON(`/api/strategic/ads?account=${encodeURIComponent(acc)}`);
  return data && typeof data === "object" ? data : { ads: null };
}
// POST /api/strategic-plan — IA gera plano 30/60/90 para um objetivo
async function generatePlan(objetivo) {
  try {
    const r = await fetch("/api/strategic-plan", { method: "POST", headers: await authHeaders({ "content-type": "application/json" }), body: JSON.stringify({ objetivo }) });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) return { ok: false, error: data.error || "Falha ao gerar o plano." };
    return { ok: true, ...data };
  } catch (e) {
    return { ok: false, error: String(e.message || e) };
  }
}

// POST /api/messages/check — verifica perguntas novas e gera rascunho automático
async function checkMessages() {
  try {
    const r = await fetch("/api/messages/check", { method: "POST", headers: await authHeaders({ "content-type": "application/json" }), body: "{}" });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) return { ok: false, error: data.error || "Falha ao verificar mensagens." };
    return { ok: true, ...data };
  } catch (e) {
    return { ok: false, error: String(e.message || e) };
  }
}

// POST /api/product-analysis — análise individual de um anúncio pela IA
async function getProductAnalysis(mlItemId) {
  try {
    const r = await fetch("/api/product-analysis", { method: "POST", headers: await authHeaders({ "content-type": "application/json" }), body: JSON.stringify({ ml_item_id: mlItemId }) });
    const data = await r.json().catch(() => ({}));
    if (!r.ok) return { ok: false, error: data.error || "Falha ao analisar o produto." };
    return { ok: true, ...data };
  } catch (e) {
    return { ok: false, error: String(e.message || e) };
  }
}

// ===== Catálogo-mestre + Vínculo de anúncios (Fase A) =====
// GET /api/produtos-mestre — catálogo-mestre do vendedor (+ nº de anúncios vinculados)
async function getMestres() {
  const d = await getJSON(`/api/produtos-mestre?account=${encodeURIComponent(resolveAccount())}`);
  return Array.isArray(d) ? d : [];
}
// POST/PATCH /api/produtos-mestre — cria/edita um produto-mestre (+ níveis de preço)
async function createMestre(data) { return _send("POST", "/api/produtos-mestre", { account_id: resolveAccount(), ...data }); }
async function updateMestre(data) { return _send("PATCH", "/api/produtos-mestre", { account_id: resolveAccount(), ...data }); }
// GET/PUT /api/config-taxas — taxas por marketplace (faixas) p/ a calculadora. GET semeia defaults na 1ª vez.
async function getConfigTaxas() {
  const d = await getJSON(`/api/config-taxas?account=${encodeURIComponent(resolveAccount())}`);
  return d && typeof d === "object" ? d : { configs: [], aviso: null };
}
async function saveConfigTaxas(config) { return _send("PUT", "/api/config-taxas", { account_id: resolveAccount(), ...config }); }
// GET /api/vinculo/sugestoes — anúncios sem vínculo + a melhor sugestão do matcher
async function getVinculoSugestoes() {
  const d = await getJSON(`/api/vinculo/sugestoes?account=${encodeURIComponent(resolveAccount())}`);
  return d && typeof d === "object" ? d : { anuncios: [], total: 0, vinculados: 0, sem_vinculo: 0 };
}
// POST /api/vinculo — confirma o vínculo de um anúncio (a mestre existente ou criando na hora)
async function vincular(payload) { return _send("POST", "/api/vinculo", { account_id: resolveAccount(), ...payload }); }
// POST /api/vinculo/desvincular — desfaz o vínculo (rede de segurança)
async function desvincular(mlItemId) { return _send("POST", "/api/vinculo/desvincular", { account_id: resolveAccount(), ml_item_id: mlItemId }); }
// GET /api/anuncio-detalhe — detalhe cru do anúncio ao vivo no ML (sem IA)
async function getAnuncioDetalhe(mlItemId) {
  return await getJSON(`/api/anuncio-detalhe?account=${encodeURIComponent(resolveAccount())}&ml_item_id=${encodeURIComponent(mlItemId)}`);
}

// GET /api/subscription/status — status da assinatura (SEMPRE do servidor). Usado pela trava/paywall.
async function getSubscription() {
  return (await getJSON("/api/subscription/status")) || { ativa: false, status: "erro" };
}
// GET /api/ia-usage — quantas análises de IA foram usadas no mês (limite 30).
async function getIaUsage() {
  return (await getJSON(`/api/ia-usage?account=${encodeURIComponent(resolveAccount())}`)) || { usadas: 0, limite: 30, restantes: 30, bloqueado: false, ilimitado: false };
}

window.VendusCopilot = {
  getSubscription, getIaUsage,
  getDigest, getAlerts, getMessages, sendMessage,
  getMestres, createMestre, updateMestre, getVinculoSugestoes, vincular, desvincular, getAnuncioDetalhe,
  getConfigTaxas, saveConfigTaxas,
  getScore, runAnalysisNow, getSchedule, saveSchedule,
  getStatus, getProducts, getSales, syncNow, saveCosts, getProductAnalysis, checkMessages, getSaudeConta,
  getAccounts, renameAccount, getActiveAccount, setActiveAccount, connectStore,
  getAds, aplicarAds, analisarAds,
  getAcoes, updateAcao, aplicarAcao, desfazerAcao, getActionsLog, getStrategic, getStrategicAds, generatePlan, getAnalysesHistory,
  getSuppliers, saveSupplier, deleteSupplier, getPurchases, savePurchase, updatePurchaseStatus, deletePurchase,
  getLancamentos, saveLancamento, deleteLancamento, getMovimentos, pagarLancamento, deleteMovimento, getResultado,
  getRecebiveis, receberLote, getCaixa,
};
