import { NextRequest, NextResponse } from "next/server";
import { upgradeSubscription } from "@/lib/stripe-subscription-billing";
import { logger } from "@/lib/logger";
import { auth } from "@/lib/auth";
import { getAuthenticatedConvexUser } from "@/lib/convex-auth-state";
import { convexQuery } from "@/lib/convex-client";
import { getActiveConvexSubscription } from "@/lib/convex-billing-state";

/**
 * POST /api/subscription/upgrade
 *
 * Upgrades a user's subscription to a higher tier with immediate proration
 *
 * Request body:
 * {
 *   subscriptionId: string,
 *   newTierId: "tier1" | "tier2" | "tier3" | "tier4" | "tier5",
 *   billingPeriod: "monthly" | "yearly",
 *   currency: "qar" | "aed" | "sar" | "gbp" | "usd"
 * }
 *
 * Response:
 * {
 *   success: true,
 *   prorationAmount: number (in cents),
 *   newTierId: string,
 *   trialEndsAt?: Date,
 *   invoiceId?: string
 * }
 */

interface UpgradeRequestBody {
  subscriptionId: string;
  newTierId: string;
  billingPeriod: "monthly" | "yearly";
  currency: string;
}

export async function POST(request: NextRequest) {
  try {
    const user = await getAuthenticatedConvexUser(request, auth);
    if (!user) {
      logger.warn("Unauthorized upgrade attempt");
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    // Parse request body
    const body = (await request.json()) as UpgradeRequestBody;

    // Input validation
    const validationErrors = validateUpgradeInput(body);
    if (validationErrors.length > 0) {
      logger.warn("Upgrade validation failed", {
        errors: validationErrors,
        userEmail: user.email,
      });
      return NextResponse.json(
        { error: "Invalid request", details: validationErrors },
        { status: 400 },
      );
    }

    const { subscriptionId, newTierId, billingPeriod, currency } = body;

    const directSubscription = await getActiveConvexSubscription(user.id);
    const orgState = directSubscription
      ? null
      : await convexQuery<{ organization: { ownerId: string } }>(
          "organizations/queries:getOrganizationStateByUserId",
          { userId: user.id },
        );
    const sub =
      directSubscription ??
      (orgState?.organization?.ownerId &&
      orgState.organization.ownerId !== user.id
        ? await getActiveConvexSubscription(orgState.organization.ownerId)
        : null);

    if (!sub) {
      logger.warn("Subscription not found or unauthorized", {
        subscriptionId,
        userEmail: user.email,
      });
      return NextResponse.json(
        { error: "Subscription not found" },
        { status: 404 },
      );
    }

    const knownIds = [
      sub._id as string,
      sub.prismaId as string | undefined,
      sub.stripeSubscriptionId as string | undefined,
    ].filter(Boolean);

    if (!knownIds.includes(subscriptionId)) {
      return NextResponse.json(
        { error: "Subscription not found" },
        { status: 404 },
      );
    }

    const tierOrder = ["tier1", "tier2", "tier3", "tier4", "tier5"];
    const currentTierIndex = tierOrder.indexOf(sub.tierId as string);
    const newTierIndex = tierOrder.indexOf(newTierId);

    if (newTierIndex <= currentTierIndex) {
      logger.warn("Attempted downgrade or same-tier change", {
        currentTier: sub.tierId,
        newTier: newTierId,
        userEmail: user.email,
      });
      return NextResponse.json(
        {
          error: "Invalid upgrade",
          message:
            "Can only upgrade to higher tiers. For downgrades, please contact support.",
        },
        { status: 400 },
      );
    }

    logger.info("Starting subscription upgrade", {
      subscriptionId,
      currentTier: sub.tierId,
      newTier: newTierId,
      userId: user.id,
    });

    const result = await upgradeSubscription({
      subscriptionId: sub._id as string,
      newTierId,
      currency,
      billingPeriod,
      language: "ar",
    });

    logger.info("Subscription upgraded successfully", {
      subscriptionId: sub.stripeSubscriptionId,
      newTierId,
      prorationAmount: result.prorationAmount,
      userId: user.id,
    });

    return NextResponse.json({
      success: true,
      prorationAmount: result.prorationAmount,
      newTierId: result.newTierId,
      trialEndsAt: result.trialEndsAt,
      invoiceId: result.invoiceId,
      metadata: result.metadata,
    });
  } catch (error) {
    logger.error("Upgrade route error", {
      error: error instanceof Error ? error.message : "Unknown error",
      stack: error instanceof Error ? error.stack : undefined,
    });

    return NextResponse.json(
      {
        error: "Failed to upgrade subscription",
        message: error instanceof Error ? error.message : "Unknown error",
      },
      { status: 500 },
    );
  }
}

/**
 * Validate upgrade request input
 */
function validateUpgradeInput(body: Partial<UpgradeRequestBody>): string[] {
  const errors: string[] = [];

  if (!body.subscriptionId) {
    errors.push("subscriptionId is required");
  } else if (typeof body.subscriptionId !== "string") {
    errors.push("subscriptionId must be a string");
  }

  if (!body.newTierId) {
    errors.push("newTierId is required");
  } else if (
    !["tier1", "tier2", "tier3", "tier4", "tier5"].includes(body.newTierId)
  ) {
    errors.push("newTierId must be tier1-tier5");
  }

  if (!body.billingPeriod) {
    errors.push("billingPeriod is required");
  } else if (!["monthly", "yearly"].includes(body.billingPeriod)) {
    errors.push("billingPeriod must be monthly or yearly");
  }

  if (!body.currency) {
    errors.push("currency is required");
  } else if (typeof body.currency !== "string" || body.currency.length !== 3) {
    errors.push("currency must be a 3-letter code (e.g., qar, aed, sar)");
  }

  return errors;
}
