/**
 * POST /api/easyship/webhook
 * Handle EasyShip webhook events for shipment and tracking notifications
 */

import { type NextRequest, NextResponse } from "next/server"
import { WooCommerce } from "@/lib/woo"
import { logger } from "@/lib/logger"
import { RateLimit, getClientIp } from "@/lib/rate-limit"
import { EasyShipWebhookSchema } from "@/lib/schemas"

// 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
    const clientIp = getClientIp(request)
    const rateLimit = rateLimiter.check(clientIp)

    if (!rateLimit.allowed) {
      logger.warn("easyship", "Webhook rate limit exceeded", { ip: clientIp })
      return NextResponse.json(
        { error: "Too many requests" },
        { status: 429 }
      )
    }

    // Parse request body
    const body = await request.json()

    // Validate webhook payload
    const validation = EasyShipWebhookSchema.safeParse(body)
    if (!validation.success) {
      logger.error("easyship", "Invalid webhook payload", {
        body,
        errors: validation.error.issues,
      })
      // Return 200 to prevent EasyShip from retrying invalid payloads
      return NextResponse.json({ received: true })
    }

    const payload = validation.data

    logger.info("easyship", "Webhook event received", {
      type: payload.event_type,
      shipmentId: payload.easyship_shipment_id,
      platformOrderNumber: payload.platform_order_number,
      trackingNumber: payload.tracking_number,
    })

    // Handle tracking status changes (replaces ShipStation SHIP_NOTIFY / ITEM_SHIPPED)
    if (
      payload.event_type === "shipment.tracking.statuschanged" ||
      payload.event_type === "shipment.tracking.checkpointscreated"
    ) {
      const wooOrderId = payload.platform_order_number
        ? Number.parseInt(payload.platform_order_number, 10)
        : null

      if (!wooOrderId || isNaN(wooOrderId)) {
        logger.error("easyship", "Missing or invalid platform_order_number in webhook", {
          payload,
        })
        return NextResponse.json({ received: true })
      }

      // Fetch order from WooCommerce
      let order
      try {
        order = await WooCommerce.getOrder(wooOrderId)
      } catch (error) {
        logger.error("easyship", "Failed to fetch WooCommerce order", {
          orderId: wooOrderId,
          error: error instanceof Error ? error.message : "Unknown error",
        })
        return NextResponse.json({ received: true })
      }

      // Check if order is in a state that can be updated
      if (order.status !== "processing" && order.status !== "awaiting_shipment") {
        logger.warn("easyship", "Order not in processable state for shipment update", {
          orderId: wooOrderId,
          currentStatus: order.status,
        })
        return NextResponse.json({ received: true })
      }

      // Build tracking information
      const trackingInfo = []
      if (payload.tracking_number) {
        trackingInfo.push(`Tracking Number: ${payload.tracking_number}`)
      }
      if (payload.courier_name) {
        trackingInfo.push(`Carrier: ${payload.courier_name}`)
      }
      if (payload.tracking_status) {
        trackingInfo.push(`Status: ${payload.tracking_status}`)
      }

      const customerNote = trackingInfo.length > 0
        ? `Your order has been shipped! ${trackingInfo.join(" | ")}`
        : "Your order has been shipped!"

      // Determine WooCommerce status based on tracking status
      const newStatus = payload.tracking_status === "delivered" ? "completed" : "shipped"

      const updateData: any = {
        status: newStatus,
        customer_note: customerNote,
        meta_data: [
          ...order.meta_data,
          {
            key: "_tracking_number",
            value: payload.tracking_number || "",
          },
          {
            key: "_shipping_carrier",
            value: payload.courier_name || "",
          },
          {
            key: "_shipped_date",
            value: new Date().toISOString(),
          },
          {
            key: "_easyship_webhook_received_at",
            value: new Date().toISOString(),
          },
        ],
      }

      try {
        await WooCommerce.updateOrder(wooOrderId, updateData)

        logger.info("easyship", "Order updated with tracking info", {
          orderId: wooOrderId,
          trackingNumber: payload.tracking_number,
          courier: payload.courier_name,
          newStatus,
        })
      } catch (error) {
        logger.error("easyship", "Failed to update order status", {
          orderId: wooOrderId,
          error: error instanceof Error ? error.message : "Unknown error",
        })
        // Still return 200 to prevent retries
        return NextResponse.json({ received: true })
      }
    }

    // Handle label creation events
    if (payload.event_type === "shipment.label.created") {
      logger.info("easyship", "Label created for shipment", {
        shipmentId: payload.easyship_shipment_id,
        platformOrderNumber: payload.platform_order_number,
      })
    }

    // Handle label failure events
    if (payload.event_type === "shipment.label.failed") {
      logger.error("easyship", "Label creation failed for shipment", {
        shipmentId: payload.easyship_shipment_id,
        platformOrderNumber: payload.platform_order_number,
      })

      // Store failure in order metadata if we have an order number
      if (payload.platform_order_number) {
        const wooOrderId = Number.parseInt(payload.platform_order_number, 10)
        if (wooOrderId && !isNaN(wooOrderId)) {
          try {
            const order = await WooCommerce.getOrder(wooOrderId)
            await WooCommerce.updateOrder(wooOrderId, {
              meta_data: [
                ...order.meta_data,
                {
                  key: "_easyship_label_error",
                  value: "Label creation failed",
                },
                {
                  key: "_easyship_label_error_at",
                  value: new Date().toISOString(),
                },
              ],
            })
          } catch (error) {
            logger.error("easyship", "Failed to store label error in order metadata", {
              orderId: wooOrderId,
              error: error instanceof Error ? error.message : "Unknown error",
            })
          }
        }
      }
    }

    // Handle shipment cancellation
    if (payload.event_type === "shipment.cancelled") {
      logger.info("easyship", "Shipment cancelled", {
        shipmentId: payload.easyship_shipment_id,
        platformOrderNumber: payload.platform_order_number,
      })
    }

    return NextResponse.json({ received: true })
  } catch (error) {
    logger.error("easyship", "Webhook error", {
      error: error instanceof Error ? error.message : "Unknown error",
      stack: error instanceof Error ? error.stack : undefined,
    })
    // Return 200 even on error to prevent EasyShip from retrying
    return NextResponse.json({ received: true })
  }
}
