import { NextResponse } from "next/server";
import { createClient } from "@/lib/supabase-server";
import { canCompany, getCompanyContext } from "@/lib/company-context";
import { cancelarNotasDaVenda } from "@/lib/fiscal/servidor/travas";
import { ErroFiscal } from "@/lib/fiscal/servidor/notas";

export const runtime = "nodejs";

function isPdvOrder(order: { quote_title?: string | null; quote_internal_notes?: string | null; internal_notes?: string | null }) {
  const quoteTitle = String(order.quote_title || "").toLowerCase();
  const quoteInternalNotes = String(order.quote_internal_notes || "").toLowerCase();
  const orderInternalNotes = String(order.internal_notes || "").toLowerCase();
  return quoteTitle.includes("venda pdv") || quoteInternalNotes.includes("origem:pdv") || orderInternalNotes.includes("pdv");
}

export async function POST(req: Request) {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();
  if (!user) return NextResponse.json({ error: "Nao autenticado." }, { status: 401 });

  const ctx = await getCompanyContext(supabase, user);
  if (!canCompany(ctx, user.id, "orders.write")) {
    return NextResponse.json({ error: "Sem permissao para cancelar vendas." }, { status: 403 });
  }
  if (!canCompany(ctx, user.id, "financial.write")) {
    return NextResponse.json({ error: "Sem permissao financeira para estornar a venda." }, { status: 403 });
  }

  const body = (await req.json().catch(() => null)) as { order_id?: unknown } | null;
  const orderId = typeof body?.order_id === "string" ? body.order_id.trim() : "";
  if (!orderId) {
    return NextResponse.json({ error: "Campo 'order_id' e obrigatorio." }, { status: 400 });
  }

  const tenantIds = ctx.tenantIds?.length ? ctx.tenantIds : [user.id];

  const { data: rawOrder, error: orderError } = await supabase
    .from("orders")
    .select("id,user_id,status,number,internal_notes,quotes(title,internal_notes)")
    .eq("id", orderId)
    .in("user_id", tenantIds)
    .maybeSingle();

  if (orderError) return NextResponse.json({ error: orderError.message }, { status: 400 });
  if (!rawOrder) return NextResponse.json({ error: "Venda nao encontrada." }, { status: 404 });

  const quote = Array.isArray((rawOrder as { quotes?: unknown }).quotes)
    ? ((rawOrder as { quotes?: Array<{ title?: string | null; internal_notes?: string | null }> }).quotes?.[0] ?? null)
    : ((rawOrder as { quotes?: { title?: string | null; internal_notes?: string | null } | null }).quotes ?? null);

  const orderRow = rawOrder as { id: string; user_id: string; status: string; number?: number | null; internal_notes?: string | null };
  const pdvOrder = isPdvOrder({
    quote_title: quote?.title || null,
    quote_internal_notes: quote?.internal_notes || null,
    internal_notes: orderRow.internal_notes || null,
  });

  if (!pdvOrder) {
    return NextResponse.json({ error: "Este endpoint cancela somente vendas do PDV." }, { status: 400 });
  }

  if (orderRow.status === "canceled") {
    return NextResponse.json({ ok: true, already_canceled: true });
  }

  /* A NFC-e da venda é cancelada primeiro. Se a SEFAZ não aceitar (prazo,
     contingência), a venda fica como está: nota valendo com venda desfeita
     seria o pior dos dois mundos. */
  try {
    await cancelarNotasDaVenda({ empresaId: orderRow.user_id, pedidoId: orderRow.id, usuarioId: user.id });
  } catch (erro) {
    if (erro instanceof ErroFiscal) return NextResponse.json({ error: erro.message }, { status: erro.status });
    return NextResponse.json({ error: "Não foi possível conferir a nota fiscal da venda." }, { status: 500 });
  }

  const { data: paymentsData, error: paymentsError } = await supabase
    .from("payments")
    .select("id,amount,payment_method,payment_date,bank_account_id")
    .eq("order_id", orderId)
    .in("user_id", tenantIds)
    .order("created_at", { ascending: true });

  if (paymentsError) {
    return NextResponse.json({ error: "Falha ao buscar pagamentos para estorno.", details: paymentsError.message }, { status: 500 });
  }

  const paymentRows = (paymentsData || []) as Array<{
    id: string;
    amount: number | null;
    payment_method: string | null;
    payment_date: string | null;
    bank_account_id?: string | null;
  }>;

  const positivePayments = paymentRows.filter((payment) => Number(payment.amount || 0) > 0.0001);
  const reversedTotal = positivePayments.reduce((sum, payment) => sum + Math.abs(Number(payment.amount || 0)), 0);
  if (positivePayments.length > 0) {
    const paymentIds = positivePayments.map((payment) => payment.id);
    const { data: movementRows, error: movementFetchError } = await supabase
      .from("pdv_cash_movements")
      .select("id,session_id,movement_type,direction,amount,description,reference_payment_id,reference_order_id")
      .eq("company_id", ctx.companyId)
      .or(`reference_order_id.eq.${orderId},reference_payment_id.in.(${paymentIds.join(",")})`);

    if (movementFetchError) {
      return NextResponse.json({ error: "Falha ao buscar movimentos de caixa do PDV.", details: movementFetchError.message }, { status: 500 });
    }

    const { error: reversalError } = await supabase.rpc("reverse_pdv_order_payments_with_cleanup", {
      p_order_id: orderId,
    });

    if (reversalError) {
      return NextResponse.json(
        { error: "Falha ao estornar pagamentos da venda PDV.", details: reversalError.message },
        { status: 500 }
      );
    }

    const reversalMovements = ((movementRows || []) as Array<{
      session_id?: string | null;
      direction?: "IN" | "OUT" | null;
      amount?: number | null;
      description?: string | null;
      reference_payment_id?: string | null;
      reference_order_id?: string | null;
    }>)
      .filter((row) => row.session_id && Number(row.amount || 0) > 0.0001)
      .map((row) => ({
        session_id: String(row.session_id),
        company_id: ctx.companyId,
        movement_type: "close_adjustment" as const,
        direction: row.direction === "OUT" ? "IN" : "OUT",
        amount: Math.abs(Number(row.amount || 0)),
        description: `[PDV:REVERSAO] ${String(row.description || "Movimento operacional do PDV")} (${orderRow.number || "sem numero"})`,
        /* Sem `reference_payment_id`: os movimentos foram lidos antes de a
           reversao apagar os pagamentos, entao o id guardado aqui ja nao existe
           na tabela. A chave estrangeira recusava a insercao inteira, e o
           cancelamento terminava com os pagamentos revertidos e o caixa do PDV
           sem o contra-lancamento — a venda sumia, o dinheiro nao.
           O vinculo com o pedido e o que interessa para a auditoria, e esse
           sobrevive. */
        reference_payment_id: null,
        reference_order_id: row.reference_order_id || orderId,
        created_by: user.id,
      }));

    if (reversalMovements.length > 0) {
      const { error: movementReverseError } = await supabase.from("pdv_cash_movements").insert(reversalMovements);
      if (movementReverseError) {
        return NextResponse.json(
          { error: "Falha ao registrar a reversão operacional do caixa PDV.", details: movementReverseError.message },
          { status: 500 }
        );
      }
    }
  }

  const nowIso = new Date().toISOString();
  const internalNotes = [orderRow.internal_notes || "", "Cancelamento PDV com estorno financeiro automático."]
    .filter(Boolean)
    .join("\n");

  const { error: cancelError } = await supabase
    .from("orders")
    .update({
      status: "canceled",
      updated_at: nowIso,
      internal_notes: internalNotes,
    })
    .eq("id", orderId)
    .eq("user_id", orderRow.user_id);

  if (cancelError) {
    return NextResponse.json({ error: "Falha ao cancelar venda PDV.", details: cancelError.message }, { status: 500 });
  }

  await supabase.from("order_history").insert({
    order_id: orderId,
    user_id: user.id,
    status_from: orderRow.status || null,
    status_to: "canceled",
    notes:
      positivePayments.length > 0
        ? `Venda PDV cancelada com estorno financeiro automático (${positivePayments.length} pagamento(s) revertido(s), total ${reversedTotal.toFixed(2)}).`
        : "Venda PDV cancelada sem pagamentos para estorno.",
  });

  return NextResponse.json({
    ok: true,
    order_id: orderId,
    order_number: orderRow.number || null,
    reversed_payments: positivePayments.length,
  });
}
