/**
 * Mapa (AdvancedMarker) + PlaceAutocompleteElement + geocodificación inversa — formulario sede (CRUD).
 * Carga del API: loading=async + callback (recomendación Google).
 */
(function (global) {
    'use strict';

    function loadMapsScript(apiKey, done) {
        if (global.google && global.google.maps && typeof global.google.maps.importLibrary === 'function') {
            done(true);
            return;
        }
        var id = 'rt-google-maps-venue-page-js';
        if (document.getElementById(id)) {
            var n = 0;
            var t = setInterval(function () {
                n += 1;
                if (global.google && global.google.maps && typeof global.google.maps.importLibrary === 'function') {
                    clearInterval(t);
                    done(true);
                } else if (n > 200) {
                    clearInterval(t);
                    done(false);
                }
            }, 50);
            return;
        }
        var cb = '__rtGmCb_' + Math.random().toString(36).slice(2);
        global[cb] = function () {
            try {
                delete global[cb];
            } catch (e) {
                /* ignore */
            }
            done(!!(global.google && global.google.maps));
        };
        var s = document.createElement('script');
        s.id = id;
        s.async = true;
        s.src =
            'https://maps.googleapis.com/maps/api/js?key=' +
            encodeURIComponent(apiKey) +
            '&libraries=places&v=weekly&loading=async&callback=' +
            encodeURIComponent(cb);
        s.onerror = function () {
            try {
                delete global[cb];
            } catch (e2) {
                /* ignore */
            }
            done(false);
        };
        document.head.appendChild(s);
    }

    function parseAddressComponents(components) {
        var streetNumber = '';
        var route = '';
        var subpremise = '';
        var premise = '';
        var locality = '';
        var sublocality = '';
        var admin2 = '';
        var out = { street: '', city: '', region: '', postal: '', country: '', line2: '' };
        if (!components || !components.length) {
            return out;
        }
        for (var i = 0; i < components.length; i++) {
            var c = components[i];
            var types = c.types || [];
            if (types.indexOf('street_number') !== -1) {
                streetNumber = c.long_name || '';
            }
            if (types.indexOf('route') !== -1) {
                route = c.long_name || '';
            }
            if (types.indexOf('subpremise') !== -1 && !subpremise) {
                subpremise = c.long_name || '';
            }
            if (types.indexOf('premise') !== -1 && !premise) {
                premise = c.long_name || '';
            }
            if (types.indexOf('locality') !== -1 && !locality) {
                locality = c.long_name || '';
            }
            if (types.indexOf('sublocality_level_1') !== -1 && !sublocality) {
                sublocality = c.long_name || '';
            }
            if (types.indexOf('administrative_area_level_2') !== -1 && !admin2) {
                admin2 = c.long_name || '';
            }
            if (types.indexOf('administrative_area_level_1') !== -1 && !out.region) {
                out.region = c.short_name || c.long_name || '';
            }
            if (types.indexOf('postal_code') !== -1) {
                out.postal = c.long_name || '';
            }
            if (types.indexOf('country') !== -1) {
                out.country = (c.short_name || '').toUpperCase();
            }
        }
        out.street = [streetNumber, route].filter(Boolean).join(' ').trim();
        out.city = locality || sublocality || admin2 || '';
        var line2Parts = [subpremise, premise].filter(Boolean);
        out.line2 = line2Parts.join(', ');
        return out;
    }

    function setInput(id, val) {
        var el = document.getElementById(id);
        if (!el || typeof val !== 'string') {
            return;
        }
        el.value = val;
        if (el.tomselect && typeof el.tomselect.setValue === 'function') {
            el.tomselect.setValue(val, true);
        } else {
            el.dispatchEvent(new Event('change', { bubbles: true }));
        }
    }

    function getInputFloat(id) {
        var el = document.getElementById(id);
        if (!el || el.value === '') {
            return NaN;
        }
        return parseFloat(String(el.value).replace(',', '.'));
    }

    function fillFieldsFromGeocode(placeOrResult) {
        var formatted = placeOrResult.formatted_address || '';
        var fields = parseAddressComponents(placeOrResult.address_components || []);
        if (formatted) {
            setInput('address_line_1', formatted);
        } else if (fields.street) {
            setInput('address_line_1', fields.street);
        }
        setInput('address_line_2', fields.line2 || '');
        setInput('city', fields.city || '');
        setInput('region', fields.region || '');
        setInput('postal_code', fields.postal || '');
        setInput('country', fields.country || '');
    }

    function latLngLiteral(pos) {
        if (!pos) {
            return null;
        }
        if (typeof pos.lat === 'function') {
            return { lat: pos.lat(), lng: pos.lng() };
        }
        return { lat: Number(pos.lat), lng: Number(pos.lng) };
    }

    function newPlaceToLegacyGeocode(place) {
        var comps = place.addressComponents || [];
        var mapped = [];
        for (var i = 0; i < comps.length; i++) {
            var ac = comps[i];
            mapped.push({
                long_name: ac.longText || ac.longName || '',
                short_name: ac.shortText || ac.shortName || '',
                types: ac.types || [],
            });
        }
        return {
            formatted_address: place.formattedAddress || '',
            address_components: mapped,
        };
    }

    /**
     * @param {{ apiKey: string, mapId?: string }} opts
     */
    function init(opts) {
        var apiKey = opts.apiKey || '';
        var mapId = (opts.mapId || '').trim() || 'DEMO_MAP_ID';
        var mapEl = document.getElementById('rt-venue-page-map');
        if (!apiKey || !mapEl) {
            return;
        }

        loadMapsScript(apiKey, function (ok) {
            if (!ok) {
                return;
            }
            runVenueMap(mapId).catch(function () {
                /* fallos de red / API */
            });
        });
    }

    async function runVenueMap(mapId) {
        await global.google.maps.importLibrary('maps');
        await global.google.maps.importLibrary('places');
        var markerLib = await global.google.maps.importLibrary('marker');
        var AdvancedMarkerElement = markerLib.AdvancedMarkerElement;

        var mapEl = document.getElementById('rt-venue-page-map');
        if (!mapEl) {
            return;
        }

        var lat = getInputFloat('latitude');
        var lng = getInputFloat('longitude');
        var center = { lat: 18.2208, lng: -66.5901 };
        var hasCoords = !isNaN(lat) && !isNaN(lng);
        if (hasCoords) {
            center = { lat: lat, lng: lng };
        }

        var map = new global.google.maps.Map(mapEl, {
            mapId: mapId,
            center: center,
            zoom: hasCoords ? 16 : 8,
            mapTypeControl: false,
            streetViewControl: false,
            fullscreenControl: true,
            gestureHandling: 'cooperative',
        });

        var marker = new AdvancedMarkerElement({
            map: map,
            position: center,
            gmpDraggable: true,
        });

        var geocoder = new global.google.maps.Geocoder();
        var reverseTimer = null;

        function reverseGeocode(latLngObj) {
            geocoder.geocode({ location: latLngObj }, function (results, status) {
                if (status !== 'OK' || !results || !results.length) {
                    return;
                }
                fillFieldsFromGeocode(results[0]);
            });
        }

        function scheduleReverseGeocode(latLngObj) {
            if (reverseTimer) {
                clearTimeout(reverseTimer);
            }
            reverseTimer = setTimeout(function () {
                reverseTimer = null;
                reverseGeocode(latLngObj);
            }, 400);
        }

        function syncCoordsFromMarker() {
            var ll = latLngLiteral(marker.position);
            if (!ll) {
                return;
            }
            setInput('latitude', ll.lat.toFixed(7));
            setInput('longitude', ll.lng.toFixed(7));
            scheduleReverseGeocode(ll);
        }

        marker.addListener('dragend', syncCoordsFromMarker);

        map.addListener('click', function (e) {
            var ll = e.latLng ? latLngLiteral(e.latLng) : null;
            if (!ll) {
                return;
            }
            marker.position = ll;
            setInput('latitude', ll.lat.toFixed(7));
            setInput('longitude', ll.lng.toFixed(7));
            scheduleReverseGeocode(ll);
        });

        setupAddressAutocomplete(map, marker);
    }

    function setupAddressAutocomplete(map, marker) {
        var host = document.getElementById('rt-venue-address-autocomplete-host');
        var hiddenAddr = document.getElementById('address_line_1');
        if (!host || !hiddenAddr) {
            return;
        }

        var placesNs = global.google.maps.places;
        var PlaceAutocompleteElement = placesNs && placesNs.PlaceAutocompleteElement;

        if (PlaceAutocompleteElement) {
            try {
                var pacEl = new PlaceAutocompleteElement({});
                host.appendChild(pacEl);

                function applyBias() {
                    try {
                        var b = map.getBounds();
                        if (b && typeof pacEl.locationBias !== 'undefined') {
                            pacEl.locationBias = b;
                        }
                    } catch (e) {
                        /* ignore */
                    }
                }
                applyBias();
                map.addListener('bounds_changed', applyBias);

                if (hiddenAddr.value) {
                    try {
                        pacEl.value = hiddenAddr.value;
                    } catch (e2) {
                        /* ignore */
                    }
                }

                pacEl.addEventListener('gmp-select', async function (event) {
                    try {
                        var place = event.placePrediction.toPlace();
                        await place.fetchFields({
                            fields: ['addressComponents', 'formattedAddress', 'location', 'viewport'],
                        });
                        var legacy = newPlaceToLegacyGeocode(place);
                        fillFieldsFromGeocode(legacy);
                        var ll = latLngLiteral(place.location);
                        if (ll) {
                            marker.position = ll;
                            map.panTo(ll);
                            map.setZoom(16);
                            setInput('latitude', ll.lat.toFixed(7));
                            setInput('longitude', ll.lng.toFixed(7));
                        }
                        if (place.viewport) {
                            map.fitBounds(place.viewport);
                        }
                    } catch (err) {
                        /* Place API (New) o fetchFields */
                    }
                });
                return;
            } catch (eCtor) {
                /* widget nuevo no disponible: fallback */
            }
        }

        legacyPlacesAutocomplete(host, hiddenAddr, map, marker);
    }

    function legacyPlacesAutocomplete(host, hiddenAddr, map, marker) {
        var input = document.createElement('input');
        input.type = 'text';
        input.className = 'form-control';
        input.autocomplete = 'off';
        input.placeholder = 'Buscar dirección';
        input.value = hiddenAddr.value || '';
        host.appendChild(input);
        input.addEventListener('input', function () {
            hiddenAddr.value = input.value;
        });

        var ac = new global.google.maps.places.Autocomplete(input, {
            fields: ['geometry', 'address_components', 'formatted_address'],
        });
        ac.bindTo('bounds', map);
        ac.addListener('place_changed', function () {
            var place = ac.getPlace();
            if (!place.geometry || !place.geometry.location) {
                return;
            }
            var loc = place.geometry.location;
            var ll = latLngLiteral(loc);
            if (ll) {
                marker.position = ll;
                map.panTo(loc);
                map.setZoom(16);
                setInput('latitude', ll.lat.toFixed(7));
                setInput('longitude', ll.lng.toFixed(7));
            }
            fillFieldsFromGeocode(place);
            input.value = hiddenAddr.value || '';
        });
    }

    global.rtVenuePageMapInit = init;
})(typeof window !== 'undefined' ? window : this);
