import type { catalogoPublico, Formato } from "@/lib/paineis/metricas";
import type { ResultadoDoWidget } from "@/lib/paineis/servidor";
import type { Widget } from "@/lib/paineis/widgets";

export type MetricaDoCatalogo = ReturnType<typeof catalogoPublico>[number];
export type { ResultadoDoWidget, Widget };

/* Cores vivas da casa, na ordem em que as fatias e barras recebem. */
export const CORES = ["#7C3AED", "#0EA5E9", "#10B981", "#F59E0B", "#F43F5E", "#14B8A6", "#EC4899", "#6366F1", "#84CC16", "#F97316", "#A855F7"];

const BRL = new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" });
const BRL_CURTO = new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL", notation: "compact", maximumFractionDigits: 1 });
const INTEIRO = new Intl.NumberFormat("pt-BR", { maximumFractionDigits: 2 });

export function formatar(valor: number | null | undefined, formato: Formato) {
  const n = Number(valor ?? 0);
  if (formato === "dinheiro") return BRL.format(n);
  if (formato === "percentual") return `${INTEIRO.format(n)}%`;
  return INTEIRO.format(n);
}

/** Para eixos de gráfico, onde "R$ 12.345,67" não cabe. */
export function formatarCurto(valor: number, formato: Formato) {
  if (formato === "dinheiro") return BRL_CURTO.format(valor);
  if (formato === "percentual") return `${INTEIRO.format(valor)}%`;
  return new Intl.NumberFormat("pt-BR", { notation: "compact", maximumFractionDigits: 1 }).format(valor);
}

/** Modelos para não começar do zero. Cada um é só uma lista de quadros do catálogo. */
export const MODELOS: Array<{ id: string; nome: string; descricao: string; widgets: Array<Partial<Widget>> }> = [
  { id: "vazio", nome: "Em branco", descricao: "Você escolhe cada quadro.", widgets: [] },
  {
    id: "vendas",
    nome: "Vendas do mês",
    descricao: "Faturamento, ticket médio, vendedores, canais e os produtos que mais vendem.",
    widgets: [
      { metrica: "faturamento", tipo: "numero", periodo: "este_mes" },
      { metrica: "ticket_medio", tipo: "numero", periodo: "este_mes" },
      { metrica: "quantidade_de_pedidos", tipo: "numero", periodo: "este_mes" },
      { metrica: "taxa_de_conversao", tipo: "numero", periodo: "este_mes" },
      { metrica: "faturamento", tipo: "linha", periodo: "este_mes", titulo: "Faturamento dia a dia" },
      { metrica: "vendas_por_vendedor", tipo: "barras", periodo: "este_mes" },
      { metrica: "vendas_por_canal", tipo: "pizza", periodo: "este_mes" },
      { metrica: "produtos_mais_vendidos", tipo: "tabela", periodo: "este_mes", limite: 10 },
    ],
  },
  {
    id: "producao",
    nome: "Produção",
    descricao: "Pedidos por etapa e os atrasados.",
    widgets: [
      { metrica: "pedidos_atrasados", tipo: "numero" },
      { metrica: "pedidos_por_etapa", tipo: "numero", titulo: "Pedidos em andamento" },
      { metrica: "pedidos_por_etapa", tipo: "barras" },
      { metrica: "pedidos_atrasados", tipo: "tabela", agrupar_por: "cliente", titulo: "Atrasados por cliente" },
    ],
  },
  {
    id: "financeiro",
    nome: "Financeiro",
    descricao: "A receber, a pagar e o fluxo de caixa do mês.",
    widgets: [
      { metrica: "contas_a_receber_em_aberto", tipo: "numero" },
      { metrica: "contas_a_pagar_em_aberto", tipo: "numero" },
      { metrica: "fluxo_de_caixa", tipo: "numero", periodo: "este_mes", titulo: "Saldo do mês" },
      { metrica: "fluxo_de_caixa", tipo: "linha", periodo: "este_mes", titulo: "Fluxo de caixa" },
      { metrica: "contas_a_pagar_em_aberto", tipo: "barras", agrupar_por: "situacao" },
      { metrica: "contas_a_receber_em_aberto", tipo: "tabela", agrupar_por: "cliente", titulo: "Quem mais deve" },
    ],
  },
];

export async function chamar<T>(url: string, init?: RequestInit): Promise<T> {
  const resposta = await fetch(url, { ...init, headers: { "Content-Type": "application/json", ...(init?.headers ?? {}) } });
  const corpo = (await resposta.json().catch(() => null)) as (T & { error?: string }) | null;
  if (!resposta.ok) throw new Error(corpo?.error || "Não foi possível concluir agora.");
  return corpo as T;
}
