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

/**
 * Quem vende cada insumo, e por quanto.
 *
 * A pergunta que o modulo de fornecedores promete responder e nunca respondeu:
 * o mesmo item comprado de tres fornecedores virava tres registros que nao se
 * falavam, e a comparacao de preco da tela era sempre dentro de um fornecedor
 * so. Com `supplier_materials.linked_material_id` preenchido, a comparacao
 * entre fornecedores passa a ser uma consulta.
 *
 * Devolve o mapa da empresa inteira de uma vez, em vez de uma chamada por
 * insumo: sao dezenas de linhas, e a tela de insumos e uma lista.
 */

async function getAuth() {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();
  if (!user) return { ok: false as const, status: 401, ctx: null };
  const ctx = await getCompanyContext(supabase, user);
  /* Quem ve insumo ve de quem se compra. Nao exige a chave de fornecedores:
     esta e a tela de estoque, e o dado aqui e do proprio insumo. */
  if (!canCompany(ctx, user.id, "materials.read")) return { ok: false as const, status: 403, ctx: null };
  return { ok: true as const, status: 200, ctx };
}

export async function GET() {
  const auth = await getAuth();
  if (!auth.ok || !auth.ctx) {
    return NextResponse.json({ error: auth.status === 401 ? "Não autenticado." : "Sem permissão." }, { status: auth.status });
  }

  const admin = createAdminClient();
  const companyId = auth.ctx.companyId;

  const { data: vinculos, error } = await admin
    .from("supplier_materials")
    .select("id,supplier_id,linked_material_id,name,sku,unit,purchase_unit,last_unit_price,last_purchase_at,lead_time_days,preferred")
    .eq("company_id", companyId)
    .not("linked_material_id", "is", null)
    .is("deleted_at", null);

  if (error) {
    return NextResponse.json({ error: "Falha ao carregar os fornecedores dos insumos." }, { status: 500 });
  }

  const idsDeFornecedor = Array.from(
    new Set((vinculos ?? []).map((v) => (typeof v.supplier_id === "string" ? v.supplier_id : "")).filter(Boolean))
  );

  const nomePorFornecedor = new Map<string, { name: string; status: string; phone: string; email: string }>();
  if (idsDeFornecedor.length > 0) {
    const { data: fornecedores } = await admin
      .from("suppliers")
      .select("id,name,status,phone,email")
      .eq("company_id", companyId)
      .in("id", idsDeFornecedor)
      .is("deleted_at", null);

    for (const f of fornecedores ?? []) {
      nomePorFornecedor.set(String(f.id), {
        name: String(f.name || ""),
        status: String(f.status || "ativo"),
        phone: String(f.phone || ""),
        email: String(f.email || ""),
      });
    }
  }

  /* Agrupado por insumo, do mais barato para o mais caro. Quem nunca teve
     compra registrada (preco zero) fica no fim: preco zero nao e o mais
     barato, e "ainda nao sei". */
  const porInsumo: Record<string, Array<Record<string, unknown>>> = {};

  for (const vinculo of vinculos ?? []) {
    const insumoId = String(vinculo.linked_material_id);
    const fornecedor = nomePorFornecedor.get(String(vinculo.supplier_id));
    /* Fornecedor removido deixa o vinculo orfao: nao mostra. */
    if (!fornecedor) continue;

    if (!porInsumo[insumoId]) porInsumo[insumoId] = [];
    porInsumo[insumoId].push({
      id: String(vinculo.id),
      supplierId: String(vinculo.supplier_id),
      supplierName: fornecedor.name,
      supplierStatus: fornecedor.status,
      supplierPhone: fornecedor.phone,
      supplierEmail: fornecedor.email,
      itemName: String(vinculo.name || ""),
      sku: vinculo.sku ?? null,
      unit: String(vinculo.unit || "un"),
      purchaseUnit: vinculo.purchase_unit ?? null,
      lastUnitPrice: Number(vinculo.last_unit_price || 0),
      lastPurchaseAt: vinculo.last_purchase_at ?? null,
      leadTimeDays: vinculo.lead_time_days ?? null,
      preferred: vinculo.preferred === true,
    });
  }

  for (const lista of Object.values(porInsumo)) {
    lista.sort((a, b) => {
      const pa = Number(a.lastUnitPrice || 0);
      const pb = Number(b.lastUnitPrice || 0);
      if (pa > 0 && pb > 0) return pa - pb;
      if (pa > 0) return -1;
      if (pb > 0) return 1;
      return String(a.supplierName).localeCompare(String(b.supplierName));
    });
  }

  return NextResponse.json({ ok: true, porInsumo });
}
