import { NextResponse } from "next/server";
import { createClient } from "@/lib/supabase-server";
import { canManageFinancialCritical, getCompanyContext } from "@/lib/company-context";
import {
  getBankAccountDependencies,
  getBankAccountSnapshot,
  logBankAccountAuditEvent,
} from "@/lib/bank-account-admin";

export const runtime = "nodejs";

function normalizeIsoDate(value: unknown) {
  if (typeof value !== "string") return null;
  const trimmed = value.trim();
  if (!/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) return null;
  return trimmed;
}

export async function POST(req: Request, ctxArg: { params: Promise<{ id: string }> }) {
  const supabase = await createClient();
  const {
    data: { user },
    error: userError,
  } = await supabase.auth.getUser();

  if (userError || !user) {
    return NextResponse.json({ error: "Não autenticado." }, { status: 401 });
  }

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

  const { id } = await ctxArg.params;
  if (!id) {
    return NextResponse.json({ error: "Conta bancária inválida." }, { status: 400 });
  }

  const body = (await req.json().catch(() => null)) as
    | {
        target_balance?: unknown;
        date?: unknown;
        reason?: unknown;
      }
    | null;

  const targetBalance =
    typeof body?.target_balance === "number" ? body.target_balance : Number(body?.target_balance);
  const date = normalizeIsoDate(body?.date) || new Date().toISOString().slice(0, 10);
  const reason = typeof body?.reason === "string" ? body.reason.trim() : "";

  if (!Number.isFinite(targetBalance)) {
    return NextResponse.json({ error: "Saldo alvo inválido." }, { status: 400 });
  }
  if (!reason) {
    return NextResponse.json({ error: "Informe o motivo do ajuste." }, { status: 400 });
  }

  const before = await getBankAccountSnapshot(supabase, ctx.companyId, id);
  if (!before) {
    return NextResponse.json({ error: "Conta bancária não encontrada." }, { status: 404 });
  }

  const dependencies = await getBankAccountDependencies(
    ctx.companyId,
    id,
    ctx.tenantIds?.length ? ctx.tenantIds : [user.id]
  );
  if (dependencies.open_pdv_cash_sessions > 0) {
    return NextResponse.json(
      { error: "Não é possível ajustar saldo com um caixa PDV aberto nesta conta." },
      { status: 409 }
    );
  }

  const delta = Number((targetBalance - before.current_balance).toFixed(2));
  if (Math.abs(delta) < 0.005) {
    return NextResponse.json({ error: "O saldo informado já corresponde ao saldo atual." }, { status: 400 });
  }

  const type = delta > 0 ? "IN" : "OUT";
  const amount = Math.abs(delta);
  const description = `[SALDO:AJUSTE] Ajuste administrativo de saldo • ${reason}`;

  const { error: insertError } = await supabase.from("cash_flow").insert({
    company_id: ctx.companyId,
    bank_account_id: id,
    type,
    origin: "AJUSTE",
    reference_id: null,
    description,
    amount,
    date,
  });

  if (insertError) {
    return NextResponse.json(
      { error: "Falha ao registrar o ajuste auditável.", message: insertError.message },
      { status: 500 }
    );
  }

  const after = await getBankAccountSnapshot(supabase, ctx.companyId, id);
  await logBankAccountAuditEvent({
    companyId: ctx.companyId,
    bankAccountId: id,
    userId: user.id,
    eventType: "BALANCE_ADJUSTMENT",
    reason,
    beforeState: before,
    afterState: after,
    metadata: {
      date,
      previous_balance: before.current_balance,
      target_balance: targetBalance,
      delta,
      cash_flow_type: type,
      amount,
    },
  });

  return NextResponse.json({
    ok: true,
    adjustment: {
      previous_balance: before.current_balance,
      target_balance: targetBalance,
      delta,
      date,
      type,
      amount,
    },
    account: after,
  });
}
