<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>Magic Mountain Incident Tracker</title>

    

    <!-- Leaflet CSS -->

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />

    <!-- Leaflet MarkerCluster CSS -->

    <link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster/dist/MarkerCluster.css" />

    <link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster/dist/MarkerCluster.Default.css" />

    <!-- Tailwind CSS -->

    <script src="https://cdn.tailwindcss.com"></script>

    <!-- FontAwesome -->

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" />


    <style>

        body, html { 

            height: 100%; 

            width: 100%; 

            margin: 0; 

            padding: 0;

            overflow: hidden; /* Prevent body scroll */

        }


        #map { 

            /* Use absolute positioning instead of vh to fit exact available space */

            position: absolute;

            top: 0;

            bottom: 0;

            left: 0;

            right: 0;

            width: 100%;

            height: 100%;

            z-index: 0; 

        }


        

        /* Define custom map controls */

        .leaflet-control-layers {

            border-radius: 8px;

            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06) !important;

            border: none !important;

            padding: 10px !important;

            font-family: system-ui, -apple-system, sans-serif;

            background: white;

            max-width: 250px; /* Prevent it getting too wide on mobile */

        }

        

        /* Style title in standard control */

        .layer-control-title {

            font-weight: 700;

            margin-bottom: 8px;

            color: #374151; /* gray-700 */

            border-bottom: 1px solid #e5e7eb; /* gray-200 */

            padding-bottom: 4px;

            font-size: 0.875rem; /* text-sm */

            display: block;

        }


        /* Add spinner */

        .loader {

            border: 3px solid #f3f3f3;

            border-radius: 50%;

            border-top: 3px solid #3b82f6;

            width: 20px;

            height: 20px;

            -webkit-animation: spin 1s linear infinite; /* Safari */

            animation: spin 1s linear infinite;

        }


        @keyframes spin {

            0% { transform: rotate(0deg); }

            100% { transform: rotate(360deg); }

        }


        /* Mobile Leaflet controls */

        @media (max-width: 640px) {

            .leaflet-top { top: 120px; } /* This pushes the controls down so they don't hide behind title */

            .leaflet-control-layers { font-size: 14px; }

        }

    </style>

</head>

<body class="bg-gray-100">


    <!-- Map Container -->

    <div id="map"></div>


    <!-- UI Overlay: Title (Responsive) -->

    <!-- 

         Mobile: Top, full width minus margins, smaller text

         Desktop: Top-left, specific width, larger text

    -->

    <div class="absolute top-2 left-2 right-2 md:top-4 md:left-14 md:right-auto md:w-auto z-[1000] bg-white p-3 md:p-6 rounded-lg shadow-lg md:max-w-lg border-l-4 md:border-l-8 border-red-600">

        <div class="flex flex-col">

            <h1 class="text-xl md:text-3xl font-bold text-gray-800 mb-1 whitespace-nowrap overflow-hidden text-ellipsis">

                <i class="fas fa-mountain text-red-600 mr-2"></i>Magic Mtn Patrol

            </h1>

            <h2 class="text-sm md:text-xl font-semibold text-gray-500 mb-1 md:mb-2">Incident Reporting Tool</h2>

            <p class="text-xs md:text-sm text-gray-400 hidden md:block mt-1">Click the map to log a new incident.</p>

            <div id="connection-status" class="mt-1 md:mt-2 text-xs text-amber-600 font-semibold cursor-pointer hover:underline" onclick="init()">

                <i class="fas fa-spinner fa-spin mr-1"></i> Connecting...

            </div>

        </div>

    </div>


    <!-- Incident Form Modal -->

    <div id="incident-modal" class="fixed inset-0 z-[2000] bg-black bg-opacity-50 hidden flex items-center justify-center p-4">

        <!-- Added max-h- and flex-col to handle mobile keyboards -->

        <div class="bg-white rounded-xl shadow-2xl w-full max-w-md flex flex-col max-h-[90vh] transform transition-all">

            <!-- Header -->

            <div class="bg-gray-800 p-4 flex justify-between items-center flex-shrink-0 rounded-t-xl">

                <h2 class="text-white font-bold text-lg"><i class="fas fa-clipboard-list mr-2"></i>Log Incident</h2>

                <button onclick="closeModal()" class="text-gray-400 hover:text-white transition p-2">

                    <i class="fas fa-times text-xl"></i>

                </button>

            </div>


            <!-- Form -->

            <form id="incident-form" class="p-6 space-y-4 overflow-y-auto">

                <input type="hidden" id="lat" name="Latitude">

                <input type="hidden" id="lng" name="Longitude">


                <div class="grid grid-cols-2 gap-4">

                    <div>

                        <label class="block text-xs font-bold text-gray-500 uppercase mb-1">Date</label>

                        <!-- This prevents iOS zoom -->

                        <input type="date" id="date" name="Date" class="w-full bg-gray-50 border border-gray-300 rounded p-2 text-base focus:outline-none focus:border-red-500" required>

                    </div>

                    <div>

                        <label class="block text-xs font-bold text-gray-500 uppercase mb-1">Incident #</label>

                        <input type="text" id="incident_num" name="Incident_Num" placeholder="e.g. 25/26-###" class="w-full bg-gray-50 border border-gray-300 rounded p-2 text-base focus:outline-none focus:border-red-500" required>

                    </div>

                </div>


                <div>

                    <label class="block text-xs font-bold text-gray-500 uppercase mb-1">Transport Type</label>

                    <div class="relative">

                        <select id="transport" name="Transport_Type" class="w-full bg-gray-50 border border-gray-300 rounded p-2 text-base appearance-none focus:outline-none focus:border-red-500" required>

                            <option value="">Select type...</option>

                            <option value="Non-Injury Transport">Non-Injury Transport</option>

                            <option value="Injury Transport">Injury Transport</option>

                        </select>

                        <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">

                            <i class="fas fa-chevron-down text-xs"></i>

                        </div>

                    </div>

                </div>


                <div>

                    <label class="block text-xs font-bold text-gray-500 uppercase mb-1">Location Coords</label>

                    <div class="text-sm bg-gray-100 p-2 rounded text-gray-600 font-mono" id="coord-display">

                        -

                    </div>

                </div>


                <div>

                    <label class="block text-xs font-bold text-gray-500 uppercase mb-1">Comments</label>

                    <textarea id="comment" name="Comment" rows="3" class="w-full bg-gray-50 border border-gray-300 rounded p-2 text-base focus:outline-none focus:border-red-500" placeholder="Describe trail conditions, specific injury, etc."></textarea>

                </div>


                <div class="pt-2 pb-2">

                    <button type="submit" id="submit-btn" class="w-full bg-red-600 hover:bg-red-700 text-white font-bold py-3 rounded shadow transition flex justify-center items-center text-lg">

                        <span id="btn-text">Submit Report</span>

                        <div id="btn-loader" class="loader ml-2 hidden"></div>

                    </button>

                </div>

            </form>

        </div>

    </div>


    <!-- Scripts -->

    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>

    <script src="https://unpkg.com/leaflet.markercluster/dist/leaflet.markercluster.js"></script>


    <script>

        // CONFIG

        let SCRIPT_URL = 'https://script.google.com/macros/s/AKfycbzYjs0OeOcV1sGnB8cl4gMNA7DzPJID2hsKjCN7Mdkq5XLaT2dE-WSvrQ-4oMG-QXHB/exec';

        SCRIPT_URL = SCRIPT_URL.trim(); 

        

        // --- MAP SETUP ---

        // Center on Magic Mtn

        const INITIAL_CENTER = [43.197123, -72.765931];

        const INITIAL_ZOOM = 16;

        const map = L.map('map', {

            zoomControl: false // Disable default zoom control to position it better for mobile

        }).setView(INITIAL_CENTER, INITIAL_ZOOM);


        // Re-add Zoom control in a better position (Top Left, below title roughly)

        L.control.zoom({

            position: 'topleft'

        }).addTo(map);


        // Base Layer: Standard OSM (Default)

        const osmMap = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {

            maxZoom: 19,

            attribution: '© OpenStreetMap contributors'

        }).addTo(map);


        // Base Layer: Satellite Imagery (Esri World Imagery)

        const satelliteMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {

            maxZoom: 19,

            attribution: 'Tiles &copy; Esri'

        });


        // Overlay: Ski Trails (OpenSnowMap)

        const skiTrails = L.tileLayer('https://tiles.opensnowmap.org/pistes/{z}/{x}/{y}.png', {

            maxZoom: 18,

            attribution: '© OpenSnowMap.org'

        }).addTo(map);


        // Custom Icons

        const thickCrossSvg = `

        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="5" stroke="currentColor" class="w-5 h-5">

            <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />

        </svg>`;


        // Injury: Red Circle, White Cross

        const injuryIcon = L.divIcon({

            html: `<div class="w-8 h-8 bg-red-600 rounded-full border-2 border-white shadow-lg flex items-center justify-center text-white">${thickCrossSvg}</div>`,

            className: '',

            iconSize: [32, 32],

            iconAnchor: [16, 32],

            popupAnchor: [0, -32]

        });


        // Non-Injury: Green Circle, White Cross

        const nonInjuryIcon = L.divIcon({

            html: `<div class="w-8 h-8 bg-green-600 rounded-full border-2 border-white shadow-lg flex items-center justify-center text-white">${thickCrossSvg}</div>`,

            className: '',

            iconSize: [32, 32],

            iconAnchor: [16, 32],

            popupAnchor: [0, -32]

        });


        // Layer Groups

        const injuryLayer = L.layerGroup();

        const nonInjuryLayer = L.layerGroup();

        const allIncidentsLayer = L.layerGroup([injuryLayer, nonInjuryLayer]).addTo(map);

        const clusterLayer = L.markerClusterGroup(); 


        // Layer Control - Standard (Base Maps & Trails)

        const baseMaps = {

            "Standard Sheet": osmMap,

            "Satellite Imagery": satelliteMap

        };


        const overlayMaps = {

            "Ski Trails": skiTrails,

            "Incident Locations": allIncidentsLayer, 

            "Incident Clustering": clusterLayer 

        };

        const layerControl = L.control.layers(baseMaps, overlayMaps, { collapsed: true, position: 'topright' }).addTo(map);


        // Add "Data Layers" into the standard control

        const layerContainer = layerControl.getContainer();

        const titleDiv = document.createElement('div');

        titleDiv.className = 'layer-control-title';

        titleDiv.innerText = 'Data Layers';

        // Insert at the top of the container

        layerContainer.insertBefore(titleDiv, layerContainer.firstChild);



        // --- Apply Filter ---

        function applyIncidentFilter() {

            const filterValue = document.getElementById('incident-filter')?.value || 'all';

            

            allIncidentsLayer.clearLayers();


            if (filterValue === 'all') {

                allIncidentsLayer.addLayer(injuryLayer);

                allIncidentsLayer.addLayer(nonInjuryLayer);

            } else if (filterValue === 'injury') {

                allIncidentsLayer.addLayer(injuryLayer);

            } else if (filterValue === 'noninjury') {

                allIncidentsLayer.addLayer(nonInjuryLayer);

            }

        }



        // --- Exclusion Logic (Clusters vs Locations) ---

        map.on('overlayadd', function(e) {

            setTimeout(() => {

                if (e.name === 'Incident Clustering') {

                    if (map.hasLayer(allIncidentsLayer)) {

                        map.removeLayer(allIncidentsLayer);

                    }

                }

                else if (e.name === 'Incident Locations') {

                    if (map.hasLayer(clusterLayer)) {

                        map.removeLayer(clusterLayer);

                    }

                    applyIncidentFilter();

                }

            }, 50);

        });



        // --- Home Button ---

        const homeControl = L.control({ position: 'topleft' });

        homeControl.onAdd = function(map) {

            const div = L.DomUtil.create('div', 'leaflet-bar leaflet-control');

            div.innerHTML = `

                <a href="#" title="Home / Reset View" role="button" style="width: 30px; height: 30px; line-height: 30px; display: flex; align-items: center; justify-content: center; background-color: white; color: #333;">

                    <i class="fas fa-home"></i>

                </a>

            `;

            div.onclick = function(e) {

                e.preventDefault();

                e.stopPropagation();

                map.setView(INITIAL_CENTER, INITIAL_ZOOM);

            };

            return div;

        };

        homeControl.addTo(map);


        // --- Dropdown Filter ---

        const filterControl = L.control({position: 'topright'});

        filterControl.onAdd = function (map) {

            const div = L.DomUtil.create('div', 'bg-white p-3 rounded-lg shadow-xl text-sm border border-gray-200');

            div.innerHTML = `

                <div class="font-bold mb-2 text-gray-700 border-b pb-1 whitespace-nowrap">Incident Type Filter</div>

                <div class="relative">

                    <select id="incident-filter" class="w-full bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2">

                        <option value="all" selected>Show All Incidents</option>

                        <option value="injury">Injury Only</option>

                        <option value="noninjury">Non-Injury Only</option>

                    </select>

                </div>

            `;

            

            L.DomEvent.disableClickPropagation(div);

            return div;

        };

        filterControl.addTo(map);


        // Bind Dropdown Events

        setTimeout(() => {

            const filterSelect = document.getElementById('incident-filter');

            filterSelect.addEventListener('change', (e) => {

                applyIncidentFilter();

            });

        }, 500); 



        // --- App Logic ---


        function init() {

            const statusEl = document.getElementById('connection-status');

            statusEl.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i> Connecting to Sheet...';

            statusEl.className = "mt-1 md:mt-2 text-xs text-amber-600 font-semibold cursor-pointer hover:underline";

            statusEl.onclick = init; 

            

            if (SCRIPT_URL) {

                fetchData();

            } else {

                console.log("No SCRIPT_URL provided. Using mock data.");

                statusEl.innerHTML = '<i class="fas fa-wifi mr-1"></i> Demo Mode (No URL)';

                processData(mockData);

            }

        }


        function fetchData() {

            const statusEl = document.getElementById('connection-status');

            const fetchUrl = `${SCRIPT_URL}?action=read`;

            console.log("Fetching:", fetchUrl);


            fetch(fetchUrl, { 

                method: 'GET',

                credentials: 'omit',

                mode: 'cors',

                redirect: 'follow'

            })

                .then(response => {

                    if (!response.ok) {

                         throw new Error(`HTTP Error: ${response.status}`);

                    }

                    return response.json();

                })

                .then(data => {

                    processData(data);

                    statusEl.innerHTML = '<i class="fas fa-link text-green-500"></i> Connected to Live Database';

                    statusEl.className = "mt-1 md:mt-2 text-xs text-green-600 font-semibold";

                    statusEl.title = "Connection Successful";

                    statusEl.onclick = null; 

                })

                .catch(error => {

                    console.error('Fetch Failed:', error);

                    processData(mockData);

                    statusEl.innerHTML = `<i class="fas fa-info-circle"></i> Demo Data (Live View Blocked)`;

                    statusEl.className = "mt-1 md:mt-2 text-xs text-orange-600 font-semibold cursor-pointer hover:underline";

                    statusEl.title = "The preview environment blocked the database connection.";

                    statusEl.onclick = function() {

                        window.open(SCRIPT_URL, '_blank');

                    };

                });

        }


        function processData(data) {

            injuryLayer.clearLayers();

            nonInjuryLayer.clearLayers();

            clusterLayer.clearLayers();

            allIncidentsLayer.clearLayers(); 


            if (!Array.isArray(data)) {

                console.warn("Data is not an array:", data);

                return;

            }


            const sortedData = [...data].reverse();


            sortedData.forEach(point => {

                if (!point.Latitude || !point.Longitude) return;


                const lat = parseFloat(point.Latitude);

                const lng = parseFloat(point.Longitude);

                

                if (isNaN(lat) || isNaN(lng)) return;


                const isInjury = point.Transport_Type === 'Injury Transport';


                const marker = L.marker([lat, lng], {

                    icon: isInjury ? injuryIcon : nonInjuryIcon

                });


                const popupContent = `

                    <div class="font-sans">

                        <div class="font-bold text-lg border-b pb-1 mb-2 ${isInjury ? 'text-red-600' : 'text-blue-600'}">

                            ${point.Incident_Num || 'No ID'}

                        </div>

                        <p><strong>Date:</strong> ${point.Date ? new Date(point.Date).toLocaleDateString() : 'N/A'}</p>

                        <p><strong>Type:</strong> ${point.Transport_Type}</p>

                        <p class="mt-2"><strong>Comment:</strong> <span class="text-gray-600 italic">"${point.Comment || ''}"</span></p>

                    </div>

                `;


                marker.bindPopup(popupContent);


                if (isInjury) {

                    injuryLayer.addLayer(marker);

                } else {

                    nonInjuryLayer.addLayer(marker);

                }

                

                clusterLayer.addLayer(marker);

            });


            applyIncidentFilter();

        }


        // --- Map Interactions ---


        map.on('click', function(e) {

            const lat = e.latlng.lat.toFixed(6);

            const lng = e.latlng.lng.toFixed(6);


            document.getElementById('lat').value = lat;

            document.getElementById('lng').value = lng;

            document.getElementById('coord-display').innerText = `${lat}, ${lng}`;

            

            const today = new Date().toISOString().split('T')[0];

            document.getElementById('date').value = today;


            document.getElementById('incident-modal').classList.remove('hidden');

        });


        function closeModal() {

            document.getElementById('incident-modal').classList.add('hidden');

            document.getElementById('incident-form').reset();

        }


        document.getElementById('incident-form').addEventListener('submit', function(e) {

            e.preventDefault();


            const submitBtn = document.getElementById('submit-btn');

            const btnText = document.getElementById('btn-text');

            const loader = document.getElementById('btn-loader');

            

            submitBtn.disabled = true;

            submitBtn.classList.add('opacity-75');

            btnText.innerText = 'Submitting...';

            loader.classList.remove('hidden');


            const formData = new FormData(e.target);

            const data = Object.fromEntries(formData.entries());


            if (SCRIPT_URL) {

                fetch(SCRIPT_URL, {

                    method: 'POST',

                    mode: 'no-cors', 

                    headers: {

                        'Content-Type': 'application/json',

                    },

                    body: JSON.stringify(data)

                })

                .then(() => {

                    handleSuccess(data);

                })

                .catch(err => {

                    console.error('Error:', err);

                    alert("Failed to save data. Check console.");

                    resetButton();

                });

            } else {

                setTimeout(() => {

                    handleSuccess(data);

                }, 1000);

            }

        });


        function handleSuccess(data) {

            const isInjury = data.Transport_Type === 'Injury Transport';

            const marker = L.marker([data.Latitude, data.Longitude], {

                icon: isInjury ? injuryIcon : nonInjuryIcon

            });


             const popupContent = `

                <div class="font-sans">

                    <div class="font-bold text-lg border-b pb-1 mb-2 ${isInjury ? 'text-red-600' : 'text-blue-600'}">

                        ${data.Incident_Num}

                    </div>

                    <p><strong>Date:</strong> ${data.Date}</p>

                    <p><strong>Type:</strong> ${data.Transport_Type}</p>

                    <p class="mt-2"><strong>Comment:</strong> <span class="text-gray-600 italic">"${data.Comment}"</span></p>

                </div>

            `;

            marker.bindPopup(popupContent);


            if (isInjury) {

                injuryLayer.addLayer(marker);

            } else {

                nonInjuryLayer.addLayer(marker);

            }

            clusterLayer.addLayer(marker);

            

            // Add to master layer if filter permits

            const filterValue = document.getElementById('incident-filter')?.value || 'all';

            if (filterValue === 'all') {

                allIncidentsLayer.addLayer(isInjury ? injuryLayer : nonInjuryLayer);

            } else if (filterValue === 'injury' && isInjury) {

                 // Already in injuryLayer

            } else if (filterValue === 'noninjury' && !isInjury) {

                 // Already in nonInjuryLayer

            }


            resetButton();

            closeModal();

        }


        function resetButton() {

            const submitBtn = document.getElementById('submit-btn');

            const btnText = document.getElementById('btn-text');

            const loader = document.getElementById('btn-loader');


            submitBtn.disabled = false;

            submitBtn.classList.remove('opacity-75');

            btnText.innerText = 'Submit Report';

            loader.classList.add('hidden');

        }


        init();


    </script>

</body>

</html>