/**
 * POST /api/shipstation/webhook
 * Handle ShipStation webhook events for shipment 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 { ShipStationWebhookSchema } 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("shipstation", "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 = ShipStationWebhookSchema.safeParse(body)
    if (!validation.success) {
      logger.error("shipstation", "Invalid webhook payload", {
        body,
        errors: validation.error.issues,
      })
      // Return 200 to prevent ShipStation from retrying invalid payloads
      return NextResponse.json({ received: true })
    }

    const payload = validation.data

    logger.info("shipstation", "Webhook event received", {
      type: payload.resource_type,
      orderId: payload.order_id,
      orderNumber: payload.order_number,
      trackingNumber: payload.tracking_number,
    })

    // Handle SHIP_NOTIFY and ITEM_SHIPPED events
    if (
      payload.resource_type === "SHIP_NOTIFY" ||
      payload.resource_type === "ITEM_SHIPPED"
    ) {
      // Extract WooCommerce order number
      const wooOrderId = payload.order_number
        ? Number.parseInt(payload.order_number, 10)
        : null

      if (!wooOrderId || isNaN(wooOrderId)) {
        logger.error("shipstation", "Missing or invalid 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("shipstation", "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 shipped
      if (order.status !== "processing" && order.status !== "awaiting_shipment") {
        logger.warn("shipstation", "Order not in processable state for shipment", {
          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.carrier) {
        trackingInfo.push(`Carrier: ${payload.carrier}`)
      }
      if (payload.ship_date) {
        trackingInfo.push(`Ship Date: ${payload.ship_date}`)
      }

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

      // Update order status to "shipped" (custom status)
      // Note: If "shipped" status doesn't exist in WooCommerce, this will use "completed"
      const updateData: any = {
        status: "shipped",
        customer_note: customerNote,
        meta_data: [
          ...order.meta_data,
          {
            key: "_tracking_number",
            value: payload.tracking_number || "",
          },
          {
            key: "_shipping_carrier",
            value: payload.carrier || "",
          },
          {
            key: "_shipped_date",
            value: payload.ship_date || new Date().toISOString(),
          },
          {
            key: "_shipstation_webhook_received_at",
            value: new Date().toISOString(),
          },
        ],
      }

      try {
        await WooCommerce.updateOrder(wooOrderId, updateData)

        logger.info("shipstation", "Order marked as shipped", {
          orderId: wooOrderId,
          trackingNumber: payload.tracking_number,
          carrier: payload.carrier,
        })
      } catch (error) {
        logger.error("shipstation", "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 other event types (ORDER_NOTIFY, ITEM_ORDER_NOTIFY) - currently just log
    if (
      payload.resource_type === "ORDER_NOTIFY" ||
      payload.resource_type === "ITEM_ORDER_NOTIFY"
    ) {
      logger.info("shipstation", "Received order notification", {
        type: payload.resource_type,
        orderId: payload.order_id,
        orderNumber: payload.order_number,
      })
    }

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




