/**
 * Checkout público (Vue 3 CDN): lista de tickets + modal de asistentes + POST JSON.
 * Sustituye la versión Alpine para mejor compatibilidad entre navegadores.
 */
(function () {
    'use strict';

    function getCsrfToken() {
        const meta = document.querySelector('meta[name="csrf-token"]');
        return meta ? meta.getAttribute('content') : '';
    }

    function formatMoney(value) {
        const n = Number.isFinite(value) ? value : 0;
        return '$' + n.toFixed(2);
    }

    function generateKey() {
        if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
            return crypto.randomUUID();
        }
        return Date.now().toString(36) + Math.random().toString(36).slice(2);
    }

    function emptyMetaForFields(fields) {
        const meta = {};
        (fields || []).forEach((cf) => {
            meta[cf.slug] = cf.type === 'checkbox' ? false : '';
        });
        return meta;
    }

    function buildAttendeeRecord(ticket, customFields, prefill) {
        return {
            holder_name: prefill && prefill.holder_name ? prefill.holder_name : '',
            holder_email: prefill && prefill.holder_email ? prefill.holder_email : '',
            meta: emptyMetaForFields(customFields),
        };
    }

    function mountCheckout() {
        const mount = document.getElementById('rt-checkout-mount');
        if (!mount || typeof Vue === 'undefined' || !Vue.createApp) {
            return;
        }

        const configEl = document.getElementById('rt-checkout-config');
        let config = {};
        try {
            config = configEl ? JSON.parse(configEl.textContent) : {};
        } catch (e) {
            config = {};
        }

        const isGuest = mount.getAttribute('data-is-guest') === '1';
        const buyerPrefill = {
            holder_name: mount.getAttribute('data-buyer-name') || '',
            holder_email: mount.getAttribute('data-buyer-email') || '',
        };
        const maxDate = mount.getAttribute('data-max-date') || '';

        const { createApp } = Vue;

        createApp({
            template: '#rt-checkout-template',

            data() {
                const tickets = Array.isArray(config.tickets) ? config.tickets : [];
                const quantities = {};
                const attendees = {};
                tickets.forEach((t) => {
                    quantities[t.id] = 0;
                    attendees[t.id] = [];
                });
                return {
                    storeUrl: config.storeUrl || '',
                    fixedFee: Number(config.fixedFee) || 2.99,
                    percentageFee: Number(config.percentageFee) || 0.05,
                    tickets,
                    customFieldsByTicket: config.customFieldsByTicket || {},
                    quantities,
                    attendees,
                    modalOpen: false,
                    submitting: false,
                    errorMessage: '',
                    _idempotencyKey: generateKey(),
                    _buyerPrefill: buyerPrefill,
                    guestEmail: buyerPrefill.holder_email || '',
                    isGuest,
                    maxDate,
                };
            },

            computed: {
                totalQty() {
                    return Object.values(this.quantities).reduce((acc, v) => acc + (Number(v) || 0), 0);
                },
                totalPrice() {
                    return this.tickets.reduce(
                        (acc, t) => acc + (Number(t.price) || 0) * (this.quantities[t.id] || 0),
                        0
                    );
                },
                platformFee() {
                    if (this.totalPrice <= 0) {
                        return 0;
                    }
                    return Math.round((this.fixedFee + this.totalPrice * this.percentageFee) * 100) / 100;
                },
                grandTotal() {
                    return Math.round((this.totalPrice + this.platformFee) * 100) / 100;
                },
                selectedTickets() {
                    return this.tickets.filter((t) => (this.quantities[t.id] || 0) > 0);
                },
            },

            methods: {
                formatMoney,

                ticketById(id) {
                    return this.tickets.find((t) => t.id === id);
                },

                customFieldsFor(ticketId) {
                    return this.customFieldsByTicket[ticketId] || [];
                },

                customFieldColClass(cf) {
                    const fullWidth =
                        cf.type === 'textarea' || cf.type === 'radio' || cf.type === 'checkbox';
                    return fullWidth ? 'col-12' : 'col-12 col-md-6';
                },

                isSoldOut(ticketId) {
                    const t = this.ticketById(ticketId);
                    if (!t) {
                        return true;
                    }
                    if (t.unlimited) {
                        return false;
                    }
                    return t.available <= 0;
                },

                remaining(ticketId) {
                    const t = this.ticketById(ticketId);
                    if (!t) {
                        return 0;
                    }
                    if (t.unlimited) {
                        return '∞';
                    }
                    return Math.max(0, t.available - (this.quantities[ticketId] || 0));
                },

                maxFor(ticketId) {
                    const t = this.ticketById(ticketId);
                    if (!t) {
                        return 0;
                    }
                    if (t.unlimited) {
                        return 100;
                    }
                    return Math.max(0, t.available);
                },

                increment(ticketId) {
                    const max = this.maxFor(ticketId);
                    if ((this.quantities[ticketId] || 0) < max) {
                        this.quantities[ticketId] = (this.quantities[ticketId] || 0) + 1;
                        this._syncAttendeeArray(ticketId);
                    }
                },

                decrement(ticketId) {
                    if ((this.quantities[ticketId] || 0) > 0) {
                        this.quantities[ticketId] -= 1;
                        this._syncAttendeeArray(ticketId);
                    }
                },

                clampQuantity(ticketId) {
                    let v = parseInt(this.quantities[ticketId] || 0, 10);
                    if (Number.isNaN(v) || v < 0) {
                        v = 0;
                    }
                    const max = this.maxFor(ticketId);
                    if (v > max) {
                        v = max;
                    }
                    this.quantities[ticketId] = v;
                    this._syncAttendeeArray(ticketId);
                },

                _syncAttendeeArray(ticketId) {
                    const qty = this.quantities[ticketId] || 0;
                    const ticket = this.ticketById(ticketId);
                    if (!ticket) {
                        return;
                    }
                    const list = this.attendees[ticketId] || [];
                    const fields = this.customFieldsFor(ticketId);

                    if (qty > list.length) {
                        for (let i = list.length; i < qty; i += 1) {
                            const prefill =
                                i === 0 && this._isFirstAttendeeOverall(ticketId) ? this._buyerPrefill : null;
                            list.push(buildAttendeeRecord(ticket, fields, prefill));
                        }
                    } else if (qty < list.length) {
                        list.length = qty;
                    }
                    this.attendees[ticketId] = list;
                },

                _isFirstAttendeeOverall(ticketId) {
                    for (const t of this.tickets) {
                        if (t.id === ticketId) {
                            return true;
                        }
                        if ((this.quantities[t.id] || 0) > 0) {
                            return false;
                        }
                    }
                    return false;
                },

                attendeeRange(ticketId) {
                    const qty = this.quantities[ticketId] || 0;
                    return Array.from({ length: qty }, (_, i) => i);
                },

                openModal() {
                    if (this.totalQty === 0) {
                        return;
                    }
                    this.selectedTickets.forEach((t) => this._syncAttendeeArray(t.id));
                    this.modalOpen = true;
                    this.errorMessage = '';
                    document.body.classList.add('rt-modal-open');
                },

                closeModal() {
                    this.modalOpen = false;
                    document.body.classList.remove('rt-modal-open');
                },

                onEscapeKey(e) {
                    if (e.key === 'Escape' && this.modalOpen) {
                        this.closeModal();
                    }
                },

                _validateAttendees() {
                    for (const ticket of this.selectedTickets) {
                        const rows = this.attendees[ticket.id] || [];
                        if (rows.length === 0) {
                            return false;
                        }
                        if (ticket.iac === 'none') {
                            continue;
                        }
                        for (const row of rows) {
                            if (!row.holder_name || !String(row.holder_name).trim()) {
                                return false;
                            }
                            if (!row.holder_email || !String(row.holder_email).trim()) {
                                return false;
                            }
                        }
                    }
                    return true;
                },

                _validateGuestCheckoutEmail() {
                    if (!this.isGuest) {
                        return true;
                    }
                    return String(this.guestEmail || '').trim().length > 0;
                },

                async submitOrder() {
                    if (this.submitting) {
                        return;
                    }

                    if (!this._validateAttendees()) {
                        this.errorMessage =
                            window.rtCheckoutStrings?.attendeesRequired ||
                            'Completa el nombre y correo de todos los asistentes.';
                        return;
                    }

                    if (!this._validateGuestCheckoutEmail()) {
                        this.errorMessage =
                            window.rtCheckoutStrings?.guestEmailRequired ||
                            'Indica el correo con el que quieres acceder a tus entradas.';
                        return;
                    }

                    this.submitting = true;
                    this.errorMessage = '';

                    const sanitizeMeta = (meta) => {
                        const result = {};
                        for (const [k, v] of Object.entries(meta || {})) {
                            result[k] = typeof v === 'boolean' ? (v ? '1' : '') : String(v ?? '');
                        }
                        return result;
                    };

                    const attendeesPayload = {};
                    for (const ticket of this.selectedTickets) {
                        const rows = (this.attendees[ticket.id] || []).map((a) => ({
                            holder_name: String(a.holder_name || '').trim(),
                            holder_email: String(a.holder_email || '').trim(),
                            meta: sanitizeMeta(a.meta),
                        }));
                        if (rows.length > 0) {
                            attendeesPayload[ticket.id] = rows;
                        }
                    }

                    const bodyPayload = {
                        attendees: attendeesPayload,
                        idempotency_key: this._idempotencyKey,
                    };
                    if (this.isGuest) {
                        bodyPayload.checkout_email = String(this.guestEmail || '').trim();
                    }

                    try {
                        const response = await fetch(this.storeUrl, {
                            method: 'POST',
                            body: JSON.stringify(bodyPayload),
                            credentials: 'same-origin',
                            headers: {
                                'Content-Type': 'application/json',
                                Accept: 'application/json',
                                'X-CSRF-TOKEN': getCsrfToken(),
                                'X-Requested-With': 'XMLHttpRequest',
                            },
                        });

                        if (!response.ok) {
                            let msg =
                                window.rtCheckoutStrings?.purchaseError ||
                                'No pudimos procesar tu compra. Inténtalo de nuevo.';
                            try {
                                const data = await response.json();
                                if (data && typeof data.message === 'string') {
                                    msg = data.message;
                                }
                                if (data && data.errors) {
                                    const first = Object.values(data.errors).flat()[0];
                                    if (first) {
                                        msg = first;
                                    }
                                }
                            } catch (_) {
                                /* ignore */
                            }
                            this.errorMessage = msg;
                            this.submitting = false;
                            return;
                        }

                        const data = await response.json().catch(() => null);
                        if (data && data.redirect) {
                            window.location.href = data.redirect;
                            return;
                        }
                        window.location.reload();
                    } catch (e) {
                        this.errorMessage =
                            window.rtCheckoutStrings?.networkError ||
                            'Error de red. Verifica tu conexión.';
                        this.submitting = false;
                    }
                },
            },

            mounted() {
                window.addEventListener('keydown', this.onEscapeKey);
            },

            unmounted() {
                window.removeEventListener('keydown', this.onEscapeKey);
            },
        }).mount('#rt-checkout-mount');
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', mountCheckout);
    } else {
        mountCheckout();
    }
})();
