import imagen_presupuesto from "./imagen-presupuesto.js";
import ServiceOptionCard from "./service-option-card.js";
import TiradaCard from "./tirada-price-card.js";
import * as Summary from "./summary.js";
import { formateaMoneda } from "../utils.js";

class PresupuestoCliente {

    constructor() {

        this.DEBUG = true; // Activar o desactivar el modo de depuración

        this.formData = {
            datosGenerales: {
                titulo: '',
                autor: '',
                isbn: '',
                tirada1: '',
                tirada2: '',
                tirada3: '',
                tirada4: '',
                ancho: '',
                alto: '',
                formatoPersonalizado: false,
                paginasNegro: '',
                paginasColor: '',
                posicionPaginasColor: '',
                tipoEncuadernacion: 'fresado',
            },
            interior: {
                tipoImpresion: 'negro',
                papelInteriorId: 3,
                gramajeInterior: 80,
            },
            cubierta: {
                tipoCubierta: 'tapaBlanda',
                solapasCubierta: 0,
                tamanioSolapasCubierta: '80',
                cubiertaCaras: 2,
                papelGuardasId: 3,
                gramajeGuardas: 170,
                guardasImpresas: 0,
                cabezada: 'WHI',
                papelCubiertaId: 3,
                gramajeCubierta: 170,
                acabado: 1,
                sobrecubierta: {
                    activo: false,
                    papelSobrecubiertaId: 2,
                    gramajeSobrecubierta: 170,
                    tamanioSolapasSobrecubierta: 80,
                    acabado: 0
                },
                faja: {
                    activo: false,
                    papelFajaId: 2,
                    gramajeFaja: 170,
                    alto: 50,
                    tamanioSolapasFaja: 80,
                    acabado: 0
                }
            },
            servicios: {
                servicios: [],
                datosMarcapaginas: {
                    marcapaginas_tirada: 100,
                    tamanio_marcapaginas: '_50x140_',
                    caras_impresion: 'una_cara',
                    papel_marcapaginas: 'cartulina_grafica',
                    gramaje_marcapaginas: 300,
                    acabado_marcapaginas: 'ninguno',
                    resultado: {
                        precio_unitario: 0,
                        precio: 0
                    }
                },
                datosMaquetacion: {
                    num_caracteres: 200000,
                    formato_maquetacion: 'A5',
                    cuerpo_texto: 'medium',
                    num_columnas: 1,
                    num_tablas: 0,
                    num_fotos: 0,
                    correccion_ortotipografica: false,
                    texto_mecanografiado: false,
                    disenio_portada: false,
                    epub: false,
                    resultado: {
                        num_paginas_estimadas: 0,
                        precio_pagina_estimado: 0,
                        precio: 0
                    }
                }
            },
            selectedTirada: null,
        }

        // pestaña datos generales
        this.divContentDatosGenerales = $('#content-datos-generales');
        this.titulo = $('#titulo');
        this.autor = $('#autor');
        this.isbn = $('#isbn');
        this.tirada1 = $('#tirada1');
        this.tirada2 = $('#tirada2');
        this.tirada3 = $('#tirada3');
        this.tirada4 = $('#tirada4');
        this.formatoPersonalizado = $('#formato-personalizado');
        this.divFormato = $('.div-formato');
        this.divFormatoPersonalizado = $('.div-formato-personalizado');
        this.formato = $('#formato');
        this.ancho = $('#ancho');
        this.alto = $('#alto');
        this.paginasNegro = $('#paginas-negro');
        this.paginasColor = $('#paginas-color');
        this.divPosicionPaginasColor = $('#div-posicion-paginas-color');
        this.posicionPaginasColor = $('#posicionPaginasColor');
        this.paginas = $('#paginas');
        this.btn_next_datos_generales = $('#next-datos-generales');
        this.datos_generales_alert = $('#datos-generales-alert');

        // pestaña interior
        this.divContentInterior = $('#content-interior');
        this.divOpcionesColor = $('#div-opciones-color');
        this.divPapelInterior = $('#div-papel-interior');
        this.divGramajeInterior = $("#div-gramaje-interior");
        this.interior_alert = $('#interior-alert');

        // pestaña cubierta
        this.divSolapasCubierta = $('#div-solapas-cubierta');
        this.divPapelCubierta = $('#div-papel-cubierta');
        this.divGramajeCubierta = $("#div-gramaje-cubierta");
        this.btn_plantilla_cubierta = $('#btn-plantilla-cubierta');
        this.btn_impresion_cubierta_help = $('#impresion-cubierta-help');
        this.carasImpresionCubierta = $('#impresion-cubierta');
        this.tamanioSolapasCubierta = $('#tamanio-solapas-cubierta');
        this.guardasCubierta = $('#papel-guardas');
        this.guardasImpresas = $('#guardas-impresas');
        this.cabezada = $('#cabezada');
        this.divAcabadoCubierta = $('#div-acabado-cubierta');
        this.divSobrecubierta = $('#div-sobrecubierta');
        this.divFaja = $('#div-faja');
        this.acabadoSobrecubierta = $('#sobrecubierta-acabado');
        this.fajaSobrecubierta = $('#faja-acabado');
        this.sobrecubierta = $('#sobrecubierta');
        this.papelSobrecubierta = $('#papel-sobrecubierta');
        this.solapasSobrecubierta = $('#tamanio-solapas-sobrecubierta');
        this.faja = $('#faja');
        this.papelFaja = $('#papel-faja');
        this.altoFaja = $('#alto-faja');
        this.solapasFaja = $('#tamanio-solapas-faja');
        this.acabadoFaja = $('#faja-acabado');

        // seleccion tirada
        this.divTiradas = $('#div-tiradas');
        this.divTiradasError = $('#div-tiradas-error');

        // pestaña extras
        this.divExtras = $('#div-extras');

        // pestaña resumen
        this.tablaResumen = $('#resumen-tabla-final');

        // resumen
        this.summaryTableInterior = $('#summary-interior');
        this.summaryTableCubierta = $('#summary-cubierta');
        this.summaryTableSobrecubierta = $('#summary-sobrecubierta');
        this.summaryTableFaja = $('#summary-faja');
        this.summaryTableExtras = $('#summary-servicios-extras');
    }

    init() {

        const stored = sessionStorage.getItem("formData");

        this.#initDatosGenerales();
        this.#initCubierta();

        if (stored) {
            this.formData = JSON.parse(stored);
            this.#loadDatosGeneralesData();
        }

        Summary.updateEncuadernacion();
        Summary.updateFormato();
        Summary.updatePaginas();


        this.#initInterior();
        this.#initSeleccionTirada();
        this.#initExtras();
        this.#initResumen();

        $(document).on('change', 'input[min][max]', function () {
            const $input = $(this);
            let valor = parseFloat($input.val());
            const min = parseFloat($input.attr('min'));
            const max = parseFloat($input.attr('max'));

            if (isNaN(valor)) return;

            if (valor < min) {
                $input.val(min);
            } else if (valor > max) {
                $input.val(max);
            }
        });

    }

    #cacheFormData() {
        sessionStorage.setItem("formData", JSON.stringify(this.formData));
    }

    #changeTab(idContenidoTab) {
        const tabButton = document.querySelector(`[data-bs-target="#${idContenidoTab}"]`);
        if (tabButton) {
            bootstrap.Tab.getOrCreateInstance(tabButton).show();
        }
    }

    #getPresupuestoData() {
        let data = {
            ...this.#getDatosGeneralesData(),
            ...this.#getInteriorData(),
            ...this.#getCubiertaData(),
            selectedTirada: this.formData.selectedTirada
        };

        const sobrecubierta = data.sobrecubierta;
        const faja = data.faja;

        delete data.sobrecubierta;
        delete data.faja;
        data = {
            ...data,
            sobrecubierta: sobrecubierta.activo,
            papelSobrecubiertaId: sobrecubierta.papelSobrecubiertaId,
            gramajeSobrecubierta: sobrecubierta.gramajeSobrecubierta,
            tamanioSolapasSobrecubierta: sobrecubierta.tamanioSolapasSobrecubierta,
            acabadoSobrecubierta: sobrecubierta.acabado,
            faja: faja.activo,
            papelFajaId: faja.papelFajaId,
            gramajeFaja: faja.gramajeFaja,
            altoFaja: faja.alto,
            tamanioSolapasFaja: faja.tamanioSolapasFaja,
            acabadoFaja: faja.acabado
        }

        return data;

    }

    #addGramaje(contenedor, id_base, gramaje, name) {

        const id = `${id_base}-${gramaje}`;

        // Crear input
        const input = document.createElement('input');
        input.type = 'radio';
        input.className = 'btn-check';
        input.dataset.gramaje = gramaje;
        input.id = id;
        input.name = name;

        // Crear label
        const label = document.createElement('label');
        label.className = 'btn btn-opcion-presupuesto material-shadow gramaje-radio ' + name;
        label.setAttribute('for', id);
        label.textContent = gramaje;

        // Añadir al contenedor
        contenedor.append(input);
        contenedor.append(label);
    }


    /******************************
     * DATOS GENERALES
     ******************************/
    #initDatosGenerales() {

        $('.datos-generales-data').on('change', () => {
            const dataToStore = this.#getDatosGeneralesData();
            this.#updateDatosGeneralesData(dataToStore);
            this.#cacheFormData();
        });

        $('.paginas').on('change', () => {
            $('#paginas').val(parseInt(this.paginasNegro.val()) + parseInt(this.paginasColor.val()));
            if (parseInt(this.paginasColor.val()) == 0) {
                this.divPosicionPaginasColor.addClass('d-none');
                this.posicionPaginasColor.val("");
            }
            else {
                this.divPosicionPaginasColor.removeClass('d-none');
            }
            $('#paginas').val(parseInt(this.paginasNegro.val()) + parseInt(this.paginasColor.val()));
            Summary.updatePaginas();
            this.#updateTipoEncuadernacion();
        });

        this.formatoPersonalizado.on('change', () => {
            if (this.formatoPersonalizado.is(':checked')) {
                this.divFormato.addClass('d-none');
                this.divFormatoPersonalizado.removeClass('d-none');
            }
            else {
                this.divFormatoPersonalizado.addClass('d-none');
                this.divFormato.removeClass('d-none');
            }
            Summary.updateFormato();
        });

        this.btn_next_datos_generales.on('click', () => {
            this.#nextDatosGenerales();
        });

        // Eventos para el resumen
        $(document).on('change', 'input[name="tipoEncuadernacion"]', (e) => {
            if ($(e.target).is(':checked')) {
                // Actualizar el resumen
                Summary.updateEncuadernacion();
            }
        });

        this.formato.on('change', () => {
            Summary.updateFormato();
        });

        this.ancho.on('change', () => {
            Summary.updateFormato();
        });
        this.alto.on('change', () => {
            Summary.updateFormato();
        });
    }

    #nextDatosGenerales() {

        let data = this.#getDatosGeneralesData();
        data = {
            ...data,
            ...{
                papelInteriorId: this.formData.interior.papelInteriorId,
                gramajeInterior: this.formData.interior.gramajeInterior,
                tipoImpresion: this.formData.interior.tipoImpresion,
            }
        }

        $.ajax({
            url: '/presupuesto/public/validar/datos-generales',
            type: 'POST',
            data: data,
            success: (data) => {
                this.#processDatosGenerales(data);
            },
            error: (xhr, status, error) => {

                this.datos_generales_alert.removeClass('d-none');
                this.datos_generales_alert.find('#datos-generales-alert-list').empty();
                const errors = xhr.responseJSON;
                if (errors && typeof errors === 'object') {
                    if (!this.DEBUG && xhr.responseJSON.error && xhr.responseJSON.error == 'Internal Server Error') {
                        console.error("Error al validar los datos generales. Internal Server Error");
                        return;
                    }
                    Object.values(errors).forEach(errorMsg => {
                        this.datos_generales_alert.find('#datos-generales-alert-list').append(`<li>${errorMsg}</li>`);
                    });
                } else {
                    this.datos_generales_alert.find('#datos-generales-alert-list').append('<li>Error desconocido. Por favor, inténtelo de nuevo más tarde.</li>');
                }
                $(window).scrollTop(0);
            }
        });
    }

    #processDatosGenerales(data) {

        this.datos_generales_alert.addClass('d-none');

        $('.alto-faja-max').text(`max: ${this.formData.datosGenerales.alto} mm`);

        this.#loadInteriorData(data);

        const interiorData = this.#getInteriorData();
        this.#updateInteriorData(interiorData);

        this.#changeTab('pills-inside');

        this.divContentInterior.addClass('animate-fadeInUpBounce');
    }

    #getDatosGeneralesData() {

        const tamanio = this.#getTamanio();

        return {
            titulo: this.titulo.val(),
            autor: this.autor.val(),
            isbn: this.isbn.val(),
            tirada1: this.tirada1.val(),
            tirada2: this.tirada2.val(),
            tirada3: this.tirada3.val(),
            tirada4: this.tirada4.val(),
            formatoPersonalizado: this.formatoPersonalizado.is(':checked'),
            ancho: parseInt(tamanio.ancho),
            alto: parseInt(tamanio.alto),
            paginasNegro: this.paginasNegro.val(),
            paginasColor: this.paginasColor.val(),
            posicionPaginasColor: this.posicionPaginasColor.val(),
            tipoEncuadernacion: ($('.tipo-libro.selected').length > 0) ? $('.tipo-libro.selected').attr('id') : 'fresado',
        };
    }

    #updateDatosGeneralesData(data) {

        this.formData.datosGenerales = {
            titulo: data.titulo,
            autor: data.autor,
            isbn: data.isbn,
            tirada1: data.tirada1,
            tirada2: data.tirada2,
            tirada3: data.tirada3,
            tirada4: data.tirada4,
            formatoPersonalizado: data.formatoPersonalizado,
            ancho: parseInt(data.ancho),
            alto: parseInt(data.alto),
            paginasNegro: data.paginasNegro,
            paginasColor: data.paginasColor,
            posicionPaginasColor: data.posicionPaginasColor,
            tipoEncuadernacion: data.tipoEncuadernacion,
        };
    }

    #loadDatosGeneralesData() {

        this.titulo.val(this.formData.datosGenerales.titulo);
        this.autor.val(this.formData.datosGenerales.autor);
        this.isbn.val(this.formData.datosGenerales.isbn);
        this.tirada1.val(this.formData.datosGenerales.tirada1);
        this.tirada2.val(this.formData.datosGenerales.tirada2);
        this.tirada3.val(this.formData.datosGenerales.tirada3);
        this.tirada4.val(this.formData.datosGenerales.tirada4);

        this.paginasNegro.val(this.formData.datosGenerales.paginasNegro);
        this.paginasColor.val(this.formData.datosGenerales.paginasColor);

        this.posicionPaginasColor.val(this.formData.datosGenerales.posicionPaginasColor);

        this.formatoPersonalizado.prop('checked', this.formData.datosGenerales.formatoPersonalizado);
        if (this.formData.datosGenerales.formatoPersonalizado) {
            this.ancho.val(this.formData.datosGenerales.ancho);
            this.alto.val(this.formData.datosGenerales.alto);
        }

        $('.tipo-libro').removeClass('selected');
        $('.image-container#' + this.formData.datosGenerales.tipoEncuadernacion).trigger('click');
        this.#updateTipoEncuadernacion();

        this.formatoPersonalizado.trigger('change');

        $('.paginas').trigger('change');

        if (this.formatoPersonalizado.is(':checked')) {
            this.ancho.val(this.formData.datosGenerales.ancho);
            this.alto.val(this.formData.datosGenerales.alto);
        } else {
            const option = this.formato.find('option').filter(() => {
                return $(this).data('ancho') == this.formData.datosGenerales.ancho &&
                    $(this).data('alto') == this.formData.datosGenerales.alto;
            });

            if (option.length) {
                this.formato.val(option.val()).trigger('change');
            }
        }
    }

    #getTamanio() {

        if (this.formatoPersonalizado.is(':checked')) {
            return {
                ancho: this.ancho.val(),
                alto: this.alto.val()
            };
        }
        else {
            const opcionSeleccionada = $('#formato option:selected');
            const ancho = opcionSeleccionada.data('ancho');
            const alto = opcionSeleccionada.data('alto');
            return {
                ancho: ancho,
                alto: alto
            };
        }
    }

    #updateTipoEncuadernacion() {

        const paginas = parseInt($('#paginas').val());
        const selectedTipo = $('.tipo-libro.selected').attr('id');
        $('.tipo-libro').removeClass('selected');

        if (paginas < 32) {
            $('.tipo-libro#fresado').addClass('d-none');
            $('.tipo-libro#cosido').addClass('d-none');
        }
        else {
            $('.tipo-libro#fresado').removeClass('d-none');
            $('.tipo-libro#cosido').removeClass('d-none');
        }
        if (paginas < 20) {
            $('.tipo-libro#espiral').addClass('d-none');
            $('.tipo-libro#wireo').addClass('d-none');
        }
        else {
            $('.tipo-libro#espiral').removeClass('d-none');
            $('.tipo-libro#wireo').removeClass('d-none');
        }
        if (paginas < 12 || paginas > 40) {
            $('.tipo-libro#grapado').addClass('d-none');
        }
        else {
            $('.tipo-libro#grapado').removeClass('d-none');
        }

        if (selectedTipo && $('.tipo-libro#' + selectedTipo).length > 0 && !$('.tipo-libro#' + selectedTipo).hasClass('d-none')) {
            $('.tipo-libro#' + selectedTipo).addClass('selected');
        }
        else {
            let firstVisible = $('.tipo-libro').not('.d-none').first();

            if (firstVisible.length) {
                firstVisible.addClass('selected');
            }
        }

        if ($('.tipo-libro.selected').length > 0) {
            this.formData.datosGenerales.tipoEncuadernacion = $('.tipo-libro.selected').attr('id');
            Summary.updateEncuadernacion();
        }
        else {
            this.formData.datosGenerales.tipoEncuadernacion = '';
        }
    }
    /******************************
     * END OF DATOS GENERALES
     ******************************/


    /******************************
     * INTERIOR
     ******************************/

    #initInterior() {

        $(document).on('click', '.interior-data', (e) => {
            const dataToStore = this.#getInteriorData();
            this.#updateInteriorData(dataToStore);
            this.#cacheFormData();
        });


        $(document).on('click', '.opcion-color', (e) => {

            const data = this.#getPresupuestoData();
            Summary.updateTipoImpresion();

            this.divPapelInterior.empty();
            this.divGramajeInterior.empty();

            this.divPapelInterior.removeClass('animate-fadeInUpBounce');
            this.divGramajeInterior.removeClass('animate-fadeInUpBounce');

            $.ajax({
                url: '/presupuesto/public/get-papel-interior',
                type: 'POST',
                data: data,
                success: (data) => {

                    this.divPapelInterior.addClass('animate-fadeInUpBounce');
                    this.divGramajeInterior.addClass('animate-fadeInUpBounce');

                    const opciones_papel_interior = data.opciones_papel_interior;
                    for (let i = 0; i < opciones_papel_interior.length; i++) {
                        const opcion = opciones_papel_interior[i];
                        const item = new imagen_presupuesto(opcion);
                        item.extraClass = 'interior-data papel-interior';
                        if (opcion.id === this.formData.interior.papelInteriorId) {
                            item.setSelected(true);
                        }
                        this.divPapelInterior.append(item.render());
                    }

                    const gramajes = data.opciones_gramaje_interior;

                    const maxSolapas = data.solapas ?? 120;
                    $('.solapas-presupuesto').attr('max', maxSolapas);
                    $('.max-solapa-text').text(function (_, textoActual) {
                        return textoActual.replace(/\d+/, maxSolapas);
                    });

                    this.#addGramajesInterior(gramajes);

                    Summary.updatePapelInterior();
                    Summary.updateGramajeInterior();
                },
                error: (xhr, status, error) => {

                    console.error("Error al obtener los papeles de interior: ", xhr.responseText);
                }
            });
        });

        $(document).on('click', '.papel-interior', (e) => {

            const data = this.#getPresupuestoData();

            Summary.updatePapelInterior();

            this.divGramajeInterior.removeClass('animate-fadeInUpBounce');
            this.divGramajeInterior.empty();

            $.ajax({
                url: '/presupuesto/public/get-gramaje-interior',
                type: 'POST',
                data: data,
            }).done((data) => {

                const gramajes = data.opciones_gramaje_interior;
                this.#addGramajesInterior(gramajes);
                this.divGramajeInterior.addClass('animate-fadeInUpBounce');

                const maxSolapas = data.solapas ?? 120;
                $('.solapas-presupuesto').attr('max', maxSolapas);
                $('.max-solapa-text').text(function (_, textoActual) {
                    return textoActual.replace(/\d+/, maxSolapas);
                });

                const dataInterior = this.#getInteriorData();
                this.#updateInteriorData(dataInterior);
                this.#cacheFormData();
                Summary.updateGramajeInterior();

            }).fail((xhr, status, error) => {
                console.error("Error al obtener los gramajes de interior: ", xhr.responseText);
            });
        });

        $(document).on('click', '.gramaje-interior', (e) => {

            const inputId = $(e.currentTarget).attr('for');
            const gramaje = parseInt($('#' + inputId).data('gramaje'));
            this.formData.interior.gramajeInterior = gramaje;
            this.#cacheFormData();

            const data = this.#getPresupuestoData();

            $.ajax({
                url: '/presupuesto/public/get-max-solapas',
                type: 'POST',
                data: data,
            }).done((data) => {

                const maxSolapas = data.solapas ?? 120;
                $('.solapas-presupuesto').attr('max', maxSolapas);
                $('.max-solapa-text').text(function (_, textoActual) {
                    return textoActual.replace(/\d+/, maxSolapas);
                });

                Summary.updateGramajeInterior();

            }).fail((xhr, status, error) => {
                console.error("Error al obtener los gramajes de interior: ", xhr.responseText);
            });
        });

        $('.btn-change-tab-interior').on('click', (e) => {

            let data = this.#getPresupuestoData();
            const id = e.currentTarget.id;

            $.ajax({
                url: '/presupuesto/public/validar/interior',
                type: 'POST',
                data: data,
                success: (data) => {
                    if (id === 'btn-prev-interior') {
                        this.summaryTableInterior.addClass('d-none');
                        this.#changeTab('pills-general-data');
                    } else {
                        const maxSolapas = data.solapas ?? 120;
                        $('.solapas-presupuesto').attr('max', maxSolapas);
                        $('.max-solapa-text').text(function (_, textoActual) {
                            return textoActual.replace(/\d+/, maxSolapas);
                        });

                        this.divAcabadoCubierta.empty();
                        this.acabadoSobrecubierta.empty();
                        this.fajaSobrecubierta.empty();
                        for (const opcion of data.opciones_acabados_cubierta) {
                            const item = `
                                <input type="radio" class="btn-check acabado-cubierta-check" id="acabado-cubierta-${opcion['sk-id']}" name="acabado-cubierta" sk-id="${opcion['sk-id']}">
                                <label class="btn btn-opcion-presupuesto material-shadow" for="acabado-cubierta-${opcion['sk-id']}">
                                    ${opcion.name}
                                </label>
                            `;
                            this.divAcabadoCubierta.append(item);
                            this.acabadoSobrecubierta.append(new Option(opcion.name, opcion['sk-id']));
                            this.fajaSobrecubierta.append(new Option(opcion.name, opcion['sk-id']));
                        };

                        $(`input[type="radio"][name="acabado-cubierta"][sk-id="${this.formData.cubierta.acabado}"]`).prop('checked', true);
                        this.acabadoSobrecubierta.val(this.formData.cubierta.sobrecubierta.acabado);
                        this.fajaSobrecubierta.val(this.formData.cubierta.faja.acabado);

                        this.#loadCubiertaData();
                        this.summaryTableCubierta.removeClass('d-none');
                        if (this.sobrecubierta.hasClass('active')) {
                            this.summaryTableSobrecubierta.removeClass('d-none');
                            Summary.updateSobreCubierta();
                        }
                        if (this.faja.hasClass('active')) {
                            this.summaryTableFaja.removeClass('d-none');
                            Summary.updateFaja();
                        }

                        this.#changeTab('pills-cover');

                        const dataCubierta = this.#getCubiertaData();
                        this.#updateCubiertaData(dataCubierta);
                        this.#cacheFormData();

                    }
                },
                error: (xhr, status, error) => {

                    this.interior_alert.removeClass('d-none');
                    this.interior_alert.find('#inside-alert-list').empty();
                    const errors = xhr.responseJSON;
                    if (errors && typeof errors === 'object') {
                        if (!this.DEBUG && xhr.responseJSON.error && xhr.responseJSON.error == 'Internal Server Error') {
                            console.error("Error al validar los datos generales. Internal Server Error");
                            return;
                        }
                        Object.values(errors).forEach(errorMsg => {
                            this.interior_alert.find('#inside-alert-list').append(`<li>${errorMsg}</li>`);
                        });
                    } else {
                        this.interior_alert.find('#inside-alert-list').append('<li>Error desconocido. Por favor, inténtelo de nuevo más tarde.</li>');
                    }
                    $(window).scrollTop(0);
                }
            });
        });
    }

    #loadInteriorData(data) {

        this.summaryTableInterior.removeClass('d-none');

        this.divOpcionesColor.empty();
        this.divPapelInterior.empty();
        this.divGramajeInterior.empty();

        const opciones_color = data.opciones_color;

        for (let i = 0; i < opciones_color.length; i++) {
            const opcion = opciones_color[i];
            const item = new imagen_presupuesto(opcion);
            item.extraClass = 'interior-data opcion-color';
            if ((this.formData.interior.tipoImpresion === '' && i === 0) ||
                this.formData.interior.tipoImpresion === opcion.id) {
                item.setSelected(true);
            }
            this.divOpcionesColor.append(item.render());
        }

        const opciones_papel_interior = data.opciones_papel_interior;
        for (let i = 0; i < opciones_papel_interior.length; i++) {
            const opcion = opciones_papel_interior[i];
            const item = new imagen_presupuesto(opcion);
            item.extraClass = 'interior-data papel-interior';
            if (this.formData.interior.papelInteriorId == '' && i === 0 ||
                this.formData.interior.papelInteriorId == opcion.extra_data["sk-id"]) {
                item.setSelected(true);
            }
            this.divPapelInterior.append(item.render());
        }

        const gramajes = data.opciones_gramaje_interior;
        this.#addGramajesInterior(gramajes);

        const dataInterior = this.#getInteriorData();
        this.#updateInteriorData(dataInterior);
        this.#cacheFormData();

        Summary.updateTipoImpresion();
        Summary.updatePapelInterior();
        Summary.updateGramajeInterior();
    }

    #addGramajesInterior(gramajes) {

        for (let i = 0; i < gramajes.length; i++) {
            const gramaje = gramajes[i];
            this.#addGramaje(this.divGramajeInterior, 'gramaje-interior', gramaje, 'gramaje-interior');

            // Seleccionar el gramaje por defecto
            if (this.formData.interior.gramajeInterior === '' && i === 0) {
                $(`#gramaje-interior-${gramaje}`).prop('checked', true);
            } else if (this.formData.interior.gramajeInterior == gramaje) {
                $(`#gramaje-interior-${gramaje}`).prop('checked', true);
            }
        }
        if (this.divGramajeInterior.find('input[type="radio"]:checked').length === 0) {
            // If not, select the first one by default
            this.divGramajeInterior.find('input[type="radio"]').first().prop('checked', true);
        }
    }

    #getInteriorData() {

        const tipoImpresion = $('#div-opciones-color .image-container.selected').attr('id') || 'negro';
        const papelInteriorId = $('#div-papel-interior .image-container.selected').data('sk-id') || 3;
        const gramajeInterior = $('input[name="gramaje-interior"]:checked').data('gramaje') || 90;
        return {
            tipoImpresion: tipoImpresion,
            papelInteriorId: papelInteriorId,
            gramajeInterior: gramajeInterior
        };
    }

    #updateInteriorData(data) {

        this.formData.interior.tipoImpresion = data.tipoImpresion;
        this.formData.interior.papelInteriorId = data.papelInteriorId;
        this.formData.interior.gramajeInterior = data.gramajeInterior;
    }


    /******************************
     * END INTERIOR
     ******************************/


    /******************************
     * CUBIERTA
     ******************************/
    #initCubierta() {

        this.btn_plantilla_cubierta.on('click', () => {
            Swal.fire({
                position: 'top-end',
                icon: 'info',
                title: window.languageBundle.get('presupuesto.plantilla-cubierta'),
                html: `
            <div class="text-center p-4">
                <img src="/assets/images/imprimelibros/presupuestador/plantilla-cubierta.png" class="img-fluid" alt="" />
            </div>
            <div class="acitivity-timeline p-4">
                ${window.languageBundle.get('presupuesto.plantilla-cubierta-text')}
            </div>
        `,
                confirmButtonClass: 'btn btn-primary w-xs mt-2',
                showConfirmButton: false,
                showCloseButton: true
            });
        });

        this.btn_impresion_cubierta_help.on('click', () => {
            Swal.fire({
                position: 'top-end',
                icon: 'info',
                title: window.languageBundle.get('presupuesto.impresion-cubierta'),
                html: window.languageBundle.get('presupuesto.impresion-cubierta-help'),
                confirmButtonClass: 'btn btn-primary w-xs mt-2',
                showConfirmButton: false,
                showCloseButton: true
            });
        });

        $(document).on('click', '.tapa-cubierta', (e) => {

            $('.tapa-dura-options').eq(0).removeClass('animate-fadeInUpBounce');
            $('.tapa-blanda-options').eq(0).removeClass('animate-fadeInUpBounce');

            if (e.currentTarget.id === 'tapaBlanda') {
                $('.tapa-blanda-options').eq(0).addClass('animate-fadeInUpBounce');
                $('.tapa-dura-options').addClass('d-none');
                $('.tapa-blanda-options').removeClass('d-none');
            }
            else {
                $('.tapa-dura-options').eq(0).addClass('animate-fadeInUpBounce');
                $('.tapa-blanda-options').addClass('d-none');
                $('.tapa-dura-options').removeClass('d-none');
            }

            this.#getPapelesCubierta(e.currentTarget.id);
            Summary.updateTapaCubierta();
        });

        $(document).on('click', '.solapas-cubierta', (e) => {

            if (e.currentTarget.id === 'sin-solapas') {
                this.divSolapasCubierta.addClass('d-none');
            }
            else {
                this.divSolapasCubierta.removeClass('d-none');
            }

            const dataToStore = this.#getCubiertaData();
            this.#updateCubiertaData(dataToStore);
            this.#cacheFormData();

            Summary.updateTapaCubierta();
        });

        $(document).on('click', '.papel-cubierta', (e) => {

            const data = this.#getPresupuestoData();

            this.divGramajeCubierta.removeClass('animate-fadeInUpBounce');
            this.divGramajeCubierta.empty();

            $.ajax({
                url: '/presupuesto/public/get-gramaje-cubierta',
                type: 'POST',
                data: data,
            }).done((data) => {

                const gramajes = data.opciones_gramaje_cubierta;
                this.#addGramajesCubierta(gramajes);
                this.divGramajeCubierta.addClass('animate-fadeInUpBounce');

                const dataCubierta = this.#getCubiertaData();
                this.#updateCubiertaData(dataCubierta);
                this.#cacheFormData();

                Summary.updatePapelCubierta();
                Summary.updateGramajeCubierta();

            }).fail((xhr, status, error) => {
                console.error("Error al obtener los gramajes de interior: ", xhr.responseText);
            });
        });

        $(document).on('click', '.gramaje-cubierta', (e) => {

            const inputId = $(e.currentTarget).attr('for');
            const gramaje = parseInt($('#' + inputId).data('gramaje'));
            this.formData.cubierta.gramajeCubierta = gramaje;
            this.#cacheFormData();
            Summary.updateGramajeCubierta();
        });

        $(document).on('change', '.datos-cubierta', (e) => {

            const dataToStore = this.#getCubiertaData();
            this.#updateCubiertaData(dataToStore);
            this.#cacheFormData();
        });

        $(document).on('change', '.acabado-cubierta-check', (e) => {

            this.formData.cubierta.acabado = parseInt($(e.currentTarget).attr('sk-id')) || 1;
            this.#cacheFormData();
            Summary.updateAcabadoCubierta();
        });

        $(document).on('click', '.custom-toggle', (e) => {

            const $target = $(e.currentTarget);
            if ($target.hasClass('active')) {
                if ($target.attr('id') === 'sobrecubierta') {
                    this.divSobrecubierta.removeClass('d-none');
                    this.summaryTableSobrecubierta.removeClass('d-none');
                    Summary.updateSobreCubierta();
                }
                else if ($target.attr('id') === 'faja') {
                    this.divFaja.removeClass('d-none');
                    this.summaryTableFaja.removeClass('d-none');
                    Summary.updateFaja();
                }
            } else {
                if ($target.attr('id') === 'sobrecubierta') {
                    this.divSobrecubierta.addClass('d-none');
                    this.summaryTableSobrecubierta.addClass('d-none');
                    Summary.updateSobreCubierta();
                }
                else if ($target.attr('id') === 'faja') {
                    this.divFaja.addClass('d-none');
                    this.summaryTableFaja.addClass('d-none');
                    Summary.updateFaja();
                }
            }
            const dataToStore = this.#getCubiertaData();
            this.#updateCubiertaData(dataToStore);
            this.#cacheFormData();
        });

        $(document).on('change', '.sobrecubierta-item', () => {
            const dataToStore = this.#getCubiertaData();
            this.#updateCubiertaData(dataToStore);
            this.#cacheFormData();
            Summary.updateSobreCubierta();
        });

        $(document).on('change', '.faja-item', () => {
            const dataToStore = this.#getCubiertaData();
            this.#updateCubiertaData(dataToStore);
            this.#cacheFormData();
            Summary.updateFaja();
        });

        $('.btn-change-tab-cubierta').on('click', (e) => {

            const data = this.#getPresupuestoData();
            const id = e.currentTarget.id;

            if (id === 'btn-prev-cubierta') {
                data.calcular = false;
            }
            else {
                data.calcular = true;
            }

            $.ajax({
                url: '/presupuesto/public/validar/cubierta',
                type: 'POST',
                data: data,
                success: (data) => {
                    if (id === 'btn-prev-cubierta') {
                        this.summaryTableCubierta.addClass('d-none');
                        this.#changeTab('pills-inside');
                    }
                    else {
                        $('#btn-next-seleccion-tirada').removeClass('d-none');
                        this.#loadSeleccionTiradaData(data);
                        this.#changeTab('pills-seleccion-tirada');
                    }
                },
                error: (xhr, status, error) => {
                    if (id === 'btn-prev-cubierta') {
                        this.#changeTab('pills-inside');
                        return;
                    }
                    this.divTiradas.empty();
                    this.divTiradasError.empty();
                    this.divTiradas.addClass('d-none');
                    this.divTiradasError.removeClass('d-none');
                    $('#btn-next-seleccion-tirada').addClass('d-none');
                    this.divTiradasError.append('<div class="alert alert-danger" role="alert">' +
                        '<h4>' + xhr.responseText + '</h4></div>');
                    this.#changeTab('pills-seleccion-tirada');
                }
            });
        });

        // Eventos para el resumen
        $(document).on('change', '.tapa-cubierta-summary', () => {
            Summary.updateTapaCubierta();
        });

    }

    #getPapelesCubierta(tapa_id) {

        new Promise((resolve) => {
            this.divPapelCubierta.empty();
            this.divGramajeCubierta.empty();
            setTimeout(resolve, 250);
        }).then(() => {

            this.divPapelCubierta.removeClass('animate-fadeInUpBounce');
            this.divGramajeCubierta.removeClass('animate-fadeInUpBounce');

            $.ajax({
                url: '/presupuesto/public/get-papel-cubierta',
                type: 'POST',
                data: {
                    tipoCubierta: tapa_id,
                    papelCubiertaId: this.formData.cubierta.papelCubiertaId,
                    gramajeCubierta: this.formData.cubierta.gramajeCubierta,
                },
                success: (data) => {
                    this.divPapelCubierta.addClass('animate-fadeInUpBounce');
                    this.divGramajeCubierta.addClass('animate-fadeInUpBounce');

                    const papelesCubierta = data.opciones_papel_cubierta;
                    for (let i = 0; i < papelesCubierta.length; i++) {
                        const papel = papelesCubierta[i];
                        const item = new imagen_presupuesto(papel);
                        item.extraClass = 'cubierta-data papel-cubierta';
                        if (item.extraData["sk-id"] == this.formData.cubierta.papelCubiertaId) {
                            item.setSelected(true);
                        }
                        this.divPapelCubierta.append(item.render());
                    }

                    if (this.divPapelCubierta.find('.image-container.selected').length === 0) {
                        this.divPapelCubierta.find('.image-container').first().addClass('selected');
                        this.formData.cubierta.papelCubiertaId =
                            this.divPapelCubierta.find('.image-container').first().data('sk-id') || 3;
                    }

                    this.#addGramajesCubierta(data.opciones_gramaje_cubierta);

                    const dataToStore = this.#getCubiertaData();
                    this.#updateCubiertaData(dataToStore);
                    this.#cacheFormData();

                    Summary.updatePapelCubierta();
                },
                error: (xhr, status, error) => {
                    console.error("Error al obtener los papeles de cubierta: ", xhr.responseText);
                    $(window).scrollTop(0);
                }
            });
        });
    }

    #getCubiertaData() {

        const tipoCubierta = $('.tapa-cubierta.selected').attr('id') || 'tapaBlanda';
        const solapas = $('.solapas-cubierta.selected').id == 'sin-solapas' ? 0 : 1 || 0;
        const tamanioSolapasCubierta = $('#tamanio-solapas-cubierta').val() || '80';
        const cubiertaCaras = parseInt(this.carasImpresionCubierta.val()) || 2;
        const papelGuardasId = parseInt($('#papel-guardas option:selected').data('papel-id')) || 3;
        const gramajeGuardas = parseInt($('#papel-guardas option:selected').data('gramaje')) || 170;
        const guardasImpresas = parseInt(this.guardasImpresas) || 0;
        const cabezada = this.cabezada.val() || 'WHI';
        const papelCubiertaId = $('#div-papel-cubierta .image-container.selected').data('sk-id') || this.formData.cubierta.papelCubiertaId || 3;
        const gramajeCubierta = $('input[name="gramaje-cubierta"]:checked').data('gramaje') || this.formData.cubierta.gramajeCubierta || 170;
        const acabado = parseInt($(`input[name="acabado-cubierta"]:checked`).attr('sk-id')) || 1;
        const sobrecubierta = this.sobrecubierta.hasClass('active');
        const papelSobrecubiertaId = $('#papel-sobrecubierta option:selected').data('papel-id') || 2;
        const gramajeSobrecubierta = parseInt($('#papel-sobrecubierta option:selected').data('gramaje')) || 170;
        const solapasSobrecubierta = parseInt(this.solapasSobrecubierta.val()) || 0;
        const acabadoSobrecubierta = $('#sobrecubierta-acabado option:selected').val() || 0;
        const faja = this.faja.hasClass('active');
        const papelFajaId = $('#papel-faja option:selected').data('papel-id') || 2;
        const gramajeFaja = parseInt($('#papel-faja option:selected').data('gramaje')) || 170;
        const fajaAlto = parseInt(this.altoFaja.val()) || 50;
        const solapasFaja = parseInt(this.solapasFaja.val()) || 0;
        const acabadoFaja = $('#faja-acabado option:selected').val() || 0;

        return {
            tipoCubierta: tipoCubierta,
            solapasCubierta: solapas,
            tamanioSolapasCubierta: tamanioSolapasCubierta,
            cubiertaCaras: cubiertaCaras,
            papelGuardasId: papelGuardasId,
            gramajeGuardas: gramajeGuardas,
            guardasImpresas: guardasImpresas,
            cabezada: cabezada,
            papelCubiertaId: papelCubiertaId,
            gramajeCubierta: gramajeCubierta,
            acabado: acabado,
            sobrecubierta: {
                activo: sobrecubierta,
                papelSobrecubiertaId: papelSobrecubiertaId,
                gramajeSobrecubierta: gramajeSobrecubierta,
                acabado: acabadoSobrecubierta,
                tamanioSolapasSobrecubierta: solapasSobrecubierta
            },
            faja: {
                activo: faja,
                papelFajaId: papelFajaId,
                gramajeFaja: gramajeFaja,
                alto: fajaAlto,
                acabado: acabadoFaja,
                tamanioSolapasFaja: solapasFaja
            }
        };
    }

    #updateCubiertaData(data) {

        this.formData.cubierta.tipoCubierta = data.tipoCubierta;
        this.formData.cubierta.solapasCubierta = data.solapasCubierta;
        this.formData.cubierta.tamanioSolapasCubierta = data.tamanioSolapasCubierta;
        this.formData.cubierta.cubiertaCaras = data.cubiertaCaras;
        this.formData.cubierta.papelGuardasId = data.papelGuardasId;
        this.formData.cubierta.gramajeGuardas = data.gramajeGuardas;
        this.formData.cubierta.guardasImpresas = data.guardasImpresas;
        this.formData.cubierta.cabezada = data.cabezada;
        this.formData.cubierta.papelCubiertaId = data.papelCubiertaId;
        this.formData.cubierta.gramajeCubierta = data.gramajeCubierta;
        this.formData.cubierta.acabado = data.acabado;
        this.formData.cubierta.sobrecubierta = {
            activo: data.sobrecubierta.activo,
            papelSobrecubiertaId: data.sobrecubierta.papelSobrecubiertaId,
            gramajeSobrecubierta: data.sobrecubierta.gramajeSobrecubierta,
            tamanioSolapasSobrecubierta: data.sobrecubierta.tamanioSolapasSobrecubierta,
            acabado: data.sobrecubierta.acabado
        };
        this.formData.cubierta.faja = {
            activo: data.faja.activo,
            papelFajaId: data.faja.papelFajaId,
            gramajeFaja: data.faja.gramajeFaja,
            tamanioSolapasFaja: data.faja.tamanioSolapasFaja,
            acabado: data.faja.acabado,
            alto: data.faja.alto
        };
    }

    #addGramajesCubierta(gramajes) {

        for (let i = 0; i < gramajes.length; i++) {
            const gramaje = gramajes[i];
            this.#addGramaje(this.divGramajeCubierta, 'gramaje-cubierta datos-cubierta', gramaje, 'gramaje-cubierta');

            // Seleccionar el gramaje por defecto
            if (this.formData.cubierta.gramajeCubierta === '' && i === 0) {
                $(`#gramaje-cubierta-${gramaje}`).prop('checked', true);
            } else if (this.formData.cubierta.gramajeCubierta == gramaje) {
                $(`#gramaje-cubierta-${gramaje}`).prop('checked', true);
            }
        }
        if (this.divGramajeCubierta.find('input[type="radio"]:checked').length === 0) {
            // If not, select the first one by default
            this.divGramajeCubierta.find('input[type="radio"]').first().prop('checked', true);
        }

        Summary.updateGramajeCubierta();
    }

    #loadCubiertaData() {

        $('.tapa-cubierta').removeClass('selected');
        $(`#${this.formData.cubierta.tipoCubierta}`).addClass('selected');

        if (this.formData.cubierta.tipoCubierta === 'tapaBlanda') {
            $('.tapa-blanda-options').removeClass('d-none');
            $('.tapa-dura-options').addClass('d-none');
        }
        else {
            $('.tapa-dura-options').removeClass('d-none');
            $('.tapa-blanda-options').addClass('d-none');
            $('#papel-guardas option[data-papel-id="' +
                this.formData.cubierta.papelGuardasId + '"][data-gramaje="' +
                this.formData.cubierta.gramajeGuardas + '"]').prop('selected', true).trigger('change');
            this.guardasImpresas.val(this.formData.cubierta.guardasImpresas);
            this.cabezada.val(this.formData.cubierta.cabezada);
        }

        $(`#${this.formData.cubierta.tipoCubierta}`).trigger('click');

        if (this.formData.cubierta.solapasCubierta === 0) {
            $('.solapas-cubierta#sin-solapas').addClass('selected');
            this.divSolapasCubierta.addClass('d-none');
        }
        else {
            $('.solapas-cubierta').removeClass('selected');
            $(`.solapas-cubierta#con-solapas`).addClass('selected');
            this.divSolapasCubierta.removeClass('d-none');
            this.carasImpresionCubierta.val(this.formData.cubierta.cubiertaCaras);
            this.tamanioSolapasCubierta.val(this.formData.cubierta.tamanioSolapasCubierta);
        }

        this.carasImpresionCubierta.val(this.formData.cubierta.cubiertaCaras);
        $(`input[type="radio"][name="acabado-cubierta"][sk-id="${this.formData.cubierta.acabado}"]`).prop('checked', true);

        if (this.formData.cubierta.sobrecubierta.activo) {
            this.sobrecubierta.addClass('active');
            this.divSobrecubierta.removeClass('d-none');
        }
        else {
            this.sobrecubierta.removeClass('active');
            this.divSobrecubierta.addClass('d-none');
        }
        $('#papel-sobrecubierta option[data-papel-id="' +
            this.formData.cubierta.sobrecubierta.papelSobrecubiertaId + '"][data-gramaje="' +
            this.formData.cubierta.sobrecubierta.gramajeSobrecubierta + '"]').prop('selected', true);
        this.solapasSobrecubierta.val(this.formData.cubierta.sobrecubierta.tamanioSolapasSobrecubierta);
        this.acabadoSobrecubierta.val(this.formData.cubierta.sobrecubierta.acabado);

        if (this.formData.cubierta.faja.activo) {
            this.faja.addClass('active');
            this.divFaja.removeClass('d-none');
        }
        else {
            this.faja.removeClass('active');
            this.divFaja.addClass('d-none');
        }
        $('#papel-faja option[data-papel-id="' +
            this.formData.cubierta.faja.papelFajaId + '"][data-gramaje="' +
            this.formData.cubierta.faja.gramajeFaja + '"]').prop('selected', true);
        this.solapasFaja.val(this.formData.cubierta.faja.tamanioSolapasFaja);
        this.altoFaja.val(this.formData.cubierta.faja.alto);
        this.acabadoFaja.val(this.formData.cubierta.faja.acabado);

        Summary.updateTapaCubierta();
        Summary.updateAcabadoCubierta();
    }
    /******************************
     * END CUBIERTA
     ******************************/


    /******************************
     * SELECCION TIRADA
     ******************************/
    #initSeleccionTirada() {

        $(document).on('click', '.btn-change-tab-seleccion-tirada', (e) => {

            const id = e.currentTarget.id;

            if (id === 'btn-prev-seleccion-tirada') {
                this.#changeTab('pills-cover');
            } else {
                const data = this.#getPresupuestoData();
                const id = e.currentTarget.id;
                $.ajax({
                    url: '/presupuesto/public/validar/seleccion-tirada',
                    type: 'POST',
                    data: data,
                    success: (data) => {
                        this.divExtras.data('language-calcular', data.language.calcular);
                        this.#loadExtrasData(data.servicios_extra);
                        this.#changeTab('pills-extras');
                    },
                    error: (xhr, status, error) => {
                        console.error("Error al validar los datos de selección de tirada: ", xhr.responseText);
                    }
                });

            }
        });

        this.divTiradas.off('tirada:changed.cache') // por si re-bindeas
            .on('tirada:changed.cache', (e, detail) => {
                // detail = { id, name, unidades, precioUnidad, precioTotal }
                this.formData.selectedTirada = detail.unidades;
                this.#cacheFormData();
            });
    }

    #loadSeleccionTiradaData(data) {

        this.divTiradasError.addClass('d-none');
        this.divTiradas.empty();
        this.divTiradas.removeClass('d-none');
        this.divTiradas.removeClass('animate-fadeInUpBounce');

        const labels = {
            perUnit: this.divTiradas.data('perUnit'),
            total: this.divTiradas.data('total'),
            select: this.divTiradas.data('select'),
            selected: this.divTiradas.data('selected'),
            units: this.divTiradas.data('units')
        };

        this.divTiradas.addClass('animate-fadeInUpBounce');
        for (let i = 0; i < data.tiradas.length; i++) {
            const item = new TiradaCard({
                id: "tirada-" + data.tiradas[i],
                unidades: data.tiradas[i],
                precioUnidad: data.precios[i],
                precioTotal: data.precios[i] * data.tiradas[i],
                moneda: "€",
                labels: labels,
                selected: this.formData.selectedTirada == data.tiradas[i]
            });
            this.divTiradas.append(item.renderCol(this.divTiradas));
        }

        if (this.divTiradas.find('.tirada-card input[type="radio"]:checked').length === 0) {
            this.divTiradas.find('.tirada-card input[type="radio"]').first().prop('checked', true).trigger('change');
            this.formData.selectedTirada = this.divTiradas.find('.tirada-card input[type="radio"]').first().data('unidades') || data.tiradas[0];
        }
    }
    /******************************
     * END SELECCION TIRADA
     ******************************/



    /******************************
     * EXTRAS
     ******************************/
    #initExtras() {

        const self = this;

        $(document).on('click', '.btn-change-tab-extras', (e) => {

            const id = e.currentTarget.id;

            if (id === 'btn-prev-extras') {
                this.#changeTab('pills-seleccion-tirada');
                this.summaryTableExtras.addClass('d-none');
            } else {

                const servicios = [];
                $('.service-checkbox:checked').each(function () {
                    const $servicio = $(this);
                    servicios.push({
                        id: $servicio.attr('id') ?? $(`label[for="${$servicio.attr('id')}"] .service-title`).text().trim(),
                        label: $(`label[for="${$servicio.attr('id')}"] .service-title`).text().trim(),
                        units: $servicio.attr('id') === 'marcapaginas' ? self.formData.servicios.datosMarcapaginas.marcapaginas_tirada : 1,
                        price: $servicio.data('price') ?? $(`label[for="${$servicio.attr('id')}"] .service-price`).text().trim().replace(" " + self.divExtras.data('currency'), ''),
                    });
                });

                const body = {
                    presupuesto: this.#getPresupuestoData(),
                    servicios: servicios
                };

                $.ajax({
                    url: '/presupuesto/public/resumen',
                    type: 'POST',
                    contentType: 'application/json',
                    data: JSON.stringify(body)
                }).then((data) => {
                    $('#resumen-titulo').text(data.titulo);
                    this.#updateResumenTable(data);
                }).catch((error) => {
                    console.error("Error obtener resumen: ", error);
                });

                this.#changeTab('pills-resumen');
            }
        });

        // Eventos para el resumen
        $(document).on('change', '.service-checkbox', (e) => {

            const $target = $(e.currentTarget);

            if ($target.prop('checked')) {
                this.formData.servicios.servicios.push($target.val());
            } else {
                const index = this.formData.servicios.servicios.indexOf($target.val());
                if (index > -1) {
                    this.formData.servicios.servicios.splice(index, 1);
                }
            }
            Summary.updateExtras();
            this.#cacheFormData();
        });

        this.#bindMaquetacionEvents();
        this.#bindMarcapaginasEvents();
    }

    #loadExtrasData(servicios) {

        this.divExtras.empty();
        this.summaryTableExtras.removeClass('d-none');
        this.divExtras.removeClass('animate-fadeInUpBounce');

        this.divExtras.addClass('animate-fadeInUpBounce');
        for (const extra of servicios) {
            if (this.formData.servicios.servicios.includes(extra.id) && !extra.checked) {
                extra.checked = true;
                if (extra.id === "marcapaginas" || extra.id === "maquetacion") {
                    extra.price = extra.id === "marcapaginas" ?
                        this.formData.servicios.datosMarcapaginas.resultado.precio :
                        this.formData.servicios.datosMaquetacion.resultado.precio;
                    extra.priceUnit = this.divExtras.data('currency');
                }
            }
            const item = new ServiceOptionCard(extra);
            this.divExtras.append(item.render());
            if (item.checked) {
                if (!this.formData.servicios.servicios.includes(extra.id)) {
                    this.formData.servicios.servicios.push(extra.id);
                }
            }
        }

        this.#cacheFormData();
        Summary.updateExtras();
    }

    #bindMaquetacionEvents() {

        $(document).on('maquetacion:request', (e) => {
            const data = this.formData.servicios.datosMaquetacion;
            $(document).trigger('maquetacion:response', [data]);
        });

        $(document).on('maquetacion:update', (e, payload) => {
            // payload: campos planos (num_caracteres, formato_maquetacion, ...)
            this.formData.servicios.datosMaquetacion = {
                ...this.formData.servicios.datosMaquetacion,
                ...payload,
            };
            this.#cacheFormData();
        });

        $(document).on('maquetacion:result', (e, result) => {
            this.formData.servicios.datosMaquetacion.resultado = {
                ...this.formData.servicios.datosMaquetacion.resultado,
                ...result,
            };

            const list = this.formData.servicios.servicios;
            if (!list.includes('maquetacion')) list.push('maquetacion');

            this.#cacheFormData();
        });
    }

    #bindMarcapaginasEvents() {

        $(document).on('marcapaginas:request', (e) => {
            const data = this.formData.servicios.datosMarcapaginas;
            $(document).trigger('marcapaginas:response', [data]);
        });

        $(document).on('marcapaginas:update', (e, payload) => {
            // payload: { marcapaginas_tirada, tamanio_marcapaginas, ... }
            this.formData.servicios.datosMarcapaginas = {
                ...this.formData.servicios.datosMarcapaginas,
                ...payload,
            };
            this.#cacheFormData();
        });

        $(document).on('marcapaginas:result', (e, result) => {
            // result: { precio_unitario, precio }
            this.formData.servicios.datosMarcapaginas.resultado = {
                ...this.formData.servicios.datosMarcapaginas.resultado,
                ...result,
            };

            // asegúrate de añadir el servicio seleccionado
            const list = this.formData.servicios.servicios;
            if (!list.includes('marcapaginas')) list.push('marcapaginas');

            this.#cacheFormData();
        });

    }
    /******************************
     * END EXTRAS
     ******************************/


    /******************************
     * RESUMEN
     ******************************/
    #initResumen() {
        const $row = $('#presupuesto-row');

        // 1) Transición al cambiar de pestaña (click o programático)
        $(document).on('shown.bs.tab', '.custom-nav .nav-link', (e) => {
            const targetSelector = $(e.target).data('bs-target'); // ej: "#pills-resumen"
            if (targetSelector === '#pills-resumen') {
                $row.addClass('expanded');
                window.scrollTo({ top: 0, behavior: 'smooth' });
            } else {
                $row.removeClass('expanded');
            }
        });

        // 2) Botón "atrás" en Resumen
        $(document).on('click', '.btn-change-tab-resumen', (e) => {
            if (e.currentTarget.id === 'btn-prev-resumen') {
                this.#changeTab('pills-extras');
            }
        });

        // 3) Estado inicial si ya cargas en Resumen
        $(function () {
            const activeTarget = $('.custom-nav .nav-link.active').data('bs-target');
            $('#presupuesto-row').toggleClass('expanded', activeTarget === '#pills-resumen');
        });
    }

    #updateResumenTable(data) {
        this.tablaResumen.find('tbody').empty();

        const lineas = Object.keys(data).filter(k => k.startsWith("linea")).sort((a, b) => {
            const numA = parseInt(a.replace("linea", ""), 10);
            const numB = parseInt(b.replace("linea", ""), 10);
            return numA - numB;
        });
        const servicios = data.servicios || [];

        let total = 0;

        const locale = document.documentElement.lang || 'es-ES';

        for (const l of lineas) {
            const row = `
                <tr>
                    <td>${l == "linea0" ? `<img style="max-width: 60px; height: auto;" src="${data.imagen}" alt="${data.imagen_alt}" class="img-fluid" />` : ''}</td>
                    <td>${data[l].descripcion}</td>
                    <td class="text-center">${data[l].cantidad}</td>
                    <td class="text-center">${formateaMoneda(data[l].precio_unitario, 4, locale)}</td>
                    <td class="text-end">${formateaMoneda(data[l].precio_total, 2, locale)}</td>
                </tr>
            `;
            total += data[l].precio_total;
            this.tablaResumen.find('tbody').append(row);
        }
        for (const s of servicios) {
            const row = `
                <tr>
                    <td></td>
                    <td>${s.descripcion}</td>
                    <td class="text-center">${s.unidades}</td>
                    <td class="text-center">${s.id === "marcapaginas" ? formateaMoneda(s.precio, 4, locale) : formateaMoneda(s.precio, 2, locale)}</td>
                    <td class="text-end">${s.id === "marcapaginas" ? formateaMoneda(s.precio * s.unidades, 2, locale) : formateaMoneda(s.precio, 2, locale)}</td>
                </tr>
            `;
            total += s.precio;
            this.tablaResumen.find('tbody').append(row);
        }

        $('#resumen-base').text(formateaMoneda(total, 2, locale));
        $('#resumen-iva').text(formateaMoneda(total * 0.04, 2, locale));
        $('#resumen-total').text(formateaMoneda(total * 1.04, 2, locale));
    }

    /******************************
     * END RESUMEN
     ******************************/
}


document.addEventListener('DOMContentLoaded', function () {
    const presupuestoCliente = new PresupuestoCliente();
    presupuestoCliente.init();
});