import { Controller, Post, Body, Query, HttpCode, HttpStatus, Logger } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { OrderEventsService } from './services/order-events.service';

@Controller('webhooks/woocommerce')
export class WooCommerceWebhookController {
  private readonly logger = new Logger(WooCommerceWebhookController.name);

  constructor(
    private readonly prisma: PrismaService,
    private readonly orderEventsService: OrderEventsService,
  ) {}

  @Post('orders')
  @HttpCode(HttpStatus.OK)
  async handleOrderWebhook(
    @Query('businessId') businessId: string,
    @Body() payload: any,
  ) {
    this.logger.log(`Received WooCommerce order webhook for businessId: ${businessId}, Order ID: ${payload.id}, Status: ${payload.status}`);

    if (!businessId) {
      this.logger.error('Missing businessId in WooCommerce webhook query parameters');
      return { error: 'Missing businessId' };
    }

    const externalOrderId = String(payload.id);

    // 1. Check if the order already exists in our database
    const existingOrder = await this.prisma.order.findFirst({
      where: { businessId, externalOrderId },
    });

    // Map WooCommerce status to our internal order status
    let status = 'PENDING';
    const wcStatus = (payload.status || '').toLowerCase();
    if (['processing', 'completed'].includes(wcStatus)) {
      status = wcStatus.toUpperCase();
    } else if (['cancelled', 'refunded', 'failed'].includes(wcStatus)) {
      status = 'CANCELLED';
    }

    const paymentStatus = payload.date_paid ? 'PAID' : 'UNPAID';

    if (existingOrder) {
      // Update existing order status
      const updated = await this.prisma.order.update({
        where: { id: existingOrder.id },
        data: {
          status,
          paymentStatus,
        },
      });
      this.logger.log(`Updated existing order status to ${status} for external ID: ${externalOrderId}`);

      this.orderEventsService.emitOrderUpdate(businessId, {
        type: 'order_updated',
        orderId: updated.id,
        orderNumber: updated.orderNumber,
        status: updated.status,
      });

      return { success: true, orderId: updated.id, action: 'updated' };
    }

    // 2. If it is a new order, create it
    // Check if the order came from the WhatsApp chatbot payment method
    const isWhatsAppOrder = payload.payment_method === 'whatsapp_hub';
    const sourceChannel = isWhatsAppOrder ? 'whatsapp' : 'web';

    // Parse billing details
    const billing = payload.billing || {};
    const customerPhone = billing.phone || payload.shipping?.phone || 'unknown';
    const customerName = `${billing.first_name || ''} ${billing.last_name || ''}`.trim() || 'Website Customer';

    // Find or create customer
    let customer = await this.prisma.customer.findFirst({
      where: { businessId, whatsappNumber: customerPhone },
    });

    if (!customer) {
      customer = await this.prisma.customer.create({
        data: {
          businessId,
          whatsappNumber: customerPhone,
          name: customerName,
        },
      });
    }

    // Resolve products for order items
    const lineItems = payload.line_items || [];
    const itemsToCreate: any[] = [];

    for (const item of lineItems) {
      const extProdId = String(item.product_id);
      const extVarId = item.variation_id ? String(item.variation_id) : null;

      // Find local product ID
      const product = await this.prisma.product.findFirst({
        where: { businessId, externalProductId: extProdId },
      });

      if (product) {
        // Find variant if applicable
        let variantId: string | null = null;
        if (extVarId) {
          const variant = await this.prisma.productVariant.findFirst({
            where: { productId: product.id, externalVariantId: extVarId },
          });
          if (variant) {
            variantId = variant.id;
          }
        }

        itemsToCreate.push({
          productId: product.id,
          variantId,
          externalProductId: extProdId,
          externalVariantId: extVarId,
          productName: item.name,
          quantity: item.quantity,
          unitPrice: parseFloat(item.price || '0'),
          lineTotal: parseFloat(item.total || '0'),
        });
      }
    }

    if (itemsToCreate.length === 0 && lineItems.length > 0) {
      this.logger.warn(`Could not map any WooCommerce products to local products for order: ${payload.id}`);
      // Fallback: create mock products or just ignore
    }

    // Create the order
    const newOrder = await this.prisma.order.create({
      data: {
        businessId,
        customerId: customer.id,
        sourceChannel,
        sourceSystem: 'woocommerce',
        externalOrderId,
        orderNumber: payload.number || String(payload.id),
        status,
        paymentStatus,
        totalAmount: parseFloat(payload.total || '0'),
        currency: payload.currency || 'USD',
        customerPhone,
        customerName,
        deliveryAddress: payload.shipping?.address_1 || null,
        items: {
          create: itemsToCreate,
        },
      },
    });

    this.logger.log(`Created new order from WooCommerce: ${newOrder.orderNumber} (sourceChannel: ${sourceChannel})`);

    this.orderEventsService.emitOrderUpdate(businessId, {
      type: 'order_created',
      orderId: newOrder.id,
      orderNumber: newOrder.orderNumber,
      status: newOrder.status,
    });

    return { success: true, orderId: newOrder.id, action: 'created' };
  }
}
