/**
 * Send Quotation API
 * POST - Send quotation to customer via email with payment link
 *
 * Convex-first: fetches quotation + items from Convex, generates portal token,
 * sends email via SMTP (MailHog in dev), updates status to SENT.
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { getAuthenticatedUser } from "@/lib/utils/auth-helpers.util";
import { getEffectiveOwnerId } from "@/lib/utils/organization-data";
import { logger } from "@/lib/logger";
import { convexQuery } from "@/lib/convex-client";
import { ConvexHttpClient } from "convex/browser";
import Stripe from "stripe";

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

type RouteContext = { params: Promise<{ id: string }> };

export async function POST(request: NextRequest, context: RouteContext) {
  // CSRF validation (skip in development)
  if (process.env.NODE_ENV !== "development") {
    const { validateCSRFToken } = await import("@/lib/csrf");
    if (!validateCSRFToken(request)) {
      return NextResponse.json(
        { error: "Invalid or missing CSRF token" },
        { status: 403 },
      );
    }
  }

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

    const effectiveUserId = await getEffectiveOwnerId(user.userId);
    const { id: quotationId } = await context.params;

    const convexUrl =
      process.env.NEXT_PUBLIC_CONVEX_URL || process.env.CONVEX_URL;
    if (!convexUrl) {
      return NextResponse.json(
        { success: false, error: "Convex not configured" },
        { status: 503 },
      );
    }

    const client = new ConvexHttpClient(convexUrl);

    // Fetch quotation from Convex
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const quotation = await (client.query as any)(
      "quotations/queries:getById" as any,
      { id: quotationId },
    );

    if (!quotation || quotation.userId !== effectiveUserId) {
      return NextResponse.json(
        { success: false, error: "Quotation not found" },
        { status: 404 },
      );
    }

    // Fetch line items
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const items = await (client.query as any)(
      "quotations/queries:getItems" as any,
      { quotationId: quotationId },
    );

    // Fetch customer info if customerId exists
    let customer: { name?: string; email?: string; phone?: string } | null =
      null;
    if (quotation.customerId) {
      try {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        customer = await (client.query as any)(
          "customers/queries:getCustomerById" as any,
          { id: quotation.customerId, userId: effectiveUserId },
        );
      } catch {
        log.warn("Failed to fetch customer for quotation send");
      }
    }

    if (!customer?.email) {
      return NextResponse.json(
        {
          success: false,
          error: "Customer has no email address. Add an email to send the quotation.",
        },
        { status: 400 },
      );
    }

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

    // Get organization's Stripe keys for payment link
    let paymentUrl: string | null = null;
    try {
      const orgState = await convexQuery<Record<string, unknown>>(
        "organizations/queries:getOrganizationStateByUserId",
        { userId: effectiveUserId },
      );

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

      if (stripeSecretKeyEncrypted) {
        const { decryptStripeKey } = await import("@/lib/services/stripe-keys.service");
        const stripeSecretKey = decryptStripeKey(stripeSecretKeyEncrypted);
        const stripe = new Stripe(stripeSecretKey, { apiVersion: "2024-12-18.acacia" });

        const lineItems = (items || []).map(
          (item: { description: string; quantity: number; unitPrice: number }) => ({
            price_data: {
              currency: (quotation.currency || "QAR").toLowerCase(),
              product_data: { name: item.description },
              unit_amount: Math.round(item.unitPrice),
            },
            quantity: item.quantity,
          }),
        );

        const session = await stripe.checkout.sessions.create({
          payment_method_types: ["card"],
          mode: "payment",
          customer_email: customer.email,
          line_items: lineItems,
          metadata: {
            quotationId,
            quotationNumber: quotation.quotationNumber,
            type: "quotation_payment",
          },
          success_url: `${appUrl}/en/payment/success?type=quotation&id=${quotationId}`,
          cancel_url: `${appUrl}/en/dashboard?tab=quotations`,
        });

        paymentUrl = session.url;
      }
    } catch (stripeErr) {
      log.warn("Stripe checkout creation failed, sending without payment link", stripeErr);
    }

    // Fallback portal URL if Stripe not configured
    const portalUrl = paymentUrl || `${appUrl}/en/dashboard?tab=quotations`;

    // Update quotation status to SENT
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    await (client.mutation as any)(
      "quotations/mutations:updateQuotation" as any,
      {
        id: quotationId,
        status: "SENT",
      },
    );

    // Build email HTML
    const itemRows = (items || [])
      .map(
        (item: { description: string; quantity: number; unitPrice: number; total: number }) =>
          `<tr>
          <td style="padding: 8px; border-bottom: 1px solid #eee;">${item.description}</td>
          <td style="padding: 8px; border-bottom: 1px solid #eee; text-align: center;">${item.quantity}</td>
          <td style="padding: 8px; border-bottom: 1px solid #eee; text-align: right;">${item.unitPrice.toFixed(2)}</td>
          <td style="padding: 8px; border-bottom: 1px solid #eee; text-align: right;">${item.total.toFixed(2)}</td>
        </tr>`,
      )
      .join("");

    const currency = quotation.currency || "QAR";
    const total = quotation.total.toFixed(2);

    const emailHtml = `
      <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">
        <h2 style="color: #1a1a1a;">Quotation ${quotation.quotationNumber}</h2>
        <p>Dear ${customer.name || "Customer"},</p>
        <p>Please find your quotation details below:</p>

        <table style="width: 100%; border-collapse: collapse; margin: 16px 0;">
          <thead>
            <tr style="background: #f8f8f8;">
              <th style="padding: 8px; text-align: left; border-bottom: 2px solid #ddd;">Description</th>
              <th style="padding: 8px; text-align: center; border-bottom: 2px solid #ddd;">Qty</th>
              <th style="padding: 8px; text-align: right; border-bottom: 2px solid #ddd;">Unit Price</th>
              <th style="padding: 8px; text-align: right; border-bottom: 2px solid #ddd;">Total</th>
            </tr>
          </thead>
          <tbody>
            ${itemRows}
          </tbody>
        </table>

        ${quotation.discountAmount > 0 ? `<p style="color: #666;">Discount: -${currency} ${quotation.discountAmount.toFixed(2)}</p>` : ""}
        ${quotation.taxAmount > 0 ? `<p style="color: #666;">Tax: ${currency} ${quotation.taxAmount.toFixed(2)}</p>` : ""}

        <p style="font-size: 18px; font-weight: bold; color: #1a1a1a;">
          Total: ${currency} ${total}
        </p>

        <a href="${portalUrl}" style="display: inline-block; background-color: #16a34a; color: white; padding: 14px 28px; text-decoration: none; border-radius: 8px; font-weight: bold; margin: 16px 0; font-size: 16px;">
          ${paymentUrl ? "Pay Now" : "View Quotation"}
        </a>
        ${!paymentUrl ? '<p style="color: #999; font-size: 12px;">Payment link unavailable — Stripe keys not configured.</p>' : ""}

        <p style="color: #666; font-size: 14px; margin-top: 24px;">
          ${quotation.validUntil ? `This quotation is valid until ${new Date(quotation.validUntil).toLocaleDateString("en-GB")}.` : ""}
          If you have any questions, please contact us.
        </p>
      </div>
    `;

    // Send email via SMTP (MailHog in development)
    let emailSent = false;
    try {
      const { sendEmail } = await import("@/lib/email");
      await sendEmail(customer.email, {
        subject: `Quotation ${quotation.quotationNumber} — ${quotation.title}`,
        html: emailHtml,
      });
      emailSent = true;
      log.info("Quotation email sent", {
        quotationId,
        to: customer.email,
        quotationNumber: quotation.quotationNumber,
      });
    } catch (emailErr) {
      log.error("Failed to send quotation email", emailErr);
    }

    return NextResponse.json({
      success: true,
      emailSent,
      hasPaymentLink: !!paymentUrl,
      quotationNumber: quotation.quotationNumber,
    });
  } catch (error) {
    log.error("Failed to send quotation", error);
    return NextResponse.json(
      {
        success: false,
        error:
          error instanceof Error ? error.message : "Internal server error",
      },
      { status: 500 },
    );
  }
}
