import { NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
import { calculateShipDate, formatDateToYYYYMMDD } from '@/lib/dateUtils';

export async function GET(request: Request) {
  try {
    const { searchParams } = new URL(request.url);
    const awb = searchParams.get('awb')?.trim().toLowerCase() || '';
    const master = searchParams.get('master')?.trim().toLowerCase() || '';
    const agency = searchParams.get('agency')?.trim().toLowerCase() || '';
    const date = searchParams.get('date')?.trim() || ''; // YYYY-MM-DD
    const search = searchParams.get('search')?.trim().toLowerCase() || '';

    const lines = await prisma.orderLine.findMany({
      where: {
        farmId: { not: null },
        boxNumber: { not: null },
        status: { in: ['FARM ASIGNED', 'RECEIVED', 'SHIPPED'] },
        order: {
          status: { not: 'CANCELLED' }
        }
      },
      include: {
        order: {
          include: {
            shippingCustomer: true,
            billingCustomer: true
          }
        },
        product: true,
        farm: true
      },
      orderBy: [
        { farmDepartureDate: 'desc' },
        { createdAt: 'desc' }
      ]
    });

    const mapped = lines
      .filter(line => {
        if (!line.boxNumber) return false;
        const cleanBox = line.boxNumber.replace('#', '').trim();
        if (!cleanBox || /^0+$/.test(cleanBox)) return false;
        if (line.status === 'CANCELLED' || line.order?.status === 'CANCELLED') return false;
        return true;
      })
      .map(line => {
      const lineAwb = (line.airwayBill || line.order.awb || '').trim();
      const digitsOnly = lineAwb.replace(/\D/g, '');
      const autoMaster = digitsOnly.length >= 4 ? digitsOnly.slice(-4) : lineAwb.slice(-4);
      const agencyName = line.order.service || 'FEDEX';

      const salidaFincaStr = line.farmDepartureDate ? formatDateToYYYYMMDD(line.farmDepartureDate) : '';
      const shipDateStr = line.order.shipdt || (line.order.deliveryDate ? calculateShipDate(line.order.deliveryDate, agencyName) : '');
      const deliverStr = formatDateToYYYYMMDD(line.order.deliveryDate);
      const orderDateStr = line.order.creationDate ? formatDateToYYYYMMDD(line.order.creationDate) : '';
      const fechaPedidoStr = line.farmOrderDate ? new Date(line.farmOrderDate).toLocaleString('es-EC') : orderDateStr;

      const unitPrice = line.farmPrice || line.price || 0;
      const totalPrice = unitPrice * (line.quantity || 1);

      return {
        id: line.id,
        orderId: line.order.id,
        po: line.order.po,
        orderNumber: line.order.orderNumber,
        finca: line.farm?.name || '—',
        farmId: line.farmId,
        farmRuc: line.farm?.ruc || '',
        item: line.product.code,
        prodDesc: line.product.name,
        qty: line.quantity || 1,
        boxType: line.boxType || line.product.boxType || 'EB',
        precioCaja: unitPrice,
        precioTotal: totalPrice,
        salidaFinca: salidaFincaStr,
        shipdate: shipDateStr,
        deliver: deliverStr,
        agencia: agencyName,
        awb: lineAwb,
        master: autoMaster,
        orderDate: orderDateStr,
        fechaPedido: fechaPedidoStr,
        hawb: line.hawb || 'FC-2026',
        boxNumber: line.boxNumber || '',
        uniqueCode: line.uniqueCode || '',
        tracking: line.trackingNumber || '',
        consolidado: '',
        status: line.status,
        customerName: line.order.shippingCustomer?.businessName || line.order.billingCustomer?.businessName || ''
      };
    }).filter(row => {
      if (awb && !row.awb.toLowerCase().includes(awb)) return false;
      if (master && !row.master.toLowerCase().includes(master)) return false;
      if (agency && !row.agencia.toLowerCase().includes(agency)) return false;
      if (date && row.salidaFinca !== date && row.shipdate !== date && row.deliver !== date) return false;
      if (search) {
        const match = row.finca.toLowerCase().includes(search) ||
          row.item.toLowerCase().includes(search) ||
          row.prodDesc.toLowerCase().includes(search) ||
          row.po.toLowerCase().includes(search) ||
          row.orderNumber.toLowerCase().includes(search) ||
          row.boxNumber.toLowerCase().includes(search) ||
          row.tracking.toLowerCase().includes(search) ||
          row.uniqueCode.toLowerCase().includes(search);
        if (!match) return false;
      }
      return true;
    });

    return NextResponse.json(mapped);
  } catch (error: any) {
    return NextResponse.json({ error: error.message || 'Error fetching cold room inventory' }, { status: 500 });
  }
}

export async function POST(request: Request) {
  try {
    const body = await request.json();
    const { action } = body;

    // 1. Action: REJECT_QC
    if (action === 'REJECT_QC') {
      const { lineIds, reason, comment, photoUrl } = body;
      if (!lineIds || !Array.isArray(lineIds) || lineIds.length === 0 || !reason) {
        return NextResponse.json({ error: 'Se requiere al menos una caja y el motivo del rechazo' }, { status: 400 });
      }

      const lines = await prisma.orderLine.findMany({
        where: { id: { in: lineIds } },
        include: { product: true, farm: true, order: true }
      });

      const rejectionsCreated = [];
      const farmNames = new Set<string>();

      for (const line of lines) {
        if (line.farm?.name) farmNames.add(line.farm.name);

        // Register QC Rejection with comment
        const rej = await prisma.qcRejection.create({
          data: {
            orderLineId: line.id,
            farmId: line.farmId,
            boxNumber: line.boxNumber || null,
            productCode: line.product.code,
            productName: line.product.name,
            reason: reason.trim(),
            comment: (comment || '').trim() || null,
            photoUrl: photoUrl || null,
            price: line.farmPrice || line.price || 0,
            creditApplied: false
          }
        });
        rejectionsCreated.push(rej);

        // Reset the OrderLine back to status NEW (so it can be repurchased)
        await prisma.orderLine.update({
          where: { id: line.id },
          data: {
            status: 'NEW',
            farmId: null,
            airwayBill: null,
            hawb: null,
            trackingNumber: null,
            qcRejected: true,
            qcReason: reason.trim(),
            qcComment: (comment || '').trim() || null,
            qcPhoto: photoUrl || null,
            qcRejectedAt: new Date()
          }
        });
      }

      const farmListStr = Array.from(farmNames).join(', ') || 'finca';

      return NextResponse.json({
        success: true,
        message: `${lines.length} caja(s) rechazada(s) por QC. Regresaron a estado NEW para reordenar. Notificación enviada a ${farmListStr}: Dispone de 48 horas máximo para retirar la caja de Cuarto Frío antes de su desecho.`,
        rejections: rejectionsCreated
      });
    }

    // 2. Action: CHANGE_AWB
    if (action === 'CHANGE_AWB') {
      const { lineIds, newAwb } = body;
      if (!lineIds || !Array.isArray(lineIds) || lineIds.length === 0 || !newAwb) {
        return NextResponse.json({ error: 'Se requiere seleccionar cajas y especificar la nueva AWB' }, { status: 400 });
      }

      // En el sistema: eliminación de tracking, se mantiene la finca, se mantienen los códigos únicos, la orden regresa a status de FARM ASIGNED
      await prisma.orderLine.updateMany({
        where: { id: { in: lineIds } },
        data: {
          airwayBill: newAwb.trim(),
          trackingNumber: null, // Eliminación de tracking
          status: 'FARM ASIGNED' // Regresa a estado FARM ASIGNED / CONFIRMED
        }
      });

      return NextResponse.json({
        success: true,
        message: `AWB actualizada a ${newAwb} para ${lineIds.length} caja(s). Tracking eliminado y estado regresado a FARM ASIGNED.`
      });
    }

    // 3. Action: SCAN_RECEIVE (Scan box in Cold Room)
    if (action === 'SCAN_RECEIVE') {
      const { code } = body;
      if (!code) return NextResponse.json({ error: 'Código requerido' }, { status: 400 });

      const clean = code.trim();
      const line = await prisma.orderLine.findFirst({
        where: {
          OR: [
            { uniqueCode: clean },
            { boxNumber: clean },
            { id: clean }
          ]
        },
        include: { product: true, farm: true }
      });

      if (!line) {
        return NextResponse.json({ error: `No se encontró ninguna caja con el código: ${clean}` }, { status: 404 });
      }

      const updated = await prisma.orderLine.update({
        where: { id: line.id },
        data: {
          status: 'RECEIVED',
          receivedDate: new Date()
        }
      });

      return NextResponse.json({
        success: true,
        message: `Caja ${line.boxNumber || clean} (${line.product.name}) marcada como RECIBIDA en Cuarto Frío.`,
        line: updated
      });
    }

    // 4. Action: SCAN_SHIP (Assign tracking and dispatch)
    if (action === 'SCAN_SHIP') {
      const { lineId, trackingNumber } = body;
      if (!lineId || !trackingNumber) {
        return NextResponse.json({ error: 'ID de línea y tracking son obligatorios' }, { status: 400 });
      }

      const updated = await prisma.orderLine.update({
        where: { id: lineId },
        data: {
          trackingNumber: trackingNumber.trim(),
          status: 'SHIPPED',
          shippedDate: new Date()
        }
      });

      return NextResponse.json({
        success: true,
        message: `Tracking ${trackingNumber} asignado. Estado actualizado a SHIPPED.`,
        line: updated
      });
    }

    return NextResponse.json({ error: 'Acción no válida' }, { status: 400 });
  } catch (error: any) {
    return NextResponse.json({ error: error.message || 'Error en operación de cuarto frío' }, { status: 500 });
  }
}
