import { limitesDaLoja } from "@/lib/digitais/limites";
import { lerConfigDigital, ROTULO_DO_TIPO } from "@/lib/digitais/produto";
import { configuracaoDoR2 } from "@/lib/digitais/r2";
import { estoqueDeCodigos } from "@/lib/digitais/servidor/codigos";
import { contarComentarios } from "@/lib/digitais/servidor/comentarios";
import { ErroDigital, type ContextoDigital } from "@/lib/digitais/servidor/contexto";

type Resumo = {
  vendas_30?: number;
  vendas_30_antes?: number;
  pedidos_30?: number;
  pedidos_7?: number;
  por_dia?: Array<{ dia: string; valor: number }>;
  mais_vendidos?: Array<{ product_id: string; valor: number; pedidos: number }>;
  com_acesso?: number;
  produtos?: number;
  entregas_pendentes?: number;
  entregas_com_falha?: number;
  sem_cliente?: number;
  enviando_arquivos?: number;
};

type LinhaDeAcesso = {
  id: string;
  status: string;
  criado_em: string;
  liberado_em: string | null;
  downloads: number;
  ultimo_acesso_em: string | null;
  clients: { name: string | null; email: string | null } | null;
  products: { name: string | null } | null;
};

/* A Visão geral da área: vendas, quem tem acesso, espaço e o que pede atenção.
   Fora da rota: o painel e o assistente (MCP) leem a mesma coisa. */
export async function lerVisaoGeral({ admin, lojaId, situacao, pode }: ContextoDigital) {
  const [resumo, espaco, recentes, produtos, comentarios] = await Promise.all([
    admin.rpc("resumo_digital_da_loja", { p_loja: lojaId }),
    admin.rpc("espaco_digital_da_loja", { p_loja: lojaId }),
    admin
      .from("digital_entitlements")
      .select("id,status,criado_em,liberado_em,downloads,ultimo_acesso_em,clients(name,email),products(name)")
      .eq("user_id", lojaId)
      .order("criado_em", { ascending: false })
      .limit(6),
    admin
      .from("products")
      .select("id,name,image_url,price,digital_config,show_in_catalog,active")
      .eq("user_id", lojaId)
      .eq("product_kind", "digital"),
    /* As perguntas dos alunos sem resposta (só para quem pode ver os comentários). */
    pode("digital.comments.read") ? contarComentarios(admin, lojaId).catch(() => null) : Promise.resolve(null),
  ]);
  if (resumo.error) throw new ErroDigital("Não foi possível ler os números.", 500);

  const r = (resumo.data ?? {}) as Resumo;
  const listaDeProdutos = (produtos.data ?? []) as Array<{
    id: string;
    name: string;
    image_url: string | null;
    price: number;
    digital_config: unknown;
    show_in_catalog: boolean | null;
    active: boolean | null;
  }>;
  /* "Esgotado" e "acabando" falam da vitrine: o rascunho não alerta (quem espera código, sim). */
  const naLoja = new Set(listaDeProdutos.filter((p) => p.show_in_catalog && p.active !== false).map((p) => p.id));

  /* Fase 3: códigos acabando, encomendas esperando o arquivo final e acessos que o freio pausou. */
  const hoje = new Date().toLocaleDateString("en-CA", { timeZone: "America/Sao_Paulo" });
  const [estoque, encomendas, freio] = await Promise.all([
    estoqueDeCodigos(admin, lojaId, listaDeProdutos).catch(() => new Map()),
    admin
      .from("digital_entitlements")
      .select("entregar_ate,digital_deliverables!inner(tipo)")
      .eq("user_id", lojaId)
      .eq("status", "aguardando_arquivo")
      .eq("digital_deliverables.tipo", "encomenda")
      .limit(1000),
    admin.from("digital_entitlements").select("order_id").eq("user_id", lojaId).eq("status", "pausado").like("motivo", "freio%").limit(1000),
  ]);
  const deCodigo = Array.from(estoque.values());
  const linhasDeEncomenda = (encomendas.data ?? []) as Array<{ entregar_ate: string | null }>;
  const porId = new Map(listaDeProdutos.map((p) => [p.id, p]));
  const usoBruto = (espaco.data ?? {}) as { usado?: number; por_categoria?: Record<string, { bytes: number; arquivos: number }> };
  const vendas30 = Number(r.vendas_30 ?? 0);
  const vendasAntes = Number(r.vendas_30_antes ?? 0);

  return {
    deposito: configuracaoDoR2() !== null,
    numeros: {
      vendas30,
      variacao: vendasAntes > 0 ? Math.round(((vendas30 - vendasAntes) / vendasAntes) * 100) : null,
      pedidos30: Number(r.pedidos_30 ?? 0),
      pedidos7: Number(r.pedidos_7 ?? 0),
      comAcesso: Number(r.com_acesso ?? 0),
      produtos: Number(r.produtos ?? 0),
    },
    porDia: (r.por_dia ?? []).map((d) => ({ dia: d.dia, valor: Number(d.valor) || 0 })),
    maisVendidos: (r.mais_vendidos ?? []).map((item) => {
      const produto = porId.get(item.product_id);
      const config = lerConfigDigital(produto?.digital_config);
      return {
        id: item.product_id,
        nome: produto?.name ?? "Produto removido",
        imagem: produto?.image_url ?? null,
        tipo: config.tipo,
        rotuloDoTipo: ROTULO_DO_TIPO[config.tipo],
        valor: Number(item.valor) || 0,
        pedidos: Number(item.pedidos) || 0,
      };
    }),
    espaco: {
      usado: Number(usoBruto.usado ?? 0),
      porCategoria: usoBruto.por_categoria ?? {},
      ...limitesDaLoja(situacao),
    },
    atencao: {
      entregasPendentes: Number(r.entregas_pendentes ?? 0),
      entregasComFalha: Number(r.entregas_com_falha ?? 0),
      semCliente: Number(r.sem_cliente ?? 0),
      enviandoArquivos: Number(r.enviando_arquivos ?? 0),
      comentariosSemResposta: comentarios?.semResposta ?? 0,
      codigosEsgotados: deCodigo.filter((e) => naLoja.has(e.produtoId) && e.aVenda === 0 && e.total > 0).length,
      codigosAcabando: deCodigo.filter((e) => naLoja.has(e.produtoId) && e.aVenda > 0 && e.aVenda <= e.avisarCom).length,
      codigosEsperando: deCodigo.reduce((soma, e) => soma + e.esperando, 0),
      encomendasPendentes: linhasDeEncomenda.length,
      encomendasAtrasadas: linhasDeEncomenda.filter((e) => e.entregar_ate && e.entregar_ate < hoje).length,
      pausadosPeloFreio: new Set(((freio.data ?? []) as Array<{ order_id: string | null }>).map((l) => l.order_id ?? "")).size,
    },
    recentes: ((recentes.data ?? []) as unknown as LinhaDeAcesso[]).map((linha) => ({
      id: linha.id,
      status: linha.status,
      quando: linha.liberado_em ?? linha.criado_em,
      cliente: linha.clients?.name || linha.clients?.email || "Cliente",
      produto: linha.products?.name ?? "Produto",
      downloads: linha.downloads,
      ultimoAcesso: linha.ultimo_acesso_em,
    })),
  };
}
