{*
* Alsendo - PrestaShop shipping module
*
* @author    Innovation Software
* @copyright 2026 Innovation Software
* @license   https://opensource.org/licenses/AFL-3.0  Academic Free License (AFL 3.0)
*}
<link rel="stylesheet" href="{$alsendo_map_css_url|escape:'html':'UTF-8'}" media="screen">
<script type="text/javascript" src="{$alsendo_map_js_url|escape:'html':'UTF-8'}" defer></script>
<script type="text/javascript" src="{$smarty.const._MODULE_DIR_|escape:'html':'UTF-8'}alsendo/views/js/map-widget.js" defer></script>

<div id="alsendo-carrier-map-container"
     style="margin-bottom: 15px; display: block; transition: opacity 0.15s ease;"
     data-cart-id="{$alsendo_cart->id|intval|escape:'html':'UTF-8'}"
     data-map-config="{$alsendo_map_config|escape:'html':'UTF-8'}"
     data-shipping-methods="{$alsendo_shipping_methods_json|escape:'html':'UTF-8'}">
    <input type="hidden" id="alsendo_pickup_point" name="alsendo_pickup_point" data-map-selector="pickup" readonly
           value="{$alsendo_pickup_point|escape:'html':'UTF-8'}" />

    <input type="text" id="alsendo_pickup_point_display" readonly data-map-selector="pickup" class="form-control"
           placeholder="{l s='No pickup point selected' mod='alsendo'}"
           value="{$alsendo_pickup_point_display|escape:'html':'UTF-8'}" />
    <div class="clearfix"></div>
    <button id="alsendo-carrier-map-btn" class="btn btn-primary" type="button" style="margin-top: 10px;">
        {l s='Select pickup point' mod='alsendo'}
    </button>
</div>

<script>
    var ALSENDO_MSG_SELECT_PICKUP = "{l s='Please select a pickup point' mod='alsendo' js=1}";
    window.ALSENDO_MAP_TRANSLATIONS = {ldelim}
        loading: "{l s='Loading map...' mod='alsendo' js=1}",
        failed: "{l s='Map widget failed to load' mod='alsendo' js=1}",
        close: "{l s='Close' mod='alsendo' js=1}",
        retry: "{l s='Try again' mod='alsendo' js=1}"
    {rdelim};
    var alsendoShippingCountry = '{$alsendo_shipping_country|escape:'javascript':'UTF-8'}';

    {*
    * Named, idempotent init. The module bootstraps it below; OPC modules (e.g. thecheckout)
    * that re-render the checkout DOM after DOMContentLoaded can call window.alsendoInitCheckout()
    * again safely instead of re-dispatching a global DOMContentLoaded event.
    *}
    window.alsendoInitCheckout = function() {
        var mapContainerEl = document.getElementById('alsendo-carrier-map-container');
        if (!mapContainerEl) {
            return;
        }

        var alsendoCarriers;
        try {
            alsendoCarriers = JSON.parse(mapContainerEl.dataset.shippingMethods || '[]');
        } catch (e) {
            alsendoCarriers = [];
        }
        try {
            window.ALSENDO_MAP_CONFIG = JSON.parse(mapContainerEl.dataset.mapConfig || '{}');
        } catch (e) {
            window.ALSENDO_MAP_CONFIG = {};
        }

        function moveMapBelowCarrier(mapContainer, selectedRadio) {
            if (!mapContainer || !selectedRadio) {
                return;
            }
            var deliveryOption = selectedRadio.closest('.delivery-option');
            if (!deliveryOption) {
                return;
            }
            var insertAfter = deliveryOption;
            var next = deliveryOption.nextElementSibling;
            while (next && !next.classList.contains('delivery-option') && !next.querySelector('input[type="radio"][name^="delivery_option"]')) {
                insertAfter = next;
                next = next.nextElementSibling;
            }
            insertAfter.insertAdjacentElement('afterend', mapContainer);
        }

        function updateMapVisibility() {
            var selectedCarrierId = null;
            var selectedRadio = null;
            var deliveryOptions = document.querySelectorAll('input[type="radio"][name^="delivery_option"]');
            deliveryOptions.forEach(function(input) {
                if (input.checked) {
                    selectedRadio = input;
                    var parts = input.value.split(',');
                    selectedCarrierId = parseInt(parts[0], 10);
                }
            });

            var showMap = false;
            var mapOperator = null;
            if (selectedCarrierId && alsendoCarriers && Array.isArray(alsendoCarriers)) {
                alsendoCarriers.forEach(function(carrier) {
                    if (parseInt(carrier.id_carrier, 10) === selectedCarrierId && carrier.map === true) {
                        showMap = true;
                        mapOperator = carrier.operator || null;
                    }
                });
            }

            var mapContainer = document.getElementById('alsendo-carrier-map-container');
            if (mapContainer) {
                if (showMap && selectedRadio) {
                    moveMapBelowCarrier(mapContainer, selectedRadio);
                    mapContainer.style.display = 'block';
                } else {
                    mapContainer.style.display = 'none';
                }
            }

            updateConfirmButtonState(showMap);
            return { showMap: showMap, mapOperator: mapOperator };
        }

        function updateConfirmButtonState(mapRequired) {
            var confirmBtn = document.querySelector('button[name="confirmDeliveryOption"]');
            var pickupPointInput = document.getElementById('alsendo_pickup_point');

            if (confirmBtn && mapRequired && pickupPointInput) {
                if (!pickupPointInput.value) {
                    confirmBtn.disabled = true;
                    confirmBtn.style.opacity = '0.5';
                    confirmBtn.style.cursor = 'not-allowed';

                    var msgEl = document.getElementById('alsendo-pickup-required-message');
                    if (!msgEl) {
                        msgEl = document.createElement('div');
                        msgEl.id = 'alsendo-pickup-required-message';
                        msgEl.className = 'alert alert-warning';
                        msgEl.textContent = ALSENDO_MSG_SELECT_PICKUP;
                        if (confirmBtn.parentNode) {
                            confirmBtn.parentNode.insertBefore(msgEl, confirmBtn);
                        }
                    }
                } else {
                    confirmBtn.disabled = false;
                    confirmBtn.style.opacity = '';
                    confirmBtn.style.cursor = 'pointer';

                    var msgEl = document.getElementById('alsendo-pickup-required-message');
                    if (msgEl) {
                        msgEl.remove();
                    }
                }
            } else if (confirmBtn && !mapRequired) {
                confirmBtn.disabled = false;
                confirmBtn.style.opacity = '';
                confirmBtn.style.cursor = 'pointer';

                var msgEl = document.getElementById('alsendo-pickup-required-message');
                if (msgEl) {
                    msgEl.remove();
                }
            }
        }

        // Expose for map-widget.js callback after pickup point selection.
        window.alsendoUpdateConfirmButtonState = updateConfirmButtonState;

        function alsendoGetCartId() {
            var cartEl = document.querySelector('[data-cart-id]');
            return (cartEl && cartEl.dataset.cartId) ? cartEl.dataset.cartId : null;
        }

        // Operator of the point currently held in the hidden field (or null when empty/unparseable).
        function alsendoCurrentPointOperator() {
            var ppInput = document.getElementById('alsendo_pickup_point');
            if (!ppInput || !ppInput.value) {
                return null;
            }
            try {
                var data = JSON.parse(ppInput.value);
                return (data && data.operator) ? String(data.operator).toLowerCase().trim() : null;
            } catch (e) {
                return null;
            }
        }

        function alsendoWipePointInputs() {
            var ppInput = document.getElementById('alsendo_pickup_point');
            var ppDisplay = document.getElementById('alsendo_pickup_point_display');
            if (ppInput) {
                ppInput.value = '';
            }
            if (ppDisplay) {
                ppDisplay.value = '';
            }
        }

        function alsendoMatches(a, b) {
            if (typeof window.alsendoOperatorMatches === 'function') {
                return window.alsendoOperatorMatches(a, b);
            }
            a = (a || '').toLowerCase().trim();
            b = (b || '').toLowerCase().trim();
            return !a || !b || a === b || a.indexOf(b) !== -1 || b.indexOf(a) !== -1;
        }

        // Reconcile the stored/selected point with the currently selected carrier.
        // allowDbClear: only true for real carrier changes — never on the observer/init path,
        // so a transient OPC re-render can't delete a valid point from the database.
        function alsendoSyncPointForCarrier(state, allowDbClear) {
            var cartId = alsendoGetCartId();

            if (!state.showMap) {
                // Carrier without a map — the point no longer applies (UI only; keep the DB row,
                // an OPC re-render may briefly report no map carrier before re-selecting one).
                if (document.getElementById('alsendo_pickup_point') &&
                    document.getElementById('alsendo_pickup_point').value) {
                    alsendoWipePointInputs();
                }
                return;
            }

            var wantOperator = (state.mapOperator || '').toLowerCase().trim();
            var haveOperator = alsendoCurrentPointOperator();

            if (haveOperator) {
                // A point is already selected — keep it only if it belongs to this operator.
                // Switching InPost -> DHL lands here and clears the now-invalid InPost point.
                if (!alsendoMatches(haveOperator, wantOperator)) {
                    alsendoWipePointInputs();
                    if (allowDbClear && cartId && typeof window.alsendoClearPickupPointAjax === 'function') {
                        window.alsendoClearPickupPointAjax(cartId);
                    }
                    updateConfirmButtonState(true);
                }
                return;
            }

            // Field empty — restore from DB, but only a point that matches this operator.
            if (cartId && typeof window.alsendoRehydratePickupPoint === 'function') {
                window.alsendoRehydratePickupPoint(cartId, wantOperator);
            }
        }

        var initState = updateMapVisibility();
        alsendoSyncPointForCarrier(initState, false);

        var deliveryOptions = document.querySelectorAll('input[type="radio"][name^="delivery_option"]');
        deliveryOptions.forEach(function(radio) {
            if (radio.dataset.alsendoBound) {
                return;
            }
            radio.dataset.alsendoBound = '1';
            radio.addEventListener('change', function() {
                alsendoSyncPointForCarrier(updateMapVisibility(), true);
            });
        });

        var mapBtn = document.getElementById('alsendo-carrier-map-btn');
        if (mapBtn && !mapBtn.dataset.alsendoBound) {
            mapBtn.dataset.alsendoBound = '1';
            mapBtn.addEventListener('click', function(e) {
                e.preventDefault();
                var state = updateMapVisibility();
                var selectedCarrierCountry = alsendoShippingCountry;
                if (state.mapOperator && alsendoCarriers && Array.isArray(alsendoCarriers)) {
                    alsendoCarriers.forEach(function(carrier) {
                        if (carrier.operator === state.mapOperator && carrier.country) {
                            selectedCarrierCountry = carrier.country;
                        }
                    });
                }
                if (state.mapOperator) {
                    window.openPointMap('pickup', [state.mapOperator], 'DELIVERY', selectedCarrierCountry);
                } else {
                    window.openPointMap('pickup', null, 'DELIVERY', selectedCarrierCountry);
                }
            });
        }

        var pickupPointInput = document.getElementById('alsendo_pickup_point');
        if (pickupPointInput && !pickupPointInput.dataset.alsendoBound) {
            pickupPointInput.dataset.alsendoBound = '1';
            pickupPointInput.addEventListener('change', function() {
                updateConfirmButtonState(true);
            });
        }

        {* Subscribe once per page lifecycle; the handler re-runs the (idempotent) init. *}
        if (typeof prestashop !== 'undefined' && !window.__alsendoDeliveryFormBound) {
            window.__alsendoDeliveryFormBound = true;
            prestashop.on('updatedDeliveryForm', function() {
                setTimeout(function() {
                    window.alsendoInitCheckout();
                }, 50);
            });
        }
    };

    {*
    * Self-bootstrap + auto re-init. A MutationObserver watches the page so that any checkout
    * module (OPC / thecheckout) rebuilding the DOM after load re-triggers our idempotent init
    * automatically — no external call required. The observer disconnects while we run our own
    * init so our DOM changes never cause a feedback loop.
    *}
    (function() {
        function alsendoSafeInit() {
            if (window.__alsendoObserver) {
                window.__alsendoObserver.disconnect();
            }
            window.alsendoInitCheckout();
            if (window.__alsendoObserver && document.body) {
                window.__alsendoObserver.observe(document.body, { childList: true, subtree: true });
            }
        }

        function alsendoBootstrap() {
            if (!window.__alsendoObserver && typeof MutationObserver !== 'undefined') {
                var scheduled = false;
                window.__alsendoObserver = new MutationObserver(function() {
                    if (scheduled) {
                        return;
                    }
                    scheduled = true;
                    setTimeout(function() {
                        scheduled = false;
                        alsendoSafeInit();
                    }, 150);
                });
            }
            alsendoSafeInit();
        }

        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', alsendoBootstrap);
        } else {
            alsendoBootstrap();
        }
    })();
</script>
