/**
 * Booking Payment Link API
 * POST - Generate a Stripe payment link and optionally send it via email
 *
 * Uses company-specific Stripe keys if configured, otherwise returns an error
 * asking the company to configure their Stripe keys first.
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { prisma } from "@/lib/db";
import { getAuthenticatedEmail } from "@/lib/utils/auth-helpers.util";
import { getEffectiveOwnerId } from "@/lib/utils/organization-data";
import { logger } from "@/lib/logger";
import {
  getStripeClientForOrganization,
  hasOrganizationStripeKeys,
} from "@/lib/stripe";
import { sendEmail } from "@/lib/email";

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

interface RouteContext {
  params: Promise<{ id: string }>;
}

/**
 * POST /api/bookings/[id]/payment-link
 * Generate a payment link for the booking deposit and optionally email it
 */
export async function POST(request: NextRequest, context: RouteContext) {
  try {
    const { id: bookingId } = await context.params;

    // Authenticate user
    const userEmail = await getAuthenticatedEmail(request, auth);

    if (!userEmail) {
      logger.warn("Unauthorized payment link request");
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    // Get user
    const user = await prisma.users.findUnique({
      where: { email: userEmail },
      select: { id: true },
    });

    if (!user) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    // Get effective owner ID (for org members, this returns the org owner's ID)
    // This allows staff to send payment links for organization bookings
    const effectiveUserId = await getEffectiveOwnerId(user.id);

    // Get the booking
    const booking = await prisma.bookings.findUnique({
      where: { id: bookingId },
    });

    if (!booking) {
      return NextResponse.json(
        { success: false, error: "Booking not found" },
        { status: 404 },
      );
    }

    // Verify the booking belongs to this user or their organization
    if (booking.userId !== effectiveUserId) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 403 },
      );
    }

    // Check if already paid
    if (booking.depositPaid) {
      return NextResponse.json(
        { success: false, error: "Deposit has already been paid" },
        { status: 400 },
      );
    }

    // Parse request body
    const body = await request.json();
    const { sendEmail: shouldSendEmail = true, language = "en" } = body;

    // Determine the amount to charge
    const amount = booking.depositAmount || booking.totalAmount;

    if (!amount || amount <= 0) {
      return NextResponse.json(
        {
          success: false,
          error: "No payment amount specified for this booking",
        },
        { status: 400 },
      );
    }

    // Get organization for company-specific Stripe keys
    const organization = await prisma.organizations.findUnique({
      where: { ownerId: effectiveUserId },
      select: { id: true },
    });

    // Check if company has Stripe keys configured - REQUIRED for payment links
    if (!organization) {
      logger.warn("No organization found for user when creating payment link", {
        userId: user.id,
        effectiveUserId,
        bookingId,
      });
      return NextResponse.json(
        {
          success: false,
          error: "Organization not found",
          errorCode: "NO_ORGANIZATION",
          message: "Please set up your organization to send payment links.",
        },
        { status: 400 },
      );
    }

    const hasStripeKeys = await hasOrganizationStripeKeys(organization.id);

    if (!hasStripeKeys) {
      logger.warn(
        "Payment link requested but organization has no Stripe keys",
        {
          organizationId: organization.id,
          bookingId,
        },
      );
      return NextResponse.json(
        {
          success: false,
          error: "Stripe keys not configured",
          errorCode: "STRIPE_KEYS_NOT_CONFIGURED",
          message:
            language === "ar"
              ? "يرجى إضافة مفاتيح Stripe الخاصة بك في الإعدادات قبل إرسال روابط الدفع."
              : "Please configure your Stripe API keys in Settings before sending payment links.",
          settingsUrl: "/staff/dashboard/settings/stripe",
        },
        { status: 400 },
      );
    }

    // Get organization-specific Stripe client
    const {
      client: stripeClient,
      isCompanyKeys,
      mode: stripeMode,
    } = await getStripeClientForOrganization(organization.id);

    logger.info("Creating payment link with company Stripe keys", {
      organizationId: organization.id,
      isCompanyKeys,
      stripeMode,
      bookingId,
    });

    // Format appointment date for display
    const appointmentDate = new Date(booking.appointmentDate);
    const formattedDate = appointmentDate.toLocaleDateString(
      language === "ar" ? "ar-SA" : "en-US",
      {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
      },
    );

    // Create Stripe checkout session using company's Stripe keys
    const session = await stripeClient.checkout.sessions.create({
      customer_email: booking.customerEmail || undefined,
      line_items: [
        {
          price_data: {
            currency: "qar", // Qatar Riyal
            unit_amount: Math.round(amount * 100), // Convert to cents/halalas
            product_data: {
              name:
                language === "ar"
                  ? `عربون موعد - ${booking.service}`
                  : `Appointment Deposit - ${booking.service}`,
              description:
                language === "ar"
                  ? `${formattedDate} الساعة ${booking.appointmentTime}`
                  : `${formattedDate} at ${booking.appointmentTime}`,
            },
          },
          quantity: 1,
        },
      ],
      mode: "payment",
      metadata: {
        type: "booking_deposit",
        booking_id: booking.id,
        customer_name: booking.customerName,
        customer_email: booking.customerEmail || "",
        customer_phone: booking.customerPhone,
        service: booking.service,
        appointment_date: booking.appointmentDate.toISOString(),
        appointment_time: booking.appointmentTime,
        organization_id: organization.id,
      },
      success_url: `${APP_URL}/${language}/payment/success?booking_id=${booking.id}&session_id={CHECKOUT_SESSION_ID}`,
      cancel_url: `${APP_URL}/${language}/payment/cancelled?booking_id=${booking.id}`,
    });

    if (!session?.url) {
      logger.error("Failed to create Stripe checkout session", { bookingId });
      return NextResponse.json(
        { success: false, error: "Failed to create payment link" },
        { status: 500 },
      );
    }

    // Send email with payment link if requested and email is available
    let emailSent = false;
    if (shouldSendEmail && booking.customerEmail) {
      try {
        const isAr = language === "ar";

        const emailTemplate = createPaymentLinkEmail({
          customerName: booking.customerName,
          service: booking.service,
          appointmentDate: formattedDate,
          appointmentTime: booking.appointmentTime,
          amount: amount,
          currency: "QAR",
          paymentUrl: session.url,
          language: isAr ? "ar" : "en",
        });

        emailSent = await sendEmail(booking.customerEmail, emailTemplate);

        if (emailSent) {
          logger.info("Payment link email sent", {
            bookingId,
            customerEmail: booking.customerEmail,
          });
        }
      } catch (emailError) {
        logger.error("Failed to send payment link email", {
          bookingId,
          error:
            emailError instanceof Error ? emailError.message : "Unknown error",
        });
        // Don't fail the request if email fails - still return the payment link
      }
    }

    logger.info("Payment link created", {
      bookingId,
      sessionId: session.id,
      amount,
      emailSent,
      isCompanyKeys,
      stripeMode,
      organizationId: organization.id,
    });

    return NextResponse.json({
      success: true,
      paymentUrl: session.url,
      sessionId: session.id,
      emailSent,
      amount,
      currency: "QAR",
      stripeMode,
      isCompanyKeys,
    });
  } catch (error) {
    logger.error("Failed to create payment link", {
      error: error instanceof Error ? error.message : "Unknown error",
    });

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

/**
 * Create a professional payment link email template
 */
function createPaymentLinkEmail(params: {
  customerName: string;
  service: string;
  appointmentDate: string;
  appointmentTime: string;
  amount: number;
  currency: string;
  paymentUrl: string;
  language: "ar" | "en";
}) {
  const {
    customerName,
    service,
    appointmentDate,
    appointmentTime,
    amount,
    currency,
    paymentUrl,
    language,
  } = params;
  const isAr = language === "ar";
  const dir = isAr ? "rtl" : "ltr";

  const t = {
    subject: isAr
      ? `رابط الدفع لموعدك - ${service}`
      : `Payment Link for Your Appointment - ${service}`,
    greeting: isAr ? `مرحباً ${customerName}،` : `Hello ${customerName},`,
    intro: isAr
      ? "شكراً لحجز موعدك معنا. يرجى إتمام دفع العربون لتأكيد حجزك."
      : "Thank you for booking your appointment with us. Please complete the deposit payment to confirm your booking.",
    appointmentDetails: isAr ? "تفاصيل الموعد" : "Appointment Details",
    serviceLabel: isAr ? "الخدمة" : "Service",
    dateLabel: isAr ? "التاريخ" : "Date",
    timeLabel: isAr ? "الوقت" : "Time",
    amountLabel: isAr ? "المبلغ المطلوب" : "Amount Due",
    payNow: isAr ? "ادفع الآن" : "Pay Now",
    paymentNote: isAr
      ? "سيتم تأكيد موعدك تلقائياً بعد استلام الدفعة."
      : "Your appointment will be automatically confirmed once payment is received.",
    expiry: isAr
      ? "هذا الرابط صالح لمدة 24 ساعة."
      : "This link is valid for 24 hours.",
    questions: isAr
      ? "إذا كان لديك أي أسئلة، لا تتردد في التواصل معنا."
      : "If you have any questions, please don't hesitate to contact us.",
    thanks: isAr ? "شكراً لك،" : "Thank you,",
    team: isAr ? "فريق ماويدي" : "Mawidi Team",
  };

  const html = `
<!DOCTYPE html>
<html dir="${dir}" lang="${language}">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${t.subject}</title>
</head>
<body style="margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f8fafc; direction: ${dir};">
  <table role="presentation" style="width: 100%; border-collapse: collapse;">
    <tr>
      <td align="center" style="padding: 40px 20px;">
        <table role="presentation" style="width: 100%; max-width: 600px; border-collapse: collapse;">
          <!-- Header -->
          <tr>
            <td style="background: linear-gradient(135deg, #10b981 0%, #059669 100%); padding: 40px; text-align: center; border-radius: 16px 16px 0 0;">
              <h1 style="color: white; margin: 0; font-size: 28px; font-weight: 700;">Mawidi</h1>
              <p style="color: rgba(255,255,255,0.9); margin: 8px 0 0 0; font-size: 14px;">
                ${isAr ? "إدارة المواعيد الذكية" : "Smart Appointment Management"}
              </p>
            </td>
          </tr>

          <!-- Content -->
          <tr>
            <td style="background-color: white; padding: 40px; border-radius: 0 0 16px 16px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);">
              <p style="font-size: 18px; color: #1e293b; margin: 0 0 8px 0;">${t.greeting}</p>
              <p style="font-size: 15px; color: #64748b; margin: 0 0 30px 0; line-height: 1.6;">${t.intro}</p>

              <!-- Appointment Details Card -->
              <div style="background: linear-gradient(135deg, #f0fdf4 0%, #ecfdf5 100%); border: 1px solid #bbf7d0; border-radius: 12px; padding: 24px; margin-bottom: 30px;">
                <h3 style="color: #166534; margin: 0 0 16px 0; font-size: 16px; font-weight: 600;">${t.appointmentDetails}</h3>
                <table style="width: 100%; border-collapse: collapse;">
                  <tr>
                    <td style="padding: 8px 0; color: #64748b; font-size: 14px;">${t.serviceLabel}:</td>
                    <td style="padding: 8px 0; color: #1e293b; font-size: 14px; font-weight: 600; text-align: ${isAr ? "left" : "right"};">${service}</td>
                  </tr>
                  <tr>
                    <td style="padding: 8px 0; color: #64748b; font-size: 14px;">${t.dateLabel}:</td>
                    <td style="padding: 8px 0; color: #1e293b; font-size: 14px; font-weight: 600; text-align: ${isAr ? "left" : "right"};">${appointmentDate}</td>
                  </tr>
                  <tr>
                    <td style="padding: 8px 0; color: #64748b; font-size: 14px;">${t.timeLabel}:</td>
                    <td style="padding: 8px 0; color: #1e293b; font-size: 14px; font-weight: 600; text-align: ${isAr ? "left" : "right"};">${appointmentTime}</td>
                  </tr>
                  <tr>
                    <td style="padding: 12px 0 0 0; border-top: 1px dashed #bbf7d0; color: #166534; font-size: 16px; font-weight: 600;">${t.amountLabel}:</td>
                    <td style="padding: 12px 0 0 0; border-top: 1px dashed #bbf7d0; color: #166534; font-size: 20px; font-weight: 700; text-align: ${isAr ? "left" : "right"};">${currency} ${amount.toFixed(2)}</td>
                  </tr>
                </table>
              </div>

              <!-- Pay Button -->
              <div style="text-align: center; margin-bottom: 30px;">
                <a href="${paymentUrl}" style="display: inline-block; background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: white; text-decoration: none; padding: 16px 48px; border-radius: 12px; font-size: 16px; font-weight: 600; box-shadow: 0 4px 14px 0 rgba(16, 185, 129, 0.4);">
                  ${t.payNow}
                </a>
              </div>

              <p style="font-size: 14px; color: #64748b; margin: 0 0 8px 0; text-align: center;">${t.paymentNote}</p>
              <p style="font-size: 13px; color: #94a3b8; margin: 0 0 30px 0; text-align: center;">${t.expiry}</p>

              <hr style="border: none; border-top: 1px solid #e2e8f0; margin: 30px 0;">

              <p style="font-size: 14px; color: #64748b; margin: 0 0 20px 0;">${t.questions}</p>
              <p style="font-size: 14px; color: #64748b; margin: 0;">
                ${t.thanks}<br>
                <strong style="color: #1e293b;">${t.team}</strong>
              </p>
            </td>
          </tr>

          <!-- Footer -->
          <tr>
            <td style="padding: 30px; text-align: center;">
              <p style="font-size: 12px; color: #94a3b8; margin: 0;">
                © ${new Date().getFullYear()} Mawidi. ${isAr ? "جميع الحقوق محفوظة." : "All rights reserved."}
              </p>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</body>
</html>
`;

  const text = `
${t.greeting}

${t.intro}

${t.appointmentDetails}:
- ${t.serviceLabel}: ${service}
- ${t.dateLabel}: ${appointmentDate}
- ${t.timeLabel}: ${appointmentTime}
- ${t.amountLabel}: ${currency} ${amount.toFixed(2)}

${t.payNow}: ${paymentUrl}

${t.paymentNote}
${t.expiry}

${t.questions}

${t.thanks}
${t.team}
`;

  return {
    subject: t.subject,
    html,
    text,
  };
}
