/**
 * POST /api/stripe/webhook
 * Handle Stripe webhook events (SOURCE OF TRUTH)
 */

import { type NextRequest, NextResponse } from "next/server"
import { StripeClient } from "@/lib/stripe"
import { WooCommerce } from "@/lib/woo"
import { Money } from "@/lib/money"
import { logger } from "@/lib/logger"
import { RateLimit, getClientIp } from "@/lib/rate-limit"
import { EasyShip } from "@/lib/easyship"
import { Klaviyo } from "@/lib/klaviyo"

// Rate limit: 100 requests per minute (webhooks can be frequent)
const rateLimiter = new RateLimit(100, 60000)

export async function POST(request: NextRequest) {
  try {
    // Apply rate limiting (but be generous for Stripe webhooks)
    const clientIp = getClientIp(request)
    const rateLimit = rateLimiter.check(clientIp)
    
    if (!rateLimit.allowed) {
      logger.warn("v0", "Webhook rate limit exceeded", { ip: clientIp })
      return NextResponse.json(
        { error: "Too many requests" },
        { status: 429 }
      )
    }

    const body = await request.text()
    const signature = request.headers.get("stripe-signature")

    if (!signature) {
      return NextResponse.json({ error: "Missing signature" }, { status: 400 })
    }

    // Verify webhook signature
    const event = StripeClient.constructEvent(body, signature)

    logger.info("v0", "Webhook event received", { type: event.type })

    // Handle payment_intent.succeeded
    if (event.type === "payment_intent.succeeded") {
      const paymentIntent = event.data.object

      // Extract WooCommerce order ID from metadata
      const wooOrderId = Number.parseInt(paymentIntent.metadata.wc_order_id || "0", 10)

      if (!wooOrderId) {
        logger.error("v0", "Missing wc_order_id in PaymentIntent metadata", {
          paymentIntentId: paymentIntent.id,
        })
        return NextResponse.json({ received: true })
      }

      // Fetch order from WooCommerce
      const order = await WooCommerce.getOrder(wooOrderId)

      // Check if already paid
      if (WooCommerce.isPaid(order)) {
        logger.info("v0", "Order already paid", { orderId: wooOrderId })
        return NextResponse.json({ received: true })
      }

      // Validate amounts match
      const normalizedOrder = WooCommerce.normalize(order)
      const orderTotal = normalizedOrder.total_cents
      const paidAmount = paymentIntent.amount

      logger.info("v0", "Webhook amount validation", {
        orderId: wooOrderId,
        orderTotal,
        paidAmount,
        subtotal_cents: normalizedOrder.subtotal_cents,
        tax_cents: normalizedOrder.tax_cents,
        shipping_cents: normalizedOrder.shipping_cost_cents,
      })

      try {
        Money.validateMatch(orderTotal, paidAmount)
      } catch (error) {
        logger.error("v0", "Amount mismatch - CRITICAL", {
          orderId: wooOrderId,
          expected: orderTotal,
          received: paidAmount,
          difference: paidAmount - orderTotal,
        })
        
        // Update order to on-hold with note
        await WooCommerce.updateOrder(wooOrderId, {
          status: "on-hold",
          customer_note: "Payment received but amount mismatch detected. Please contact support.",
        })
        
        // TODO: Add Slack/Email alert here
        return NextResponse.json({ received: true })
      }

      // Update order status to processing
      const chargeId = typeof paymentIntent.latest_charge === "string" 
        ? paymentIntent.latest_charge 
        : paymentIntent.latest_charge?.id || ""
      
      // Prepare order update with payment info and customer association
      const orderUpdate: any = {
        status: "processing",
        meta_data: [
          ...order.meta_data,
          {
            key: "_stripe_payment_intent_id",
            value: paymentIntent.id,
          },
          {
            key: "_stripe_charge_id",
            value: chargeId,
          },
          {
            key: "_paid_date",
            value: new Date().toISOString(),
          },
          {
            key: "_payment_method",
            value: "stripe",
          },
          {
            key: "_payment_method_title",
            value: "Credit Card (Stripe)",
          },
          {
            key: "_transaction_id",
            value: chargeId,
          },
        ],
      }

      // Ensure customer_id is set (if order has a customer)
      // This ensures the order appears in customer's order history
      if (order.customer_id > 0) {
        orderUpdate.customer_id = order.customer_id
      }

      // Set date paid (WooCommerce standard field)
      orderUpdate.date_paid = new Date().toISOString()
      orderUpdate.date_paid_gmt = new Date().toISOString()

      await WooCommerce.updateOrder(wooOrderId, orderUpdate)

      // ⭐ CREATE SHIPMENT IN EASYSHIP (after successful payment)
      logger.info("v0", "Creating shipment in EasyShip", {
        orderId: wooOrderId,
      })

      const easyshipResult = await EasyShip.createShipment(order)

      if (easyshipResult.success && easyshipResult.shipmentId) {
        // Store EasyShip shipment ID in WooCommerce metadata
        const easyshipMetadata = [
          ...order.meta_data,
          {
            key: "_easyship_shipment_id",
            value: easyshipResult.shipmentId,
          },
          {
            key: "_easyship_platform_order_number",
            value: easyshipResult.platformOrderNumber || String(order.id),
          },
          {
            key: "_easyship_synced_at",
            value: new Date().toISOString(),
          },
        ]

        await WooCommerce.updateOrder(wooOrderId, {
          meta_data: easyshipMetadata,
        })

        logger.info("v0", "EasyShip shipment created successfully", {
          orderId: wooOrderId,
          easyshipShipmentId: easyshipResult.shipmentId,
        })
      } else {
        // Log error and store failure metadata for manual retry
        logger.error("v0", "Failed to create EasyShip shipment", {
          orderId: wooOrderId,
          error: easyshipResult.error,
          errorDetails: easyshipResult.errorDetails,
        })

        const errorMetadata = [
          ...order.meta_data,
          {
            key: "_easyship_sync_error",
            value: easyshipResult.error || "Unknown error",
          },
          {
            key: "_easyship_sync_error_at",
            value: new Date().toISOString(),
          },
        ]

        await WooCommerce.updateOrder(wooOrderId, {
          meta_data: errorMetadata,
        })

        // Continue processing - don't fail the payment webhook due to EasyShip errors
        logger.warn("v0", "Order marked for manual EasyShip sync", {
          orderId: wooOrderId,
        })
      }

      // Clear cart after successful payment (only for logged-in customers)
      if (order.customer_id > 0) {
        await WooCommerce.clearCart(order.customer_id)
      }

      logger.info("v0", "Order payment completed", {
        orderId: wooOrderId,
        paymentIntentId: paymentIntent.id,
        customerId: order.customer_id,
        easyshipSynced: easyshipResult.success,
      })

      // Fire-and-forget: send receipt to customer + notification to admin via Klaviyo
      Klaviyo.sendOrderEmails(order, chargeId)
    }

    // Handle payment_intent.payment_failed
    if (event.type === "payment_intent.payment_failed") {
      const paymentIntent = event.data.object

      const wooOrderId = Number.parseInt(paymentIntent.metadata.wc_order_id || "0", 10)

      if (wooOrderId) {
        logger.warn("v0", "Payment failed for order", {
          orderId: wooOrderId,
          paymentIntentId: paymentIntent.id,
          error: paymentIntent.last_payment_error?.message,
        })

        // Fetch order to check if it's still pending
        const order = await WooCommerce.getOrder(wooOrderId)

        // Keep order as pending and add note about failure
        // DO NOT cancel the order - let customer retry
        if (order.status === "pending") {
          // Attempt to restore cart for customer
          let cartRestored = false
          if (order.customer_id > 0) {
            cartRestored = await WooCommerce.restoreCartFromOrder(order)
          }

          await WooCommerce.updateOrder(wooOrderId, {
            customer_note: cartRestored
              ? `Payment attempt failed: ${paymentIntent.last_payment_error?.message || "Unknown error"}. Your cart has been restored.`
              : `Payment attempt failed: ${paymentIntent.last_payment_error?.message || "Unknown error"}. Please try again.`,
            meta_data: [
              ...order.meta_data,
              {
                key: "_payment_failed_at",
                value: new Date().toISOString(),
              },
              {
                key: "_payment_error",
                value: paymentIntent.last_payment_error?.message || "Unknown error",
              },
              {
                key: "_cart_restored_on_failure",
                value: cartRestored ? "yes" : "no",
              },
            ],
          })

          logger.info("v0", "Order kept as pending for retry", {
            orderId: wooOrderId,
            cartRestored,
          })
        }
      }
    }

    return NextResponse.json({ received: true })
  } catch (error) {
    logger.error("v0", "Webhook error", {
      error: error instanceof Error ? error.message : "Unknown error",
      stack: error instanceof Error ? error.stack : undefined,
    })
    return NextResponse.json(
      {
        error: error instanceof Error ? error.message : "Webhook failed",
      },
      { status: 400 },
    )
  }
}
