document.addEventListener('DOMContentLoaded', () => {
    const darkModeToggle = document.getElementById('darkModeToggle');
    const body = document.body;
    const celsiusRadio = document.getElementById('celsius');
    const fahrenheitRadio = document.getElementById('fahrenheit');

    // Apply the cached theme on page load
    if (localStorage.getItem('darkMode') === 'enabled') {
        body.classList.add('dark-mode');
        darkModeToggle.checked = true;
    }

    darkModeToggle.addEventListener('change', () => {
        if (darkModeToggle.checked) {
            body.classList.add('dark-mode');
            localStorage.setItem('darkMode', 'enabled');
        } else {
            body.classList.remove('dark-mode');
            localStorage.setItem('darkMode', 'disabled');
        }
    });

    const weatherDisplay = document.getElementById('weather-display');
    const citySearchForm = document.getElementById('city-search-form');
    const cityInput = document.getElementById('city-input');
    const favoriteLocationsList = document.getElementById('favorite-locations-list');
    const searchHistoryContainer = document.getElementById('search-history');

    const getUnit = () => localStorage.getItem('unit') || 'metric';

    const getSearchHistory = () => JSON.parse(localStorage.getItem('searchHistory')) || [];

    const saveSearchHistory = (city) => {
        let history = getSearchHistory();
        history = history.filter(item => item.toLowerCase() !== city.toLowerCase());
        history.unshift(city);
        if (history.length > 5) {
            history.pop();
        }
        localStorage.setItem('searchHistory', JSON.stringify(history));
        displaySearchHistory();
    };

    const displaySearchHistory = () => {
        const history = getSearchHistory();
        if (history.length > 0) {
            let historyHtml = '<h6>Recent Searches:</h6><div class="d-flex flex-wrap">';
            history.forEach(city => {
                historyHtml += `<a href="#" class="btn btn-sm btn-outline-secondary me-2 mb-2 history-link" data-city="${city}">${city}</a>`;
            });
            historyHtml += '</div>';
            searchHistoryContainer.innerHTML = historyHtml;
        } else {
            searchHistoryContainer.innerHTML = '';
        }
    };

    const showLoading = () => {
        weatherDisplay.innerHTML = '<div class="card-body text-center"><div class="spinner-border text-primary" role="status"><span class="visually-hidden">Loading...</span></div><p class="mt-2">Loading weather...</p></div>';
    };

    const showError = (message) => {
        weatherDisplay.innerHTML = `<div class="card-body text-center"><div class="alert alert-danger">${message}</div></div>`;
    };

    const getAqiString = (aqi) => {
        switch (aqi) {
            case 1: return 'Good';
            case 2: return 'Fair';
            case 3: return 'Moderate';
            case 4: return 'Poor';
            case 5: return 'Very Poor';
            default: return 'Unknown';
        }
    };

    const showWeather = (data) => {
        if (!data || !data.name || data.cod === "404") {
            showError(data.message || 'Could not display weather data.');
            return;
        }
        const unit = getUnit();
        const unitSymbol = unit === 'metric' ? '°C' : '°F';
        const iconUrl = `https://openweathermap.org/img/wn/${data.weather[0].icon}@2x.png`;
        
        let favoriteStar = '';
        if (isUserLoggedIn) {
            favoriteStar = ` <span id="add-to-favorites" class="favorite-star" style="cursor: pointer; color: orange; font-size: 1.2em;">&#9734;</span>`; // Empty star
        }

        let aqiHtml = '';
        if (data.aqi) {
            aqiHtml = `<p>Air Quality: ${getAqiString(data.aqi)}</p>`;
        }

        let forecastHtml = '';
        if (data.forecast && data.forecast.length > 0) {
            forecastHtml += '<div class="mt-4"><h4>5-Day Forecast</h4><div class="row">';
            data.forecast.forEach(day => {
                const dayDate = new Date(day.dt * 1000);
                const dayName = dayDate.toLocaleDateString('en-US', { weekday: 'short' });
                const iconUrl = `https://openweathermap.org/img/wn/${day.icon}.png`;
                forecastHtml += `
                    <div class="col text-center forecast-day">
                        <p>${dayName}</p>
                        <img src="${iconUrl}" alt="${day.description}" title="${day.description}">
                        <p>${day.temp.toFixed(1)}${unitSymbol}</p>
                    </div>
                `;
            });
            forecastHtml += '</div></div>';
        }

        weatherDisplay.innerHTML = `
            <div class="card-body text-center" data-lat="${data.coord.lat}" data-lon="${data.coord.lon}" data-city="${data.name}">
                <h2 class="card-title">${data.name}${favoriteStar}</h2>
                <img src="${iconUrl}" alt="Weather icon" class="weather-icon">
                <h3>${data.main.temp}${unitSymbol}</h3>
                <p class="text-muted">${data.weather[0].description}</p>
                <p>Humidity: ${data.main.humidity}%</p>
                ${aqiHtml}
                ${forecastHtml}
            </div>
            <div id="weather-map" style="height: 400px; margin-top: 20px;"></div>
        `;

        initMap(data.coord.lat, data.coord.lon);
        saveSearchHistory(data.name);
    };

    const initMap = (lat, lon) => {
        const apiKey = '2350ecafed26b115b1557305d956630d';
        
        const mapContainer = document.getElementById('weather-map');
        if (!mapContainer || mapContainer._leaflet_id) {
            // If map is already initialized, just update its view
            if (mapContainer._leaflet_id) {
                 mapContainer._leaflet_map.setView([lat, lon], 10);
            }
            return;
        }
        
        const map = L.map('weather-map').setView([lat, lon], 10);
        mapContainer._leaflet_map = map; // Store map instance

        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(map);

        const tempLayer = L.tileLayer(`https://tile.openweathermap.org/map/temp_new/{z}/{x}/{y}.png?appid=${apiKey}`, {
            attribution: 'Map data &copy; <a href="https://openweathermap.org">OpenWeatherMap</a>'
        });

        const cloudsLayer = L.tileLayer(`https://tile.openweathermap.org/map/clouds_new/{z}/{x}/{y}.png?appid=${apiKey}`, {
            attribution: 'Map data &copy; <a href="https://openweathermap.org">OpenWeatherMap</a>'
        });

        const precipitationLayer = L.tileLayer(`https://tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}.png?appid=${apiKey}`, {
            attribution: 'Map data &copy; <a href="https://openweathermap.org">OpenWeatherMap</a>'
        });

        const baseMaps = {
            "OpenStreetMap": L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')
        };

        const overlayMaps = {
            "Temperature": tempLayer,
            "Clouds": cloudsLayer,
            "Precipitation": precipitationLayer
        };

        L.control.layers(baseMaps, overlayMaps).addTo(map);
        overlayMaps.Temperature.addTo(map);
    };

    const fetchWeatherByCoords = (lat, lon) => {
        const unit = getUnit();
        showLoading();
        fetch(`weather.php?lat=${lat}&lon=${lon}&units=${unit}`)
            .then(response => response.json())
            .then(data => {
                if (data.error) {
                    showError(data.error);
                } else {
                    showWeather(data);
                }
            })
            .catch(() => showError('Failed to fetch weather data.'));
    };

    const fetchWeatherByCity = (city) => {
        const unit = getUnit();
        showLoading();
        fetch(`weather.php?city=${encodeURIComponent(city)}&units=${unit}`)
            .then(response => response.json())
            .then(data => {
                if (data.error || data.cod === "404") {
                    showError(data.error || data.message);
                } else {
                    showWeather(data);
                }
            })
            .catch(() => showError('Failed to fetch weather data.'));
    };

    const saveLocation = () => {
        const weatherCardBody = weatherDisplay.querySelector('.card-body');
        if (!weatherCardBody) return;

        const city = weatherCardBody.dataset.city;
        const lat = weatherCardBody.dataset.lat;
        const lon = weatherCardBody.dataset.lon;

        if (!city || !lat || !lon) {
            alert('Could not get location data to save.');
            return;
        }

        fetch('save_location.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ city: city, lat: lat, lon: lon }),
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                alert('Location saved!');
                location.reload(); // Reload to see the updated list
            } else {
                alert(data.message || 'Could not save location.');
            }
        })
        .catch(() => alert('An error occurred while saving the location.'));
    };

    const deleteLocation = (locationId, listItemElement) => {
        if (!confirm('Are you sure you want to delete this location?')) return;

        fetch('delete_location.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ location_id: locationId }),
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                listItemElement.remove();
                alert('Location deleted!');
            } else {
                alert(data.message || 'Could not delete location.');
            }
        })
        .catch(() => alert('An error occurred.'));
    };

    const handleSubscription = (locationId, time, subscriptionId, listItem) => {
        const isSubscribing = !!locationId;
        const url = isSubscribing ? 'subscribe_weather.php' : 'unsubscribe_weather.php';
        const body = isSubscribing ? { location_id: locationId, time: time } : { subscription_id: subscriptionId };

        fetch(url, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(body)
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                alert(data.message);
                // Dynamically update the UI
                const controlsDiv = listItem.querySelector('.subscription-controls');
                if (isSubscribing) {
                    const newTime = new Date(`1970-01-01T${time}Z`);
                    const formattedTime = newTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', timeZone: 'UTC' });
                    controlsDiv.innerHTML = `
                        <small>Subscribed for daily alerts at ${formattedTime}.</small>
                        <button class="btn btn-sm btn-warning unsubscribe-btn" data-id="${data.subscription_id}">Unsubscribe</button>
                    `;
                } else {
                    controlsDiv.innerHTML = `
                        <div class="input-group input-group-sm">
                            <input type="time" class="form-control alert-time-input" value="08:00">
                            <button class="btn btn-sm btn-primary subscribe-btn">Subscribe</button>
                        </div>
                    `;
                }
            } else {
                alert(data.message || 'An error occurred.');
            }
        })
        .catch(() => alert('A network error occurred.'));
    };

    citySearchForm.addEventListener('submit', (e) => {
        e.preventDefault();
        const city = cityInput.value.trim();
        if (city) {
            fetchWeatherByCity(city);
        }
    });

    weatherDisplay.addEventListener('click', (e) => {
        if (e.target.id === 'add-to-favorites') {
            saveLocation();
        }
    });

    if (favoriteLocationsList) {
        favoriteLocationsList.addEventListener('click', (e) => {
            e.preventDefault();
            const listItem = e.target.closest('li');
            if (e.target.classList.contains('subscribe-btn')) {
                const locationId = listItem.dataset.locationId;
                const timeInput = listItem.querySelector('.alert-time-input');
                handleSubscription(locationId, timeInput.value, null, listItem);
            } else if (e.target.classList.contains('unsubscribe-btn')) {
                const subscriptionId = e.target.dataset.id;
                handleSubscription(null, null, subscriptionId, listItem);
            }
        });
    }

    if (searchHistoryContainer) {
        searchHistoryContainer.addEventListener('click', (e) => {
            e.preventDefault();
            if (e.target.classList.contains('history-link')) {
                const city = e.target.dataset.city;
                fetchWeatherByCity(city);
            }
        });
    }

    

    const getHistoryBtn = document.getElementById('get-history-btn');
    if (getHistoryBtn) {
        getHistoryBtn.addEventListener('click', () => {
            const city = document.querySelector('#weather-display .card-title')?.textContent;
            const date = document.getElementById('history-date').value;

            if (!city) {
                alert('Please search for a city first.');
                return;
            }

            if (!date) {
                alert('Please select a date.');
                return;
            }

            fetch(`get_history.php?city=${encodeURIComponent(city)}&date=${date}`)
                .then(response => response.json())
                .then(data => {
                    const historyDisplay = document.getElementById('history-display');
                    if (data.error) {
                        historyDisplay.innerHTML = `<div class="alert alert-danger">${data.error}</div>`;
                    } else if (data.length === 0) {
                        historyDisplay.innerHTML = `<div class="alert alert-info">No historical data found for this date.</div>`;
                    } else {
                        let table = '<table class="table table-striped"><thead><tr><th>Time</th><th>Temp</th><th>Humidity</th><th>Description</th></tr></thead><tbody>';
                        data.forEach(record => {
                            const recordDate = new Date(record.timestamp + ' UTC');
                            table += `<tr>
                                <td>${recordDate.toLocaleTimeString()}</td>
                                <td>${record.temperature}°C</td>
                                <td>${record.humidity}%</td>
                                <td>${record.description}</td>
                            </tr>`;
                        });
                        table += '</tbody></table>';
                        historyDisplay.innerHTML = table;
                    }
                })
                .catch(() => {
                    const historyDisplay = document.getElementById('history-display');
                    historyDisplay.innerHTML = `<div class="alert alert-danger">Failed to fetch historical data.</div>`;
                });
        });
    }

    // Set initial unit toggle state
    if (getUnit() === 'imperial') {
        fahrenheitRadio.checked = true;
    } else {
        celsiusRadio.checked = true;
    }

    // Add event listeners for unit switching
    [celsiusRadio, fahrenheitRadio].forEach(radio => {
        radio.addEventListener('change', () => {
            const selectedUnit = fahrenheitRadio.checked ? 'imperial' : 'metric';
            localStorage.setItem('unit', selectedUnit);
            const currentCity = document.querySelector('#weather-display .card-title')?.textContent;
            if (currentCity) {
                fetchWeatherByCity(currentCity);
            }
        });
    });

    // Initial weather fetch
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
            position => {
                fetchWeatherByCoords(position.coords.latitude, position.coords.longitude);
            },
            () => {
                displaySearchHistory();
                // Don't show an error, just let the user search.
            }
        );
    } else {
        displaySearchHistory();
    }

    // Initial display of search history
    displaySearchHistory();
});
