/* Minimal Roadtrip JS helpers for HTMX-driven planner
   - Initializes map helpers when Leaflet is available
   - Exposes `RoadtripMap` global with basic marker helpers
   - Heavy client-side trip logic is intentionally moved to HTMX endpoints
*/

class RoadtripMap {
    constructor() {
        this.map = null;
        this.markers = {};
    }

    init(containerId, opts = {}) {
        if (typeof L === 'undefined') return;
        try {
            this.map = L.map(containerId).setView([51.505, -0.09], 5);
            L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: '&copy; OpenStreetMap contributors'
            }).addTo(this.map);
        } catch (e) {
            console.error('Failed to initialize map', e);
        }
    }

    addMarker(park) {
        if (!this.map || !park || !park.latitude || !park.longitude) return;
        const id = park.id;
        if (this.markers[id]) return;
        const m = L.marker([park.latitude, park.longitude]).addTo(this.map).bindPopup(park.name);
        this.markers[id] = m;
    }

    removeMarker(parkId) {
        const m = this.markers[parkId];
        if (m && this.map) {
            this.map.removeLayer(m);
            delete this.markers[parkId];
        }
    }

    fitToMarkers() {
        const keys = Object.keys(this.markers);
        if (!this.map || keys.length === 0) return;
        const group = new L.featureGroup(keys.map(k => this.markers[k]));
        this.map.fitBounds(group.getBounds().pad(0.2));
    }

    showRoute(orderedParks = []) {
        if (!this.map || typeof L.Routing === 'undefined') return;
        // remove existing control if present
        if (this._routingControl) {
            try {
                this.map.removeControl(this._routingControl);
            } catch (e) {}
            this._routingControl = null;
        }

        const waypoints = orderedParks
            .filter(p => p.latitude && p.longitude)
            .map(p => L.latLng(p.latitude, p.longitude));

        if (waypoints.length < 2) return;

        try {
            this._routingControl = L.Routing.control({
                waypoints: waypoints,
                draggableWaypoints: false,
                addWaypoints: false,
                showAlternatives: false,
                routeWhileDragging: false,
                fitSelectedRoute: true,
                createMarker: function(i, wp) {
                    const cls = i === 0 ? 'waypoint-start' : (i === waypoints.length - 1 ? 'waypoint-end' : 'waypoint-stop');
                    return L.marker(wp.latLng, { className: 'waypoint-marker ' + cls }).bindPopup(`Stop ${i+1}`);
                }
            }).addTo(this.map);
        } catch (e) {
            console.error('Routing error', e);
        }
    }
}

// Expose simple global for templates to call
globalThis.RoadtripMap = new RoadtripMap();

// Backwards-compatible lightweight planner shim used by other scripts
class RoadTripPlannerShim {
    constructor(containerId) {
        this.containerId = containerId;
    }

    async addPark(parkId) {
        // POST to HTMX add endpoint and insert returned fragment
        try {
            const csrftoken = (document.cookie.match(/(^|;)\s*csrftoken=([^;]+)/) || [])[2];
            const resp = await fetch(`/parks/roadtrip/htmx/add-park/`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'X-CSRFToken': csrftoken || ''
                },
                body: `park_id=${encodeURIComponent(parkId)}`,
                credentials: 'same-origin'
            });
            const html = await resp.text();
            const container = document.getElementById('trip-parks');
            if (container) container.insertAdjacentHTML('afterbegin', html);
            if (globalThis.RoadtripMap && typeof globalThis.RoadtripMap.addMarker === 'function') {
                try {
                    const parkResp = await fetch(`/api/parks/${parkId}/`);
                    const parkJson = await parkResp.json();
                    if (parkJson && parkJson.data) globalThis.RoadtripMap.addMarker(parkJson.data);
                } catch (e) {
                    // ignore
                }
            }
        } catch (e) {
            console.error('Failed to add park via HTMX shim', e);
        }
    }

    removePark(parkId) {
        const el = document.querySelector(`[data-park-id="${parkId}"]`);
        if (el) el.remove();
        if (globalThis.RoadtripMap && typeof globalThis.RoadtripMap.removeMarker === 'function') {
            globalThis.RoadtripMap.removeMarker(parkId);
        }
    }

    fitRoute() {
        if (globalThis.RoadtripMap && typeof globalThis.RoadtripMap.fitToMarkers === 'function') {
            globalThis.RoadtripMap.fitToMarkers();
        }
    }

    toggleAllParks() {
        // No-op in shim; map integration can implement this separately
        console.debug('toggleAllParks called (shim)');
    }
}

// Expose compatibility globals
globalThis.RoadTripPlanner = RoadTripPlannerShim;
document.addEventListener('DOMContentLoaded', function() {
    try {
        globalThis.roadTripPlanner = new RoadTripPlannerShim('roadtrip-planner');
    } catch (e) {
        // ignore
    }
});
// Initialize Sortable for #trip-parks and POST new order to server
document.addEventListener('DOMContentLoaded', function () {
    try {
        if (typeof Sortable === 'undefined') return;
        const el = document.getElementById('trip-parks');
        if (!el) return;
        // avoid double-init
        if (el._sortableInit) return;
        el._sortableInit = true;

        function getCookie(name) {
            const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
            if (match) return decodeURIComponent(match[2]);
            return null;
        }

        new Sortable(el, {
            animation: 150,
            ghostClass: 'drag-over',
            handle: '.draggable-item',
            onEnd: function (evt) {
                // gather order from container children
                const order = Array.from(el.children).map(function (c) { return c.dataset.parkId; }).filter(Boolean);
                const csrftoken = getCookie('csrftoken');
                fetch('/parks/roadtrip/htmx/reorder/', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRFToken': csrftoken || ''
                    },
                    credentials: 'same-origin',
                    body: JSON.stringify({ order: order })
                }).then(function (r) { return r.text(); }).then(function (html) {
                    // replace inner HTML with server-rendered partial
                    el.innerHTML = html;
                    // notify other listeners (map, summary)
                    document.dispatchEvent(new CustomEvent('tripReordered', { detail: { order: order } }));
                }).catch(function (err) {
                    console.error('Failed to post reorder', err);
                });
            }
        });
    } catch (e) {
        console.error('Sortable init error', e);
    }
});
// Listen for HTMX trigger event and show route when available
document.addEventListener('tripOptimized', function (ev) {
    try {
        const payload = ev && ev.detail ? ev.detail : {};
        const parks = (payload && payload.parks) || [];
        if (globalThis.RoadtripMap && typeof globalThis.RoadtripMap.showRoute === 'function') {
            globalThis.RoadtripMap.showRoute(parks);
        }
    } catch (e) {
        // ignore
    }
});
// End of roadtrip helpers