import { NextResponse } from "next/server";
import { createClient, createAdminClient } from "@/lib/supabase-server";
import { canCompany, getCompanyContext } from "@/lib/company-context";

/**
 * O que já está pronto para o preço sair certo, e o que falta.
 *
 * A tela guiada precisa dizer onde a pessoa está, não só listar passos. Um
 * checklist que não sabe o que já foi feito vira uma lista de deveres que
 * ninguém encara; um que mostra três de quatro prontos é um empurrão.
 *
 * Cada item devolve o número que o torna verdadeiro — quantas máquinas têm
 * custo, quanto é o custo fixo — porque "pendente" sem quantidade não diz se
 * falta uma tarde ou cinco minutos.
 */
export async function GET() {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();
  if (!user) return NextResponse.json({ error: "Não autenticado." }, { status: 401 });

  const ctx = await getCompanyContext(supabase, user);
  if (!canCompany(ctx, user.id, "pricing.read")) {
    return NextResponse.json({ error: "Sem permissão." }, { status: 403 });
  }

  const admin = createAdminClient();
  const empresa = ctx.companyId;
  /* `machines` e `labor_roles` guardam o dono em user_id, e nao company_id. */
  const donos = ctx.tenantIds?.length ? ctx.tenantIds : [empresa];

  const [config, variaveis, fixos, maquinas, cargos, categorias, produtos] = await Promise.all([
    admin.from("company_pricing_settings").select("*").eq("company_id", empresa).maybeSingle(),
    admin.rpc("custo_variavel_da_venda", { p_company_id: empresa, p_percentual_de_comissao: 0 }),
    admin.rpc("custo_fixo_mensal", { p_company_id: empresa, p_meses: 3 }),
    admin.from("machines").select("id,name,hourly_cost").in("user_id", donos),
    admin.from("labor_roles").select("id,role_name,hourly_rate").in("user_id", donos),
    admin.from("categories").select("id,name,pricing_rule").in("user_id", donos),
    admin
      .from("products")
      .select("id,cost_total,estimated_base_cost", { count: "exact", head: false })
      .in("user_id", donos)
      .neq("product_kind", "digital")
      .limit(2000),
  ]);

  const listaMaquinas = maquinas.data ?? [];
  const listaCargos = cargos.data ?? [];
  const listaCategorias = categorias.data ?? [];
  const listaProdutos = produtos.data ?? [];

  const comCusto = (v: unknown) => Number(v ?? 0) > 0.0001;

  return NextResponse.json({
    ok: true,
    custosVariaveis: {
      configurado: Boolean(config.data),
      regime: config.data?.tax_regime ?? null,
      totalPct: Number((variaveis.data as { total_pct?: number } | null)?.total_pct ?? 0),
      detalhe: variaveis.data ?? null,
    },
    custosFixos: fixos.data ?? null,
    /* A hora da estrutura: fixo de estrutura mensal / horas produtivas da
       empresa. Cada precificacao carrega os fixos proporcionais ao tempo da
       propria ficha. O que ja entra pela hora de maquina/trabalho (categorias
       'fixo_producao') sai da base para nao cobrar duas vezes. taxa=0 quando
       as horas nao foram informadas — o motor nem ve a fatia. */
    horaDaEstrutura: (() => {
      const dadosFixos = fixos.data as { total_mensal?: number; producao_mensal?: number } | null;
      const fixoMensal = Number(dadosFixos?.total_mensal ?? 0);
      const producaoMensal = Number(dadosFixos?.producao_mensal ?? 0);
      const estruturaMensal = Math.max(0, Math.round((fixoMensal - producaoMensal) * 100) / 100);
      const horasMes = Number(config.data?.productive_hours_month ?? 0);
      const taxa = horasMes > 0 ? Math.round((estruturaMensal / horasMes) * 100) / 100 : 0;
      return { configurada: horasMes > 0, horasMes, estruturaMensal, taxa };
    })(),
    producao: {
      maquinas: listaMaquinas.length,
      maquinasComCusto: listaMaquinas.filter((m) => comCusto(m.hourly_cost)).length,
      cargos: listaCargos.length,
      cargosComCusto: listaCargos.filter((c) => comCusto(c.hourly_rate)).length,
    },
    margens: {
      categorias: listaCategorias.length,
      comRegraPropria: listaCategorias.filter((c) => c.pricing_rule !== null).length,
      /* As regras em si, para o assistente aplicar a margem DA categoria em
         vez do padrão genérico — o número que o setup mandou configurar
         finalmente chega onde o preço nasce. */
      lista: listaCategorias
        .filter((c) => c.pricing_rule !== null)
        .map((c) => {
          const regra = c.pricing_rule as { marginTargetPct?: number; marginMinPct?: number } | null;
          return {
            id: c.id,
            nome: c.name,
            marginTargetPct: Number(regra?.marginTargetPct ?? 0) || null,
            marginMinPct: Number(regra?.marginMinPct ?? 0) || null,
          };
        })
        .filter((c) => c.marginTargetPct != null),
    },
    produtos: {
      total: listaProdutos.length,
      comCusto: listaProdutos.filter(
        (p) => comCusto(p.cost_total) || comCusto(p.estimated_base_cost)
      ).length,
    },
  });
}
