import { NextResponse } from "next/server";
import { abrirEstoque, exigirV2, produtoDaEmpresa, respostaDoErro, textoOuNulo, numeroOuNulo, UUID } from "@/lib/estoque/servidor";
import { lerCelulas } from "@/lib/estoque/leituras.server";

/*
 * Registrar produção: sai a composição × quantidade e entra no item pronto da
 * combinação (estoque_registrar_producao). DELETE ?id= desfaz
 * (estoque_desfazer_producao). GET ?id= mostra uma produção; GET ?item= as
 * últimas produções que entraram num item pronto.
 */

export async function GET(req: Request) {
  const r = await abrirEstoque(["products.stock.read", "materials.read"]);
  if (!r.ok) return r.resposta;
  const falta = exigirV2(r.e);
  if (falta) return falta;
  const url = new URL(req.url);
  const id = url.searchParams.get("id");
  const item = url.searchParams.get("item");

  let q = r.e.admin
    .from("estoque_producoes")
    .select("id,produto_id,item_id,celula_id,selected_options,quantidade,custo_unitario,observacao,criado_em,desfeita_em,products(name)")
    .eq("empresa_id", r.e.dono)
    .order("criado_em", { ascending: false })
    .limit(30);
  if (id && UUID.test(id)) q = q.eq("id", id);
  else if (item && UUID.test(item)) q = q.eq("item_id", item);
  const { data } = await q;
  const producoes = (data as unknown as Array<Record<string, unknown> & { id: string; celula_id: string; products: { name: string } | null }> | null) ?? [];

  /* Uma produção aberta: os movimentos dela (o que saiu e o que entrou). */
  if (id && producoes[0]) {
    const { data: movs } = await r.e.admin
      .from("estoque_movimentos")
      .select("id,celula_id,tipo,quantidade,estorno_de,criado_em")
      .eq("empresa_id", r.e.dono)
      .eq("producao_id", id)
      .order("criado_em");
    const lista = (movs as Array<{ id: string; celula_id: string; tipo: string; quantidade: number; estorno_de: string | null; criado_em: string }> | null) ?? [];
    const celulas = await lerCelulas(r.e, lista.map((m) => m.celula_id).concat(producoes[0].celula_id));
    return NextResponse.json({
      producao: { ...producoes[0], produto: producoes[0].products?.name ?? null, celula: celulas.get(producoes[0].celula_id) ?? null },
      movimentos: lista.map((m) => ({ ...m, quantidade: Number(m.quantidade), celula: celulas.get(m.celula_id) ?? null })),
    });
  }
  const celulas = await lerCelulas(r.e, producoes.map((p) => p.celula_id));
  return NextResponse.json({
    producoes: producoes.map((p) => ({ ...p, produto: p.products?.name ?? null, celula: celulas.get(p.celula_id) ?? null })),
  });
}

export async function POST(req: Request) {
  const r = await abrirEstoque("products.stock.write");
  if (!r.ok) return r.resposta;
  const falta = exigirV2(r.e);
  if (falta) return falta;
  const corpo = (await req.json().catch(() => null)) as Record<string, unknown> | null;
  const produto = await produtoDaEmpresa(r.e, String(corpo?.produto_id ?? ""));
  if (!produto) return NextResponse.json({ error: "Produto não encontrado." }, { status: 404 });
  const quantidade = numeroOuNulo(corpo?.quantidade);
  if (!quantidade || quantidade <= 0) return NextResponse.json({ error: "Informe quantas peças ficaram prontas." }, { status: 400 });
  const sel = corpo?.selected_options && typeof corpo.selected_options === "object" ? corpo.selected_options : { options: [] };

  const { data, error } = await r.e.supabase.rpc("estoque_registrar_producao", {
    p_produto: produto.id,
    p_selected_options: sel,
    p_quantidade: quantidade,
    p_observacao: textoOuNulo(corpo?.observacao, 400),
    p_largura: numeroOuNulo(corpo?.largura),
    p_altura: numeroOuNulo(corpo?.altura),
  });
  if (error) return respostaDoErro(error);
  return NextResponse.json(data);
}

export async function DELETE(req: Request) {
  const r = await abrirEstoque("products.stock.write");
  if (!r.ok) return r.resposta;
  const falta = exigirV2(r.e);
  if (falta) return falta;
  const id = new URL(req.url).searchParams.get("id");
  if (!id || !UUID.test(id)) return NextResponse.json({ error: "Produção não encontrada." }, { status: 404 });
  const { data: minha } = await r.e.admin.from("estoque_producoes").select("id").eq("id", id).eq("empresa_id", r.e.dono).maybeSingle();
  if (!minha) return NextResponse.json({ error: "Produção não encontrada." }, { status: 404 });
  const { data, error } = await r.e.supabase.rpc("estoque_desfazer_producao", { p_producao: id });
  if (error) return respostaDoErro(error);
  return NextResponse.json(data);
}
