import jsPDF from 'jspdf';
import { formatMoney } from '@/utils/formatters';
import printService from '@Services/printService';

/**
 * Servicio para generar tickets de movimientos de inventario en formato PDF
 */
const TicketDetailMovement = {

    /**
     * Detectar ubicación del usuario (ciudad y estado)
     */
    async getUserLocation() {
        return {
            city: import.meta.env.VITE_BUSINESS_CITY,
            state: import.meta.env.VITE_BUSINESS_STATE,
            country: import.meta.env.VITE_BUSINESS_COUNTRY,
            phone: import.meta.env.VITE_BUSINESS_PHONE
        };
    },

    /**
     * Generar ticket de movimiento de inventario
     * @param {Object} movementData - Datos del movimiento
     * @param {Object} options - Opciones de configuración
     * @param {boolean} options.autoDownload - Descargar automáticamente el PDF
     */
    async generateMovementTicket(movementData, options = {}) {
        const {
            businessName = 'HIKVISION DISTRIBUIDOR',
            autoDownload = true,
        } = options;

        // Detectar ubicación del usuario
        const location = await this.getUserLocation();
        const businessAddress = `${location.city}, ${location.state}, ${location.country}`;
        const businessPhone = location.phone;

        // Crear documento PDF - Ticket térmico 80mm de ancho
        const doc = new jsPDF({
            orientation: 'portrait',
            unit: 'mm',
            format: [80, 200]
        });

        let yPosition = 10;
        const leftMargin = 5;
        const rightMargin = 75;
        const centerX = 40;

        // Colores
        const blackColor = [0, 0, 0];
        const darkGrayColor = [80, 80, 80];

        // Configuración por tipo
        const typeBadges = {
            entry: { label: 'ENTRADA', color: [34, 197, 94] },
            exit: { label: 'SALIDA', color: [239, 68, 68] },
            transfer: { label: 'TRASPASO', color: [59, 130, 246] },
        };
        const badge = typeBadges[movementData.movement_type] || {
            label: movementData.movement_type?.toUpperCase(),
            color: darkGrayColor
        };

        // ===== HEADER =====
        doc.setFontSize(14);
        doc.setFont('helvetica', 'bold');
        doc.setTextColor(...blackColor);
        doc.text(businessName, centerX, yPosition, { align: 'center' });
        yPosition += 6;

        doc.setFontSize(8);
        doc.setFont('helvetica', 'normal');
        doc.setTextColor(...darkGrayColor);
        doc.text(businessAddress, centerX, yPosition, { align: 'center' });
        yPosition += 4;
        doc.text(businessPhone, centerX, yPosition, { align: 'center' });
        yPosition += 6;

        // Línea separadora
        doc.setLineWidth(0.3);
        doc.setDrawColor(...blackColor);
        doc.line(leftMargin, yPosition, rightMargin, yPosition);
        yPosition += 5;

        // ===== TÍTULO CON TIPO =====
        doc.setFontSize(12);
        doc.setFont('helvetica', 'bold');
        doc.setTextColor(...badge.color);
        doc.text(badge.label, centerX, yPosition, { align: 'center' });
        yPosition += 5;

        doc.setFontSize(10);
        doc.setTextColor(...blackColor);
        doc.text('MOVIMIENTO DE INVENTARIO', centerX, yPosition, { align: 'center' });
        yPosition += 7;

        // ===== INFORMACIÓN DEL MOVIMIENTO =====
        doc.setFontSize(8);
        doc.setFont('helvetica', 'normal');
        doc.setTextColor(...darkGrayColor);

        // Fecha
        const movementDate = new Date(movementData.created_at || Date.now());
        const formattedDate = movementDate.toLocaleDateString('es-MX', {
            year: 'numeric',
            month: 'long',
            day: 'numeric'
        });
        doc.text(`Fecha: ${formattedDate}`, leftMargin, yPosition);
        yPosition += 4;

        // Hora
        const formattedTime = movementDate.toLocaleTimeString('es-MX', {
            hour: '2-digit',
            minute: '2-digit'
        });
        doc.text(`Hora: ${formattedTime}`, leftMargin, yPosition);
        yPosition += 4;

        // Usuario
        if (movementData.user?.name) {
            doc.text(`Usuario: ${movementData.user.name}`, leftMargin, yPosition);
            yPosition += 4;
        }

        // Referencia de factura (si existe)
        if (movementData.invoice_reference) {
            doc.text(`Factura: ${movementData.invoice_reference}`, leftMargin, yPosition);
            yPosition += 4;
        }

        yPosition += 2;

        // ===== ALMACENES =====
        // Almacén origen (si existe)
        if (movementData.warehouse_from) {
            doc.setFontSize(7);
            doc.setFont('helvetica', 'bold');
            doc.setTextColor(...[239, 68, 68]); // red
            doc.text('ORIGEN:', leftMargin, yPosition);
            yPosition += 3;

            doc.setFont('helvetica', 'normal');
            doc.setTextColor(...blackColor);
            doc.text(`${movementData.warehouse_from.name} (${movementData.warehouse_from.code})`, leftMargin + 2, yPosition);
            yPosition += 4;
        }

        // Almacén destino (si existe)
        if (movementData.warehouse_to) {
            doc.setFontSize(7);
            doc.setFont('helvetica', 'bold');
            doc.setTextColor(...[34, 197, 94]); // green
            doc.text('DESTINO:', leftMargin, yPosition);
            yPosition += 3;

            doc.setFont('helvetica', 'normal');
            doc.setTextColor(...blackColor);
            doc.text(`${movementData.warehouse_to.name} (${movementData.warehouse_to.code})`, leftMargin + 2, yPosition);
            yPosition += 4;
        }

        yPosition += 2;

        // Línea separadora
        doc.setDrawColor(...blackColor);
        doc.setLineWidth(0.3);
        doc.line(leftMargin, yPosition, rightMargin, yPosition);
        yPosition += 5;

        // ===== PRODUCTOS =====
        const isMultiProduct = movementData.products && movementData.products.length > 0;

        doc.setFontSize(9);
        doc.setFont('helvetica', 'bold');
        doc.setTextColor(...blackColor);
        doc.text('PRODUCTOS', centerX, yPosition, { align: 'center' });
        yPosition += 5;

        if (isMultiProduct) {
            // Múltiples productos
            doc.setFontSize(7);
            doc.setFont('helvetica', 'bold');
            doc.setTextColor(...darkGrayColor);
            doc.text('DESCRIPCIÓN', leftMargin, yPosition);
            doc.text('CANT', 50, yPosition, { align: 'center' });
            doc.text('COSTO', rightMargin, yPosition, { align: 'right' });
            yPosition += 4;

            // Línea bajo header
            doc.setLineWidth(0.2);
            doc.line(leftMargin, yPosition, rightMargin, yPosition);
            yPosition += 4;

            // Iterar sobre los productos
            movementData.products.forEach((product) => {
                // Nombre del producto
                const productName = product.inventory?.name || 'Producto';
                const nameLines = doc.splitTextToSize(productName, 40);

                doc.setFontSize(8);
                doc.setFont('helvetica', 'bold');
                doc.setTextColor(...blackColor);
                doc.text(nameLines, leftMargin, yPosition);
                yPosition += nameLines.length * 3.5;

                // SKU
                if (product.inventory?.sku) {
                    doc.setFontSize(7);
                    doc.setFont('helvetica', 'normal');
                    doc.setTextColor(...darkGrayColor);
                    doc.text(`SKU: ${product.inventory.sku}`, leftMargin, yPosition);
                    yPosition += 3;
                }

                // Cantidad y Costo
                doc.setFontSize(8);
                doc.setFont('helvetica', 'normal');
                doc.setTextColor(...blackColor);

                doc.text(String(product.quantity), 50, yPosition, { align: 'center' });
                doc.text(`$${formatMoney(product.unit_cost || 0)}`, rightMargin, yPosition, { align: 'right' });
                yPosition += 5;
            });

            // Total
            const totalQuantity = movementData.products.reduce((sum, p) => sum + Number(p.quantity), 0);
            const totalCost = movementData.products.reduce((sum, p) => sum + (Number(p.quantity) * Number(p.unit_cost || 0)), 0);

            yPosition += 2;
            doc.setLineWidth(0.3);
            doc.line(leftMargin, yPosition, rightMargin, yPosition);
            yPosition += 5;

            doc.setFontSize(9);
            doc.setFont('helvetica', 'bold');
            doc.text('TOTAL:', leftMargin, yPosition);
            doc.text(String(totalQuantity), 50, yPosition, { align: 'center' });
            doc.text(`$${formatMoney(totalCost)}`, rightMargin, yPosition, { align: 'right' });
            yPosition += 6;

        } else {
            // Producto individual
            doc.setFontSize(8);
            doc.setFont('helvetica', 'normal');
            doc.setTextColor(...blackColor);

            const productName = movementData.inventory?.name || 'Producto';
            const nameLines = doc.splitTextToSize(productName, 65);
            doc.text(nameLines, leftMargin, yPosition);
            yPosition += nameLines.length * 4;

            if (movementData.inventory?.sku) {
                doc.setFontSize(7);
                doc.setTextColor(...darkGrayColor);
                doc.text(`SKU: ${movementData.inventory.sku}`, leftMargin, yPosition);
                yPosition += 4;
            }

            doc.setFontSize(9);
            doc.setFont('helvetica', 'bold');
            doc.setTextColor(...blackColor);
            doc.text(`Cantidad: ${movementData.quantity}`, leftMargin, yPosition);
            yPosition += 5;

            if (movementData.unit_cost) {
                doc.text(`Costo unitario: $${formatMoney(movementData.unit_cost)}`, leftMargin, yPosition);
                yPosition += 5;

                const total = Number(movementData.quantity) * Number(movementData.unit_cost);
                doc.text(`Total: $${formatMoney(total)}`, leftMargin, yPosition);
                yPosition += 6;
            } else {
                yPosition += 1;
            }

            // Números de serie (si existen)
            const serialNumbers = movementData.serial_numbers ||
                (movementData.serials ? movementData.serials.map(s => s.serial_number) : []);

            if (serialNumbers && serialNumbers.length > 0) {
                yPosition += 2;
                doc.setLineWidth(0.2);
                doc.setDrawColor(...darkGrayColor);
                doc.line(leftMargin, yPosition, rightMargin, yPosition);
                yPosition += 5;

                doc.setFontSize(7);
                doc.setFont('helvetica', 'bold');
                doc.setTextColor(...[0, 0, 0]); // amber
                doc.text('NÚMEROS DE SERIE:', leftMargin, yPosition);
                yPosition += 4;

                doc.setFontSize(8);
                doc.setFont('courier', 'normal');
                doc.setTextColor(...blackColor);

                serialNumbers.forEach((serial, index) => {
                    doc.text(`${index + 1}. ${serial}`, leftMargin + 2, yPosition);
                    yPosition += 3.5;
                });

                yPosition += 2;
            }
        }

        // Notas (si existen)
        if (movementData.notes) {
            doc.setLineWidth(0.2);
            doc.setDrawColor(...darkGrayColor);
            doc.line(leftMargin, yPosition, rightMargin, yPosition);
            yPosition += 5;

            doc.setFontSize(7);
            doc.setFont('helvetica', 'bold');
            doc.setTextColor(...darkGrayColor);
            doc.text('NOTAS:', leftMargin, yPosition);
            yPosition += 3;

            doc.setFont('helvetica', 'normal');
            doc.setTextColor(...blackColor);
            const notesLines = doc.splitTextToSize(movementData.notes, 65);
            doc.text(notesLines, leftMargin, yPosition);
            yPosition += notesLines.length * 3.5 + 3;
        }

        // Línea decorativa doble
        doc.setLineWidth(0.3);
        doc.setDrawColor(...darkGrayColor);
        doc.line(leftMargin, yPosition, rightMargin, yPosition);
        yPosition += 0.5;
        doc.setLineWidth(0.2);
        doc.line(leftMargin, yPosition, rightMargin, yPosition);
        yPosition += 6;

        // Información de impresión
        doc.setFontSize(7);
        const currentDate = new Date().toLocaleString('es-MX', {
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit'
        });
        doc.text(`Impreso: ${currentDate}`, centerX, yPosition, { align: 'center' });

        // Guardar o retornar el PDF
        if (autoDownload) {
            const fileName = `movimiento-${badge.label.toLowerCase()}-${movementData.id}.pdf`;
            doc.save(fileName);
        }

        return doc;
    }
};

export default TicketDetailMovement;
