/**
 * Rental Deposit Link API
 *
 * POST /api/dashboard/rentals/deposit-link
 *   Creates a Stripe checkout session for the deposit amount and
 *   sends the payment link to the customer via email.
 *
 * Requires the organization to have Stripe keys configured.
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { getAuthenticatedUser } from "@/lib/utils/auth-helpers.util";
import { logger } from "@/lib/logger";
import { validateCSRFToken } from "@/lib/csrf";
import { convexQuery } from "@/lib/convex-client";
import Stripe from "stripe";

const log = logger.scope("RentalDepositLinkAPI");

export const dynamic = "force-dynamic";

export async function POST(request: NextRequest) {
  try {
    if (!validateCSRFToken(request)) {
      return NextResponse.json(
        { success: false, error: "Invalid CSRF token" },
        { status: 403 },
      );
    }

    const user = await getAuthenticatedUser(request, auth);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const body = await request.json();
    const {
      rentalId,
      customerEmail,
      customerName,
      depositAmount,
      vehicleName,
      agreementNumber,
    } = body;

    if (!rentalId || !customerEmail || !depositAmount) {
      return NextResponse.json(
        {
          success: false,
          error: "rentalId, customerEmail, and depositAmount are required",
        },
        { status: 400 },
      );
    }

    // Get organization's Stripe keys from Convex
    const orgState = await convexQuery<Record<string, unknown>>(
      "organizations/queries:getOrganizationStateByUserId",
      { userId: user.userId },
    ).catch(() => null);

    if (!orgState?.organization) {
      return NextResponse.json(
        { success: false, error: "Organization not found" },
        { status: 404 },
      );
    }

    const org = orgState.organization as Record<string, unknown>;
    const stripeSecretKeyEncrypted = org.stripeSecretKeyEncrypted as
      | string
      | undefined;

    if (!stripeSecretKeyEncrypted) {
      return NextResponse.json(
        {
          success: false,
          error: "Stripe keys not configured. Go to Settings to set up Stripe.",
        },
        { status: 400 },
      );
    }

    // Decrypt the Stripe secret key
    let stripeSecretKey: string;
    try {
      const { decryptStripeKey } = await import(
        "@/lib/services/stripe-keys.service"
      );
      stripeSecretKey = decryptStripeKey(stripeSecretKeyEncrypted);
    } catch {
      return NextResponse.json(
        { success: false, error: "Failed to decrypt Stripe keys" },
        { status: 500 },
      );
    }

    // Create Stripe checkout session for the deposit
    const stripe = new Stripe(stripeSecretKey, {
      apiVersion: "2024-12-18.acacia",
    });

    const appUrl =
      process.env.NEXT_PUBLIC_APP_URL || "http://localhost:9000";

    const session = await stripe.checkout.sessions.create({
      payment_method_types: ["card"],
      mode: "payment",
      customer_email: customerEmail,
      line_items: [
        {
          price_data: {
            currency: "qar",
            product_data: {
              name: `Rental Deposit — ${vehicleName || "Vehicle"}`,
              description: agreementNumber
                ? `Agreement: ${agreementNumber}`
                : `Rental ID: ${rentalId}`,
            },
            unit_amount: Math.round(depositAmount * 100), // Convert to fils
          },
          quantity: 1,
        },
      ],
      metadata: {
        rentalId,
        type: "rental_deposit",
        agreementNumber: agreementNumber || "",
      },
      success_url: `${appUrl}/en/payment/success?type=deposit&rental=${rentalId}`,
      cancel_url: `${appUrl}/en/dashboard?tab=appointments`,
    });

    // Send email with the payment link
    try {
      const { sendEmail } = await import("@/lib/email");
      await sendEmail({
        to: customerEmail,
        subject: agreementNumber
          ? `Deposit Payment — Agreement ${agreementNumber}`
          : `Deposit Payment — ${vehicleName || "Vehicle Rental"}`,
        html: `
          <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">
            <h2 style="color: #1a1a1a;">Rental Deposit Payment</h2>
            <p>Dear ${customerName || "Customer"},</p>
            <p>Please complete your deposit payment for the following rental:</p>
            <table style="width: 100%; border-collapse: collapse; margin: 16px 0;">
              <tr>
                <td style="padding: 8px; border-bottom: 1px solid #eee; color: #666;">Vehicle</td>
                <td style="padding: 8px; border-bottom: 1px solid #eee; font-weight: bold;">${vehicleName || "N/A"}</td>
              </tr>
              ${agreementNumber ? `<tr><td style="padding: 8px; border-bottom: 1px solid #eee; color: #666;">Agreement</td><td style="padding: 8px; border-bottom: 1px solid #eee; font-weight: bold;">${agreementNumber}</td></tr>` : ""}
              <tr>
                <td style="padding: 8px; border-bottom: 1px solid #eee; color: #666;">Deposit Amount</td>
                <td style="padding: 8px; border-bottom: 1px solid #eee; font-weight: bold;">QAR ${depositAmount.toFixed(2)}</td>
              </tr>
            </table>
            <a href="${session.url}" style="display: inline-block; background-color: #16a34a; color: white; padding: 12px 24px; text-decoration: none; border-radius: 8px; font-weight: bold; margin: 16px 0;">
              Pay Deposit Now
            </a>
            <p style="color: #666; font-size: 14px; margin-top: 24px;">
              This link will expire in 24 hours. If you have questions, please contact us.
            </p>
          </div>
        `,
      });
    } catch (emailErr) {
      log.warn("Failed to send deposit email, but checkout session created", emailErr);
    }

    log.info("Deposit link created", {
      rentalId,
      customerEmail,
      sessionId: session.id,
    });

    return NextResponse.json({
      success: true,
      checkoutUrl: session.url,
      sessionId: session.id,
    });
  } catch (error) {
    log.error("Failed to create deposit link", error);
    return NextResponse.json(
      { success: false, error: "Failed to create deposit link" },
      { status: 500 },
    );
  }
}
