// Archivo: GSYCManufacBOMIng.js
// Ruta: src\static\js\SupYCtrol\GerenteSyC\UtilityMaterials\GSYCManufacBOMIng.js
// Lenguaje: JavaScript

// Elementos del DOM
const loadingIndicator = document.getElementById("loading-indicator");
const bomForm = document.getElementById("bomForm");
const partNumSearch = document.getElementById("partNumSearch");
const partSearchResults = document.getElementById("partSearchResults");
const partNumInput = document.getElementById("partNum");
const revisionInput = document.getElementById("revision");
const resultsDiv = document.getElementById("results");
const processInfo = document.getElementById("processInfo");
const errorAlert = document.getElementById("errorAlert");
const successAlert = document.getElementById("successAlert");
const materialsTableBody = document.querySelector("#materialsTable tbody");
const operationsTableBody = document.querySelector("#operationsTable tbody");

// Variables globales
let searchTimeout;
let currentProcessId = null;

// Función para mostrar el indicador de carga
function showLoading(message = "Cargando...") {
    if (loadingIndicator) {
        loadingIndicator.querySelector("span:last-child").textContent = message;
        loadingIndicator.style.display = "block";
    }
}

// Función para ocultar el indicador de carga
function hideLoading() {
    if (loadingIndicator) {
        loadingIndicator.style.display = "none";
    }
}

// Función para mostrar alertas de error
function showError(message) {
    hideAlert();
    if (errorAlert) {
        document.getElementById("errorMessage").textContent = message;
        errorAlert.style.display = "block";
        setTimeout(() => {
            errorAlert.style.display = "none";
        }, 5000);
    }
}

// Función para mostrar alertas de éxito
function showSuccess(message) {
    hideAlert();
    if (successAlert) {
        document.getElementById("successMessage").textContent = message;
        successAlert.style.display = "block";
        setTimeout(() => {
            successAlert.style.display = "none";
        }, 3000);
    }
}

// Función para ocultar alertas
function hideAlert() {
    if (errorAlert) errorAlert.style.display = "none";
    if (successAlert) successAlert.style.display = "none";
}

// Búsqueda de partes con debounce
partNumSearch.addEventListener("input", function() {
    const query = this.value.trim();
    
    clearTimeout(searchTimeout);
    
    if (query.length < 2) {
        partSearchResults.style.display = "none";
        return;
    }
    
    searchTimeout = setTimeout(() => {
        searchParts(query);
    }, 300);
});

// Función para buscar partes
async function searchParts(query) {
    try {
        showLoading("Buscando partes...");
        
        const response = await fetch(`/SyC/GerenteSyC/UtilityMaterials/GSYCManufacBOMIng/search-parts?q=${encodeURIComponent(query)}`);
        const data = await response.json();
        
        hideLoading();
        
        if (data.success) {
            displaySearchResults(data.parts);
        } else {
            showError(data.error || "Error al buscar partes");
            partSearchResults.style.display = "none";
        }
        
    } catch (error) {
        hideLoading();
        showError("Error de conexión al buscar partes");
        console.error("Error:", error);
    }
}

// Función para mostrar resultados de búsqueda
function displaySearchResults(parts) {
    if (parts.length === 0) {
        partSearchResults.innerHTML = '<div class="list-group-item">No se encontraron partes</div>';
        partSearchResults.style.display = "block";
        return;
    }
    
    const resultsHtml = parts.map(part => `
        <button type="button" class="list-group-item list-group-item-action" 
                onclick="selectPart('${part.PartNum}', '${part.RevisionNum}', '${part.PartDescription}')">
            <div><strong>${part.PartNum}</strong> - Rev: ${part.RevisionNum || 'N/A'}</div>
            <small class="text-muted">${part.PartDescription}</small>
        </button>
    `).join('');
    
    partSearchResults.innerHTML = resultsHtml;
    partSearchResults.style.display = "block";
}

// Función para seleccionar una parte
function selectPart(partNum, revision, description) {
    partNumInput.value = partNum;
    revisionInput.value = revision || '';
    partNumSearch.value = `${partNum} - ${description}`;
    partSearchResults.style.display = "none";
}

// Ocultar resultados al hacer clic fuera
document.addEventListener("click", function(event) {
    if (!partNumSearch.contains(event.target) && !partSearchResults.contains(event.target)) {
        partSearchResults.style.display = "none";
    }
});

// Manejo del formulario de explosión de BOM
bomForm.addEventListener("submit", async function(event) {
    event.preventDefault();
    
    const partNum = partNumInput.value.trim();
    const revision = revisionInput.value.trim();
    
    if (!partNum || !revision) {
        showError("Por favor complete número de parte y revisión");
        return;
    }
    
    await explodeBOM(partNum, revision);
});

// Función para explotar BOM
async function explodeBOM(partNum, revision) {
    try {
        showLoading("Explotando BOM...");
        hideAlert();
        resultsDiv.style.display = "none";
        processInfo.style.display = "none";
        
        const response = await fetch("/SyC/GerenteSyC/UtilityMaterials/GSYCManufacBOMIng/explode", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({
                partNum: partNum,
                revision: revision
            })
        });
        
        const data = await response.json();
        
        hideLoading();
        
        if (data.success) {
            currentProcessId = data.process_id;
            showSuccess("BOM explodida exitosamente");
            await loadBOMData(currentProcessId);
        } else {
            showError(data.error || "Error al explotar BOM");
        }
        
    } catch (error) {
        hideLoading();
        showError("Error de conexión al explotar BOM");
        console.error("Error:", error);
    }
}

// Función para cargar datos de BOM
async function loadBOMData(processId) {
    try {
        showLoading("Cargando datos de BOM...");


        // CALCULO DE EXTCOST DE LOS 'M' DE ORIGEN 'P' Y OPERACIONES
        const calcResponse = await fetch(`/SyC/GerenteSyC/UtilityMaterials/GSYCManufacBOMIng/calculate-costs/${processId}`, {
            method: 'POST'
        });
        const calcData = await calcResponse.json();
        
        if (!calcData.success) {
            showError(calcData.error || "Error al calcular costos");
            hideLoading();
            return;
        }

        console.log("Detalles del cálculo:", {
            totalCalculado: calcData.totalCalculatedCost,
            costosMateriales: calcData.totalMaterialCost,
            costosOperaciones: calcData.totalOperationCost,
            breakdown: calcData.costBreakdown
        });

        //-------------------------------------

        const response = await fetch(`/SyC/GerenteSyC/UtilityMaterials/GSYCManufacBOMIng/get-bom/${processId}`);
        const data = await response.json();
        
        hideLoading();
        
        if (data.success) {
            displayBOMData(data.data);
        } else {
            showError(data.error || "Error al cargar datos de BOM");
        }
        
    } catch (error) {
        hideLoading();
        showError("Error de conexión al cargar BOM");
        console.error("Error:", error);
    }
}

// Función para mostrar datos de BOM
function displayBOMData(bomData) {
    // ✅ Guarda el processId en una variable accesible:
    currentProcessId = bomData.control?.ProcessID || null;

    // Mostrar información del proceso
    if (bomData.control) {
        //document.getElementById("processId").textContent = bomData.control.ProcessID.substring(0, 8) + "...";
        document.getElementById("processId").textContent = bomData.control.ProcessID;
        document.getElementById("processStatus").textContent = bomData.control.Status;
        document.getElementById("processLevels").textContent = bomData.control.MaxLevel;
        document.getElementById("processMaterials").textContent = bomData.control.TotalMaterials;
        document.getElementById("processOperations").textContent = bomData.control.TotalOperations;
        document.getElementById("processTime").textContent = bomData.control.ProcessingTime_MS;
        document.getElementById('totalCostDisplay').textContent = 'Calculando...';
        processInfo.style.display = "block";

        getTotalCost(bomData.control.ProcessID, bomData.control.PartNumFather, bomData.control.RevisionNumFather);
    }
    
    
    // Mostrar materiales
    displayMaterials(bomData.materials || []);
    
    // Mostrar operaciones
    displayOperations(bomData.operations || []);
    
    // Mostrar contenedor de resultados
    resultsDiv.style.display = "block";
}


//----------------------------------------------------------
// Ejemplo de llamada desde JavaScript
// Modificar la función getTotalCost para manejar mejor los errores
function getTotalCost(processId, partNum, revision) {
    // Validar processId antes de hacer la llamada
    if (!processId || processId.length < 36) {
        console.error('ProcessID inválido:', processId);
        document.getElementById('totalCostDisplay').textContent = 'Error: ProcessID inválido';
        return;
    }

    fetch(`/SyC/GerenteSyC/UtilityMaterials/GSYCManufacBOMIng/get-total-cost?processId=${processId}&partNum=${partNum}&revision=${revision}`)
        .then(response => {
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json();
        })
        .then(data => {
            if (data.success) {
                document.getElementById('totalCostDisplay').textContent = `$${data.totalCost.toLocaleString('en-US')}`;
            } else {
                console.error('Error del servidor:', data.error);
                document.getElementById('totalCostDisplay').textContent = `Error: ${data.error || 'Desconocido'}`;
            }
        })
        .catch(error => {
            console.error('Error en la solicitud:', error);
            document.getElementById('totalCostDisplay').textContent = 'Error: Conexión fallida';
        });
}
//-----------------------------------------------------




// Función para mostrar materiales
function displayMaterials(materials) {
    materialsTableBody.innerHTML = "";
    
    materials.forEach(material => {
        try {
            const row = document.createElement("tr");
            row.className = `level-${material.Level}`;
            // ✅ Agrega estos dos atributos para guardar los datos clave:
            row.dataset.processId = currentProcessId;  // Asegura que currentProcessId está definido
            row.dataset.partNum = material.PartNum;    // Usa el PartNum de la fila actual
            
            const indent = "　".repeat(material.Level);
            
            // Manejo seguro de fechas y costos
            const tranDate = material.TranDate ? 
                new Date(material.TranDate).toLocaleDateString() : 'N/A';               
                      
            row.innerHTML = `
                <td><span class="badge bg-info">${material.Level || 0}</span></td>
                <td>${material.Seq}</td>
                <td><span class="badge ${material.Type === 'M' ? 'bg-warning' : 'bg-secondary'}">
                    ${material.TipoDesc || (material.Type === 'M' ? 'Fabricado' : 'Material')}
                </span></td>
                <td><strong>${indent}${material.PartNum}</strong></td>
                <td>${material.Rev || 'N/A'}</td>
                <td title="${material.PartDescription || ''}">${material.ShortDescription || ''}</td>
                <td class="text-end">${parseFloat(material.QtyPer || 0).toFixed(4)}</td>
                <td>${material.UOMCode || ''}</td> 
                <td>${material.TranNum || ''}</td> 
                <td class="text-end">${tranDate && tranDate !== 'N/A' ? tranDate : ''}</td>
                <td class="text-end">${material.MtlUnitCost || ''}</td>
                <td class="text-end">${material.LbrUnitCost || ''}</td>
                <td class="text-end">${material.BurUnitCost || ''}</td>
                <td class="text-end">${material.SubUnitCost || ''}</td>
                <td class="text-end">${material.MtlBurUnitCost || ''}</td>
                <td class="text-end">${parseFloat(material.ExtCost || 0).toFixed(5)}</td>
                <td>${material.PO|| ''}</td>
                <td>${material.Type === 'P' ? (material.Line || '0') : (material.Line || '')}</td>                
                <th>
                    <span class="badge 
                        ${material.Status === 'COSTEADOS' ? 'bg-primary' : 
                        material.Status === 'REVISION' ? 'bg-warning' : 
                        material.Status === 'INSERTAR' ? 'bg-danger' : 
                        material.Status === 'CALCULADO' ? 'text-black' : ''}"
                        style="${material.Status === 'CALCULADO' ? 'color: black !important;' : ''}">
                        ${material.Status || ''}
                    </span>
                </th>
                <td class="text-end fw-bold ext-cost-cell">
                    <button class="btn btn-primary btn-editar ${material.Type === 'M' ? 'd-none' : ''}" 
                            data-bs-toggle="modal" data-bs-target="#editExtCostModal">
                        Editar
                    </button>
                </td>
            `;            

            
            materialsTableBody.appendChild(row);
        } catch (error) {
            console.error("Error al mostrar material:", material, error);
        }
    });
}

// Función para mostrar operaciones
function displayOperations(operations) {
    operationsTableBody.innerHTML = "";
    
    operations.forEach(operation => {
        const row = document.createElement("tr");
        row.className = `level-${operation.Level}`;
        
        // Agregar indentación visual basada en el nivel
        const indent = "　".repeat(operation.Level);
        
        row.innerHTML = `
            <td><span class="badge bg-info">${operation.Level}</span></td>
            <td><span class="badge ${operation.Type ? 'bg-danger' : 'bg-success'}">${operation.Type ? 'Subcontrato' : 'Mano de Obra'}</span></td>
            <td><strong>${indent}${operation.OpCode}</strong></td>
            <td title="${operation.OpDesc}">${operation.ShortDescription}</td>
            <td class="text-end">${parseFloat(operation.EstProdHours).toFixed(2)}</td>
            <td>${operation.UOMCode}</td>
            <th></th>
            <th></th>
            <td class="text-end">${parseFloat(operation.MtlUnitCost || 0).toFixed(5)}</td>
            <td class="text-end">${parseFloat(operation.LbrUnitCost || 0).toFixed(5)}</td>  
            <td class="text-end">${parseFloat(operation.BurUnitCost || 0).toFixed(5)}</td>
            <td class="text-end">${parseFloat(operation.SubUnitCost || 0).toFixed(5)}</td>
            <td class="text-end">${parseFloat(operation.MtlBurUnitCost || 0).toFixed(5)}</td>
            <td class="text-end">${parseFloat(operation.ExtCost || 0).toFixed(5)}</td>
            <th></th>
            <th></th>
            <th></th>      
        `;
        
        operationsTableBody.appendChild(row);
    });
}

// Funciones de utilidad para formatear datos
function formatNumber(num, decimals = 2) {
    return parseFloat(num).toFixed(decimals);
}

function formatCurrency(num) {
    return new Intl.NumberFormat('es-MX', {
        style: 'currency',
        currency: 'MXN'
    }).format(num);
}

// Función para exportar datos (funcionalidad futura)
function exportBOM(format = 'excel') {
    if (!currentProcessId) {
        showError("No hay datos de BOM para exportar");
        return;
    }
    
    // Implementar exportación
    showSuccess(`Exportando BOM en formato ${format}...`);
}


/**
 * INICIALIZA LA FUNCIONALIDAD DEL MODAL PARA EDITAR (EXTCOST)
 * ABRE EL MODAL, VALIDACIONES DE ENTRADA Y ACTUALIZACIÓN DE DATOS
 * SE CONECTA CON LOS BOTONES DE EDITAR DE LA TABLA MATERIALS
 * DEL ARCHIVO: GSYCManufacBOMIngSQL.py
 * Ruta: src\Consultas_SQL\SupYCtrol\GerenteSyC\UtilityMaterials\GSYCManufacBOMIngSQL.py
 * DE LA FUNCION def _get_status_manual
 */

// Función para inicializar el modal de edición
function initExtCostModal() {
    // Variables de estado dentro del ámbito de la función
    let currentRowExtCost = null;
    let currentProcessId = null;
    let currentPartNum = null;
    let currentExtCost = 0;

    // Función para mostrar icono de error dentro del input
    function showInputError(input, message) {
        // Limpiar iconos previos
        const existingIcon = input.parentElement.querySelector('.error-icon');
        if (existingIcon) existingIcon.remove();
        
        // Crear icono de error
        const errorIcon = document.createElement('i');
        errorIcon.className = 'error-icon bi bi-exclamation-circle-fill text-danger';
        Object.assign(errorIcon.style, {
            position: 'absolute',
            right: '10px',
            top: '50%',
            transform: 'translateY(-50%)',
            zIndex: '10'
        });
        errorIcon.title = message;
        
        // Asegurar posicionamiento relativo
        input.parentElement.style.position = 'relative';
        input.parentElement.appendChild(errorIcon);
        
        // Añadir padding para no solapar texto
        input.style.paddingRight = '30px';
        input.classList.add('is-invalid');
    }

    document.addEventListener('click', function(e) {
        if (e.target.classList.contains('btn-editar')) {
            currentRowExtCost = e.target.closest('tr');
            currentProcessId = currentRowExtCost.dataset.processId;
            currentPartNum = currentRowExtCost.dataset.partNum;
            currentExtCost = parseFloat(currentRowExtCost.cells[15].textContent.trim()) || 0;
            
            console.log('Datos para edición:', {
                processId: currentProcessId,
                partNum: currentPartNum,
                currentExtCost: currentExtCost
            });

            document.getElementById('currentExtCostDisplay').value = currentExtCost.toFixed(5);
            document.getElementById('extCostInput').value = '';
            
            const input = document.getElementById('extCostInput');
            input.classList.remove('is-invalid');
            input.style.paddingRight = ''; // Reset padding
            const feedback = input.parentElement.querySelector('.invalid-feedback');
            if (feedback) feedback.remove();

            const existingIcon = input.parentElement.querySelector('.error-icon, .input-warning-icon');
            if (existingIcon) existingIcon.remove();
        }
    });

    // VALIDACIÓN EN TIEMPO REAL
    document.getElementById('extCostInput').addEventListener('input', function() {
        const saveBtn = document.getElementById('saveExtCostBtn');
        const input = this;
        const newValue = parseFloat(input.value) || 0;
        
        // Limpiar validaciones previas
        input.classList.remove('is-invalid');
        input.style.paddingRight = '';
        const existingFeedback = input.parentElement.querySelector('.invalid-feedback');
        if (existingFeedback) existingFeedback.remove();
        
        // Limpiar iconos previos
        const existingIcon = input.parentElement.querySelector('.error-icon, .input-warning-icon');
        if (existingIcon) existingIcon.remove();

        const errorMessage = validateExtCost(input.value);
        
        if (errorMessage) {
            showInputError(input, errorMessage);
            saveBtn.disabled = true;
        } else if (newValue <= currentExtCost) {
            showInputError(input, 'El valor debe ser mayor al actual');
            saveBtn.disabled = true;
        } else {
            saveBtn.disabled = false;
        }
    });

    // GUARDAR CAMBIOS
    document.getElementById('saveExtCostBtn').addEventListener('click', async function() {
        const btn = this;
        const modal = bootstrap.Modal.getInstance(document.getElementById('editExtCostModal'));
        const input = document.getElementById('extCostInput');
        const newValue = input.value.trim();

        if (!newValue) {
            showInputError(input, 'Ingrese un valor para el costo');
            input.focus();
            return;
        }

        const numericNewValue = parseFloat(newValue);
        if (numericNewValue <= currentExtCost) {
            showInputError(input, 'El nuevo valor debe ser mayor al valor actual');
            input.focus();
            return;
        }

        try {
            btn.disabled = true;
            btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Guardando...';

            const response = await fetch('/SyC/GerenteSyC/UtilityMaterials/GSYCManufacBOMIng/update-cost', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    newExtCost: numericNewValue,
                    processId: currentProcessId,
                    partNum: currentPartNum
                })
            });

            const data = await response.json();

            if (data.success) {
                showSuccess("Costo actualizado exitosamente");
                modal.hide();
                if (currentRowExtCost) {
                    currentRowExtCost.cells[15].textContent = parseFloat(newValue).toFixed(5);
                    currentRowExtCost.cells[18].innerHTML = '<span class="badge bg-success">MANUAL</span>';
                }
            } else {
                showError(data.error || "Error al actualizar el costo");
            }

        } catch (error) {
            showError("Error de conexión");
            console.error('Error:', error);
        } finally {
            btn.disabled = false;
            btn.textContent = 'Guardar';
        }
    });
}

document.addEventListener('DOMContentLoaded', initExtCostModal);