import { auth } from "@/lib/auth";
import { cancelSubscription } from "@/lib/stripe";
import { NextRequest, NextResponse } from "next/server";
import { getAuthenticatedUser } from "@/lib/utils/auth-helpers.util";
import { applyRateLimit, rateLimiters } from "@/lib/rate-limiter";
import { validateCSRFToken, withCSRF } from "@/lib/csrf";
import { getIPFromRequest } from "@/lib/geolocation";
import { logger } from "@/lib/logger";
import { CONVEX_PATHS } from "@/lib/convex-paths";
import { convexMutation, convexQuery } from "@/lib/convex-client";

export const DELETE = withCSRF(async (request: NextRequest) => {
  let authUser: Awaited<ReturnType<typeof getAuthenticatedUser>> | null = null;

  try {
    authUser = await getAuthenticatedUser(request, auth);

    if (!authUser?.userId) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const rateLimitResponse = await applyRateLimit(
      request,
      rateLimiters.authGeneral,
    );
    if (rateLimitResponse) {
      return rateLimitResponse;
    }

    if (!validateCSRFToken(request)) {
      return NextResponse.json(
        { error: "Invalid CSRF token" },
        { status: 403 },
      );
    }

    const userId = authUser.userId;

    const activeSubscription = await convexQuery<Record<string, unknown>>(
      "billing/queries:getActiveSubscription",
      { userId },
    );

    const cancelledSubscriptions: string[] = [];
    const failedSubscriptions: string[] = [];

    if (activeSubscription?.stripeSubscriptionId) {
      try {
        await cancelSubscription(
          String(activeSubscription.stripeSubscriptionId),
        );
        cancelledSubscriptions.push(
          String(activeSubscription.stripeSubscriptionId),
        );
      } catch (stripeError) {
        failedSubscriptions.push(
          String(activeSubscription.stripeSubscriptionId),
        );
        logger.error(
          "Failed to cancel Stripe subscription",
          stripeError instanceof Error
            ? stripeError
            : new Error(String(stripeError)),
          {
            subscriptionId: activeSubscription.stripeSubscriptionId,
          },
        );
      }
    }

    const ipAddress = getIPFromRequest(request);

    await convexMutation(CONVEX_PATHS.deleteUserNoAuth, {
      userId,
    });

    await convexMutation("auth/mutations:createAuditLog", {
      type: "account",
      action: "account_deleted",
      success: true,
      ip: ipAddress,
      userAgent: request.headers.get("user-agent") || "",
      metadata: {
        deletedUserId: userId,
        cancelledSubscriptions,
        failedSubscriptions,
      },
    });

    return NextResponse.json({
      success: true,
      message: "Account deleted successfully",
    });
  } catch (error) {
    logger.error(
      "Delete account error",
      error instanceof Error ? error : new Error(String(error)),
    );
    const ipAddress = getIPFromRequest(request);

    if (authUser?.userId) {
      try {
        await convexMutation("auth/mutations:createAuditLog", {
          userId: authUser.userId,
          type: "account",
          action: "account_delete_failed",
          success: false,
          ip: ipAddress,
          userAgent: request.headers.get("user-agent") || "",
          metadata: {
            error: error instanceof Error ? error.message : "Unknown error",
          },
        });
      } catch (auditError) {
        logger.error(
          "Failed to log account deletion failure",
          auditError instanceof Error
            ? auditError
            : new Error(String(auditError)),
        );
      }
    }

    return NextResponse.json(
      { error: "Failed to delete account" },
      { status: 500 },
    );
  }
});
