import { NextResponse } from "next/server";
import { createAdminClient } from "@/lib/supabase-admin";
import { validateBrazilianDocument } from "@/lib/document-utils";
import { getMercadoPagoIntegration, resolveMercadoPagoPublicConfig } from "@/lib/mercado-pago";
import {
  getMissingGuestFields,
  mapPaymentLinkRecord,
  normalizeGuestProfile,
  normalizeText,
  type PaymentLinkRecord,
} from "@/lib/payment-links";

type CheckoutBody = {
  code?: string;
  profile?: Record<string, unknown> | null;
  additionalData?: Record<string, unknown> | null;
};

export async function POST(request: Request) {
  try {
    const body = (await request.json().catch(() => null)) as CheckoutBody | null;
    const code = normalizeText(body?.code).toUpperCase();
    const profile = normalizeGuestProfile(body?.profile || null);

    if (!code) {
      return NextResponse.json({ error: "Link de pagamento invalido." }, { status: 400 });
    }

    const missingFields = getMissingGuestFields(profile);
    if (missingFields.length > 0) {
      return NextResponse.json(
        { error: `Preencha os dados obrigatorios: ${missingFields.join(", ")}.` },
        { status: 400 }
      );
    }

    if (!validateBrazilianDocument(profile.document)) {
      return NextResponse.json({ error: "Informe um CPF ou CNPJ valido." }, { status: 400 });
    }

    const admin = createAdminClient();
    const { data: rawLink, error: linkError } = await admin
      .from("payment_links")
      .select("*")
      .eq("code", code)
      .maybeSingle();

    if (linkError || !rawLink) {
      return NextResponse.json({ error: "Link de pagamento nao encontrado." }, { status: 404 });
    }

    const link = mapPaymentLinkRecord(rawLink as PaymentLinkRecord);
    const additionalData =
      body?.additionalData && typeof body.additionalData === "object" && !Array.isArray(body.additionalData)
        ? (body.additionalData as Record<string, unknown>)
        : {};

    if (link.type !== "one_time") {
      return NextResponse.json({ error: "Este link utiliza o fluxo de assinatura." }, { status: 400 });
    }
    if (link.status !== "active") {
      return NextResponse.json({ error: "Este link nao esta disponivel para pagamento no momento." }, { status: 400 });
    }
    if (link.expiresAt && new Date(link.expiresAt).getTime() <= Date.now()) {
      return NextResponse.json({ error: "Este link expirou." }, { status: 400 });
    }

    const integration = await getMercadoPagoIntegration(admin as never, link.userId).catch(() => null);
    const mercadoPagoConfig = resolveMercadoPagoPublicConfig(integration || null);
    if (!mercadoPagoConfig) {
      return NextResponse.json({ error: "A loja nao possui checkout configurado para este link." }, { status: 400 });
    }

    const now = new Date().toISOString();
    const externalReference = `payment_link:${link.id}:session:${crypto.randomUUID()}`;
    const forwardedFor = normalizeText(request.headers.get("x-forwarded-for") || "");
    const ip = normalizeText(forwardedFor.split(",")[0]) || normalizeText(request.headers.get("x-real-ip") || "") || null;
    const userAgent = normalizeText(request.headers.get("user-agent") || "") || null;
    const { data: payment, error: paymentError } = await admin
      .from("payment_link_payments")
      .insert({
        payment_link_id: link.id,
        user_id: link.userId,
        provider: "mercado_pago",
        status: "initiated",
        external_reference: externalReference,
        checkout_environment: mercadoPagoConfig.environment,
        amount: link.amount,
        currency: link.currency,
        description: link.description || link.title,
        payer_name: profile.name,
        payer_email: profile.email,
        payer_document: profile.document,
        metadata: {
          slug: link.slug,
          payment_link_code: link.code,
          payment_link_title: link.title,
        },
        raw_request: {
          client_profile: profile,
          consent: {
            accepted_at: now,
            ip,
            user_agent: userAgent,
            additionalData,
          },
        },
        created_at: now,
        updated_at: now,
      })
      .select("id")
      .single();

    if (paymentError || !payment?.id) {
      throw new Error(paymentError?.message || "Nao foi possivel iniciar o recebimento deste link.");
    }

    await admin
      .from("payment_links")
      .update({ last_opened_at: now, updated_at: now })
      .eq("id", link.id);

    return NextResponse.json({
      ok: true,
      flow: "mercado_pago",
      payment_id: payment.id,
      payment: {
        provider: "mercado_pago",
        environment: mercadoPagoConfig.environment,
        public_key: mercadoPagoConfig.publicKey,
        amount: link.amount,
        payer: {
          name: profile.name,
          email: profile.email,
          document: profile.document,
        },
      },
    });
  } catch (error) {
    const message = error instanceof Error ? error.message : "Nao foi possivel iniciar o pagamento do link.";
    return NextResponse.json({ error: message }, { status: 500 });
  }
}
