/**
 * Organization Seats Purchase API
 * POST - Create a Stripe checkout session for purchasing additional seats
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { stripe } from "@/lib/stripe";
import { logger } from "@/lib/logger";
import { CONVEX_PATHS } from "@/lib/convex-paths";
import { ADDITIONAL_SEAT_PRICE_ANNUAL_GBP } from "@/lib/types/organization.types";
import { convexMutation, convexQuery } from "@/lib/convex-client";
import { getAuthenticatedConvexUser } from "@/lib/convex-auth-state";
import { purchaseSeatsSchema } from "@/lib/validators/api-schemas";

const SEAT_PRICE_PENCE = ADDITIONAL_SEAT_PRICE_ANNUAL_GBP * 100;

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

    const body = await request.json();
    const parsed = purchaseSeatsSchema.safeParse(body);

    if (!parsed.success) {
      return NextResponse.json(
        {
          success: false,
          error: parsed.error.errors.map(e => e.message).join(", "),
        },
        { status: 400 },
      );
    }

    const { quantity } = parsed.data;

    const orgState = await convexQuery<{
      organization: {
        id: string;
        prismaId?: string | null;
        stripeCustomerId?: string | null;
      };
      userRole: string;
    }>("organizations/queries:getOrganizationStateByUserId", {
      userId: user.id,
    });

    if (!orgState || orgState.userRole !== "OWNER") {
      return NextResponse.json(
        {
          success: false,
          error: "Only organization owners can purchase seats",
        },
        { status: 403 },
      );
    }

    let stripeCustomerId =
      user.stripeCustomerId || orgState.organization.stripeCustomerId || null;

    if (!stripeCustomerId) {
      const customer = await stripe.customers.create({
        email: user.email,
        name: user.name || undefined,
        metadata: {
          userId: user.id,
          organizationId:
            orgState.organization.prismaId || orgState.organization.id,
        },
      });
      stripeCustomerId = customer.id;

      await convexMutation("auth/mutations:updateUserNoAuth", {
        userId: user.id,
        stripeCustomerId,
      });
      await convexMutation(CONVEX_PATHS.updateOrganizationNoAuth, {
        organizationId: orgState.organization.id,
        stripeCustomerId,
      });
    }

    const totalAmount = quantity * SEAT_PRICE_PENCE;

    const session = await stripe.checkout.sessions.create({
      customer: stripeCustomerId,
      mode: "payment",
      payment_method_types: ["card"],
      line_items: [
        {
          price_data: {
            currency: "gbp",
            product_data: {
              name: `Additional Team Seats (${quantity} ${quantity === 1 ? "seat" : "seats"})`,
              description: `Annual subscription for ${quantity} additional team member ${quantity === 1 ? "seat" : "seats"}`,
              metadata: {
                type: "additional_seats",
                quantity: quantity.toString(),
              },
            },
            unit_amount: SEAT_PRICE_PENCE,
          },
          quantity,
        },
      ],
      metadata: {
        type: "seat_purchase",
        userId: user.id,
        organizationId: orgState.organization.id,
        quantity: quantity.toString(),
      },
      success_url: `${process.env.NEXT_PUBLIC_APP_URL}/en/dashboard?tab=team&seats_purchased=success&quantity=${quantity}`,
      cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/en/dashboard?tab=team&seats_purchased=cancelled`,
      allow_promotion_codes: true,
    });

    logger.info("[Seat Purchase] Checkout session created", {
      sessionId: session.id,
      userId: user.id,
      organizationId: orgState.organization.id,
      quantity,
      totalAmount,
    });

    return NextResponse.json({
      success: true,
      url: session.url,
      sessionId: session.id,
    });
  } catch (error: unknown) {
    logger.error(
      "[Seat Purchase] Failed to create checkout session",
      error instanceof Error ? error : new Error(String(error)),
    );

    return NextResponse.json(
      { success: false, error: "Failed to create checkout session" },
      { status: 500 },
    );
  }
}
