import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/db';
import { processCrmOrder, markCrmOrderPaid, getCrmOrderAuditTrail } from '@/lib/order-to-cash/crm-bridge';
import { z } from 'zod';
import { validateBody } from '@/lib/api-validation';

export const dynamic = 'force-dynamic';

const salesOrderItemSchema = z.object({
  description: z.string().max(500).optional().default('Item'),
  quantity: z.number().min(1).optional().default(1),
  unitPrice: z.number().min(0).optional().default(0),
  productId: z.string().optional(),
});

const createSalesOrderSchema = z.object({
  customerId: z.string().min(1, 'Customer ID is required'),
  items: z.array(salesOrderItemSchema).min(1, 'At least one item is required'),
  notes: z.string().max(2000).optional(),
  shippingAddress: z.union([z.string().max(1000), z.record(z.unknown())]).optional(),
  paymentMethod: z.string().max(50).optional(),
  requiredDate: z.string().optional(),
});

// GET /api/erp/crm/sales-orders - List sales orders
export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url);
    const status = searchParams.get('status');
    const customerId = searchParams.get('customerId');
    const limit = parseInt(searchParams.get('limit') || '50');
    const orderId = searchParams.get('orderId');
    const auditTrail = searchParams.get('auditTrail') === 'true';

    // If requesting audit trail for a specific order
    if (orderId && auditTrail) {
      const trail = await getCrmOrderAuditTrail(orderId);
      return NextResponse.json({ auditTrail: trail });
    }

    const orders = await prisma.salesOrder.findMany({
      where: {
        ...(status ? { status } : {}),
        ...(customerId ? { customerId } : {})
      },
      include: {
        customer: { select: { id: true, name: true, customerNumber: true } },
        items: true
      },
      orderBy: { createdAt: 'desc' },
      take: limit
    });

    // Map to expected format for UI
    const mappedOrders = orders.map(o => ({
      ...o,
      totalAmount: o.total,
      taxAmount: o.tax,
      items: o.items.map(item => ({
        ...item,
        totalPrice: item.total
      }))
    }));

    return NextResponse.json({ orders: mappedOrders });
  } catch (error) {
    console.error('Sales orders list error:', error);
    return NextResponse.json({ error: 'Failed to fetch sales orders' }, { status: 500 });
  }
}

// POST /api/erp/crm/sales-orders - Create sales order via full pipeline
export async function POST(request: NextRequest) {
  try {
    const validation = await validateBody(request, createSalesOrderSchema);
    if (validation.error) return validation.error;
    const { customerId, items, notes, shippingAddress, paymentMethod, requiredDate } = validation.data;

    // Process through the full CRM → OrderToCash pipeline
    const result = await processCrmOrder({
      customerId,
      items: items.map((item: any) => ({
        description: item.description || 'Item',
        quantity: item.quantity || 1,
        unitPrice: item.unitPrice || 0,
        productId: item.productId,
      })),
      notes,
      shippingAddress: typeof shippingAddress === 'string' ? { address: shippingAddress } as Record<string, unknown> : shippingAddress as Record<string, unknown> | undefined,
      paymentMethod,
      requiredDate,
    });

    return NextResponse.json({
      order: result.order,
      pipeline: result.pipeline,
      executionId: result.executionId,
      invoiceId: result.invoiceId,
      transactionId: result.transactionId,
      arId: result.arId,
    }, { status: 201 });
  } catch (error: any) {
    console.error('Create sales order error:', error);
    return NextResponse.json(
      { error: 'Failed to create sales order', details: error.message },
      { status: 500 }
    );
  }
}

// PATCH /api/erp/crm/sales-orders - Update order status (e.g., mark paid)
export async function PATCH(request: NextRequest) {
  try {
    const body = await request.json();
    const { orderId, action, paymentDetails } = body;

    if (!orderId || !action) {
      return NextResponse.json({ error: 'orderId and action are required' }, { status: 400 });
    }

    if (action === 'mark_paid') {
      if (!paymentDetails?.amountPaid || !paymentDetails?.paymentMethod) {
        return NextResponse.json(
          { error: 'paymentDetails with amountPaid and paymentMethod required' },
          { status: 400 }
        );
      }
      const result = await markCrmOrderPaid(orderId, paymentDetails);
      return NextResponse.json(result);
    }

    // Generic status update
    if (action === 'update_status') {
      const { status: newStatus } = body;
      if (!newStatus) {
        return NextResponse.json({ error: 'status is required for update_status action' }, { status: 400 });
      }

      const order = await prisma.salesOrder.update({
        where: { id: orderId },
        data: { status: newStatus },
        include: { customer: true },
      });

      // Audit log
      await prisma.auditLog.create({
        data: {
          action: 'update',
          resource: 'sales_order',
          resourceId: orderId,
          details: {
            orderNumber: order.orderNumber,
            newStatus,
            source: 'crm-manual',
          },
          success: true,
        },
      });

      return NextResponse.json({ order });
    }

    return NextResponse.json({ error: `Unknown action: ${action}` }, { status: 400 });
  } catch (error: any) {
    console.error('Update sales order error:', error);
    return NextResponse.json(
      { error: 'Failed to update sales order', details: error.message },
      { status: 500 }
    );
  }
}
