import axios from 'axios';
import { ready, delegate } from '@site/js/utils/dom.js';

/**
 * "Alternative Products" overlay.
 *
 * Opened from `.alternativeTrigger` links on product pages when the
 * primary item is unavailable. The overlay lists alternative items, each
 * rendered as a small `.alternativeAddForm` with an optional pack-size
 * select, a quantity input, and an `Add` button.
 *
 * Add-to-basket posts to /shop/addtobasket.php, then emits the standard
 * `receiveBasketUpdate` EventBus message so the mini-basket refreshes
 * itself. A 4-second success/error status sits next to the button —
 * timer IDs live in a WeakMap so a fast re-submit can cancel the
 * pending hide without leaking timers.
 *
 * Styling lives in sites/default/css/shop/alternative_overlay.less.
 */

// Per-status-element timer store so we can cancel a pending hide if the
// user re-submits before the success/error message has faded.
const altStatusTimers = new WeakMap();

ready(() => {

    // Open the overlay (vanilla Overlay from site_scripts/mtc_overlay.js).
    window.mtcOverlay('.alternativeTrigger', {
        content_class: 'overlaySidePanel alternativeOverlayBox',
        margin_vertical: 0,
        margin_horizontal: 0,
    });

    // Clear the error state on the pack-size select whenever the user picks
    // a new size (delegated — the overlay renders these on demand).
    delegate(document, '.alternativeAddForm .js-alt-size', 'change', (event, sizeField) => {
        sizeField.classList.remove('is-error');
        const container = sizeField.closest('.alternativeAddForm');
        const status = container?.querySelector('.js-alt-status');
        if (status) {
            status.textContent = '';
            status.classList.remove('is-error', 'is-success');
        }
    });

    // Add-to-basket from the alternative-products overlay.
    delegate(document, '.js-alt-add', 'click', async (event, button) => {
        event.preventDefault();

        const container = button.closest('.alternativeAddForm');
        if (!container) {
            return;
        }

        const itemId = Number(container.dataset.itemId);
        const redirectUrl = container.dataset.redirect || '';
        const sizeField = container.querySelector('.js-alt-size');
        const requiresSize = !!sizeField
            && sizeField.tagName === 'SELECT'
            && sizeField.required;
        const sizeValue = sizeField ? sizeField.value : undefined;
        const qtyField = container.querySelector('.js-alt-qty');
        const quantity = Math.max(parseInt(qtyField?.value ?? '1', 10) || 1, 1);
        const status = container.querySelector('.js-alt-status');

        const pendingTimer = status ? altStatusTimers.get(status) : null;
        if (pendingTimer) {
            clearTimeout(pendingTimer);
        }
        status?.classList.remove('is-error', 'is-success');

        if (!itemId) {
            return;
        }

        if (requiresSize && !sizeValue) {
            sizeField.classList.add('is-error');
            if (status) {
                status.textContent = 'Choose a pack size.';
                status.classList.add('is-error');
            }
            return;
        }

        const payload = new URLSearchParams();
        payload.set('ajax', '1');
        payload.set('id', String(itemId));
        payload.set('quantity', String(quantity));
        payload.set('url_redirect', redirectUrl);
        if (typeof sizeValue !== 'undefined') {
            payload.set('size', sizeValue || '');
        }

        button.classList.add('is-loading');
        button.disabled = true;

        let response;
        let networkOk = true;
        try {
            const result = await axios.post('/shop/addtobasket.php', payload, {
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            });
            response = result.data;
        } catch (err) {
            networkOk = false;
            const httpStatus = err.response?.status ?? 'network error';
            const message = err.response?.data?.message ?? err.message;
            console.error(`[alternativeAddForm] ${httpStatus}: ${message}`);
            if (status) {
                status.textContent = 'Unable to add to basket.';
                status.classList.add('is-error');
            }
        }

        if (networkOk) {
            const responseStatus = response && response.status;
            if (responseStatus === 'ok') {
                if (status) {
                    status.textContent = 'Added to basket.';
                    status.classList.add('is-success');
                }
                if (window.EventBus && typeof window.EventBus.$emit === 'function') {
                    window.EventBus.$emit('receiveBasketUpdate');
                }
                window.setTimeout(() => {
                    const overlayBox = button.closest('.overlayBox');
                    const closeLink = overlayBox?.querySelector('.overlayCloseButton > a');
                    closeLink?.click();
                }, 300);
            } else {
                const message = (response && response.message) || 'Unable to add to basket.';
                if (status) {
                    status.textContent = message;
                    status.classList.add('is-error');
                }
                if (response && response.error === 'size' && requiresSize && sizeField) {
                    sizeField.classList.add('is-error');
                }
            }
        }

        button.classList.remove('is-loading');
        button.disabled = false;

        if (status) {
            const timer = window.setTimeout(() => {
                status.textContent = '';
                status.classList.remove('is-error', 'is-success');
                altStatusTimers.delete(status);
            }, 4000);
            altStatusTimers.set(status, timer);
        }
    });
});
