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

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

type MercadoPagoSubscriptionResponse = Record<string, unknown> & {
  id?: unknown;
  status?: unknown;
  init_point?: unknown;
};

function resolveFrequency(link: ReturnType<typeof mapPaymentLinkRecord>) {
  if (!link.intervalCount || !link.intervalUnit) {
    return { frequency: 1, frequencyType: "months" as const };
  }
  if (link.intervalUnit === "years") {
    return { frequency: Math.max(1, link.intervalCount * 12), frequencyType: "months" as const };
  }
  if (link.intervalUnit === "days") {
    return { frequency: Math.max(1, link.intervalCount), frequencyType: "days" as const };
  }
  return { frequency: Math.max(1, link.intervalCount), frequencyType: "months" as const };
}

export async function POST(request: Request) {
  try {
    const body = (await request.json().catch(() => null)) as SubscriptionBody | null;
    const code = normalizeText(body?.code).toUpperCase();
    const profile = normalizeGuestProfile(body?.profile || null);
    const formData = body?.formData && typeof body.formData === "object" ? body.formData : {};

    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 cardToken = normalizeText(formData.token);
    if (!cardToken) {
      return NextResponse.json({ error: "Nao foi possivel capturar o cartao para a assinatura." }, { 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 assinatura nao encontrado." }, { status: 404 });
    }

    const link = mapPaymentLinkRecord(rawLink as PaymentLinkRecord);
    if (link.type !== "subscription") {
      return NextResponse.json({ error: "Este link nao e uma assinatura." }, { status: 400 });
    }
    if (link.status !== "active") {
      return NextResponse.json({ error: "Esta assinatura nao esta disponivel 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);
    if (!integration || integration.active === false) {
      return NextResponse.json({ error: "A loja nao possui Mercado Pago configurado." }, { status: 400 });
    }

    const settings = parseMercadoPagoSettings(integration.settings);
    const credentials = getActiveMercadoPagoCredentials(settings);
    if (!credentials) {
      return NextResponse.json({ error: "As credenciais do Mercado Pago desta loja estao incompletas." }, { status: 400 });
    }

    const { frequency, frequencyType } = resolveFrequency(link);
    const externalReference = `payment_link:${link.id}:subscription:${crypto.randomUUID()}`;
    const now = new Date().toISOString();
    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: localSubscription, error: localSubscriptionError } = await admin
      .from("payment_link_subscriptions")
      .insert({
        payment_link_id: link.id,
        user_id: link.userId,
        provider: "mercado_pago",
        external_reference: externalReference,
        status: "pending",
        checkout_environment: credentials.environment,
        amount: link.amount,
        currency: link.currency,
        frequency,
        frequency_type: frequencyType,
        payer_name: profile.name,
        payer_email: profile.email,
        payer_document: profile.document,
        metadata: {
          payment_link_code: link.code,
          additionalData: body?.additionalData || null,
        },
        raw_request: {
          formData,
          consent: {
            accepted_at: now,
            ip,
            user_agent: userAgent,
            additionalData: body?.additionalData || null,
          },
        },
        created_at: now,
        updated_at: now,
      })
      .select("id")
      .single();

    if (localSubscriptionError || !localSubscription?.id) {
      return NextResponse.json({ error: localSubscriptionError?.message || "Nao foi possivel iniciar a assinatura." }, { status: 500 });
    }

    const requestPayload = {
      reason: link.title,
      external_reference: externalReference,
      payer_email: profile.email,
      card_token_id: cardToken,
      auto_recurring: {
        frequency,
        frequency_type: frequencyType,
        transaction_amount: link.amount,
        currency_id: link.currency,
      },
      status: "authorized",
    };

    const mercadoPagoSubscription = await fetchMercadoPagoApi<MercadoPagoSubscriptionResponse>(
      "/preapproval",
      credentials.accessToken,
      {
        method: "POST",
        body: JSON.stringify(requestPayload),
        idempotencyKey: externalReference,
      }
    );

    const normalizedStatus = normalizeMercadoPagoSubscriptionStatus(mercadoPagoSubscription.status);
    const startedAt = normalizedStatus === "authorized" ? new Date().toISOString() : null;

    await admin
      .from("payment_link_subscriptions")
      .update({
        subscription_id: normalizeText(mercadoPagoSubscription.id) || null,
        status: normalizedStatus,
        init_point: normalizeText(mercadoPagoSubscription.init_point) || null,
        started_at: startedAt,
        raw_response: mercadoPagoSubscription,
        updated_at: new Date().toISOString(),
      })
      .eq("id", localSubscription.id);

    if (normalizedStatus === "authorized") {
      await admin
        .from("payment_links")
        .update({ last_paid_at: new Date().toISOString(), updated_at: new Date().toISOString() })
        .eq("id", link.id);
    }

    return NextResponse.json({
      ok: true,
      subscription_id: normalizeText(mercadoPagoSubscription.id) || null,
      status: normalizedStatus,
      init_point: normalizeText(mercadoPagoSubscription.init_point) || null,
      recurrence_label:
        frequencyType === "days"
          ? frequency === 1
            ? "Cobranca diaria"
            : `Cobranca a cada ${frequency} dias`
          : frequency === 1
            ? "Cobranca mensal"
            : `Cobranca a cada ${frequency} meses`,
    });
  } catch (error) {
    const message = error instanceof Error ? error.message : "Nao foi possivel criar a assinatura.";
    return NextResponse.json({ error: message }, { status: 500 });
  }
}
