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

export const dynamic = "force-dynamic";

async function resolveStripeCustomerId(
  userId: string,
  fallbackCustomerId?: string | null,
) {
  const directSubscription = await getActiveConvexSubscription(userId);
  if (directSubscription?.stripeCustomerId) {
    return directSubscription.stripeCustomerId;
  }

  const orgState = await convexQuery<{
    organization: { ownerId: string };
  }>("organizations/queries:getOrganizationStateByUserId", {
    userId,
  });

  if (
    orgState?.organization?.ownerId &&
    orgState.organization.ownerId !== userId
  ) {
    const ownerSubscription = await getActiveConvexSubscription(
      orgState.organization.ownerId,
    );
    if (ownerSubscription?.stripeCustomerId) {
      return ownerSubscription.stripeCustomerId;
    }
  }

  return fallbackCustomerId ?? null;
}

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

    const stripeCustomerId = await resolveStripeCustomerId(
      user.id,
      user.stripeCustomerId,
    );

    if (!stripeCustomerId) {
      return NextResponse.json(
        {
          error: "No billing account found. Please subscribe to a plan first.",
        },
        { status: 400 },
      );
    }

    let returnUrl = `${process.env.NEXT_PUBLIC_APP_URL || "http://localhost:9000"}/en/dashboard?tab=billing`;

    try {
      const body = await request.json();
      if (body.returnUrl) {
        returnUrl = body.returnUrl;
      }
    } catch {
      // Keep default return URL.
    }

    const portalSession = await stripe.billingPortal.sessions.create({
      customer: stripeCustomerId,
      return_url: returnUrl,
    });

    logger.info("Billing portal session created", {
      userId: user.id,
      customerId: stripeCustomerId,
    });

    return NextResponse.json({ url: portalSession.url });
  } catch (error) {
    logger.error("Failed to create billing portal session", {
      error: error instanceof Error ? error.message : "Unknown error",
    });

    return NextResponse.json(
      { error: "Failed to create billing portal session" },
      { status: 500 },
    );
  }
}
