/**
 * Hierarchical Dropdowns Handler
 * 
 * This script handles hierarchical dropdowns for both categories and geographical regions.
 * It also integrates with the map selection.
 */

// Category Hierarchical Selection
class CategorySelector {
    constructor() {
        console.log('CategorySelector initialization started');
        
        // Try different possible ID combinations that might be used in different forms
        this.mainCategorySelect = document.getElementById('main_category_id') || 
                                   document.getElementById('parent_category_id');
        this.subCategorySelect = document.getElementById('sub_category_id') || 
                                  document.getElementById('category_id');
        this.categoryIdInput = document.getElementById('category_id');
        this.categoryErrorMsg = document.getElementById('category_error');
        this.form = document.querySelector('form');
        
        console.log('Found elements:', {
            mainCategorySelect: !!this.mainCategorySelect,
            subCategorySelect: !!this.subCategorySelect,
            categoryIdInput: !!this.categoryIdInput,
            categoryErrorMsg: !!this.categoryErrorMsg,
            form: !!this.form
        });
        
        // Check if elements were found and log their IDs if available
        if (this.mainCategorySelect) {
            console.log('Main category select ID:', this.mainCategorySelect.id);
        }
        if (this.subCategorySelect) {
            console.log('Sub category select ID:', this.subCategorySelect.id);
        }
        
        if (this.mainCategorySelect && this.subCategorySelect) {
            this.setupCategorySelects();
            this.setupEventListeners();
        } else {
            console.error('Category select elements not found in the DOM. Available elements:', 
                Array.from(document.querySelectorAll('select')).map(el => el.id || 'no-id'));
        }
    }

    setupCategorySelects() {
        // Load all top-level categories (parent_id is null)
        fetch('/admin/api/categories')
            .then(response => response.json())
            .then(data => {
                // Clear existing options
                this.mainCategorySelect.innerHTML = '<option value="">انتخاب دسته‌بندی اصلی</option>';

                // Filter for parent categories (where parent_id is null)
                const parentCategories = data.filter(category => !category.parent_id);

                // Add categories to main dropdown
                parentCategories.forEach(category => {
                    const option = document.createElement('option');
                    option.value = category.id;
                    option.textContent = category.category_fa;
                    this.mainCategorySelect.appendChild(option);
                });

                console.log('Loaded parent categories:', parentCategories.length);

                // Check if we have a previously selected category
                if (this.categoryIdInput && this.categoryIdInput.value) {
                    // Find the selected category in the data
                    const selectedCategory = data.find(cat => cat.id == this.categoryIdInput.value);
                    
                    if (selectedCategory) {
                        if (selectedCategory.parent_id) {
                            // This is a subcategory, set parent and then load subcategories
                            this.mainCategorySelect.value = selectedCategory.parent_id;
                            this.loadSubcategories(selectedCategory.parent_id, selectedCategory.id);
                        } else {
                            // This is a main category
                            this.mainCategorySelect.value = selectedCategory.id;
                            // Check if it has children and load them
                            this.loadSubcategories(selectedCategory.id);
                        }
                    }
                }
            })
            .catch(error => {
                console.error('Error loading categories:', error);
                // Show error message in dropdown
                this.mainCategorySelect.innerHTML = '<option value="">خطا در بارگذاری دسته‌بندی‌ها</option>';
            });
    }

    setSelectedCategory(categoryId) {
        if (this.categoryIdInput) {
            console.log('Setting selected category to:', categoryId);
            this.categoryIdInput.value = categoryId;
            if (this.categoryErrorMsg) {
                this.categoryErrorMsg.classList.toggle('d-none', !!categoryId);
            }
        } else {
            console.error('Cannot set category - categoryIdInput not found');
        }
    }

    setupEventListeners() {
        // When main category changes, load subcategories
        this.mainCategorySelect.addEventListener('change', (e) => {
            const mainCategoryId = e.target.value;
            console.log('Main category changed to:', mainCategoryId);
            
            if (mainCategoryId) {
                // Set the category_id to the main category initially
                this.setSelectedCategory(mainCategoryId);
                
                // Load subcategories
                this.loadSubcategories(mainCategoryId);
            } else {
                // If no main category selected, reset subcategory dropdown
                this.subCategorySelect.innerHTML = '<option value="">ابتدا دسته‌بندی اصلی را انتخاب کنید</option>';
                this.subCategorySelect.disabled = true;
                this.setSelectedCategory('');
            }
        });

        // When subcategory changes, update the hidden input
        this.subCategorySelect.addEventListener('change', (e) => {
            const subCategoryId = e.target.value;
            console.log('Sub category changed to:', subCategoryId);
            
            if (subCategoryId) {
                this.setSelectedCategory(subCategoryId);
            } else if (this.mainCategorySelect.value) {
                // If no subcategory is selected but we have a main category, use the main category ID
                this.setSelectedCategory(this.mainCategorySelect.value);
            } else {
                this.setSelectedCategory('');
            }
        });

        // Form validation for category selection
        if (this.form) {
            this.form.addEventListener('submit', (e) => {
                console.log('Form submitting, checking category...');
                // Check if category is selected
                if (!this.categoryIdInput || !this.categoryIdInput.value) {
                    // Try to use main category if available
                    if (this.mainCategorySelect && this.mainCategorySelect.value) {
                        this.categoryIdInput.value = this.mainCategorySelect.value;
                        console.log('Setting category_id to main category:', this.categoryIdInput.value);
                        return true; // Continue with form submission
                    }
                    
                    console.error('Form submission prevented - no category selected');
                    e.preventDefault();
                    if (this.categoryErrorMsg) {
                        this.categoryErrorMsg.classList.remove('d-none');
                    }
                    // Scroll to the category section
                    this.mainCategorySelect.scrollIntoView({ behavior: 'smooth', block: 'center' });
                    // Flash the dropdown to draw attention
                    this.mainCategorySelect.classList.add('border-danger');
                    setTimeout(() => {
                        this.mainCategorySelect.classList.remove('border-danger');
                    }, 2000);
                } else {
                    console.log('Category is set, proceeding with form submission:', this.categoryIdInput.value);
                }
            });
        }
    }

    loadSubcategories(parentId, selectedId = null) {
        console.log('Loading subcategories for parent:', parentId, 'with selected ID:', selectedId);
        
        // Get the data from the main API and filter for children
        fetch('/admin/api/categories')
            .then(response => response.json())
            .then(data => {
                // Filter for child categories of the selected parent
                const childCategories = data.filter(cat => cat.parent_id == parentId);
                
                // Clear the subcategory select
                this.subCategorySelect.innerHTML = '<option value="">انتخاب زیر دسته</option>';
                
                if (childCategories.length === 0) {
                    // No children, disable the subcategory select
                    this.subCategorySelect.innerHTML = '<option value="">زیردسته‌ای وجود ندارد</option>';
                    this.subCategorySelect.disabled = true;
                    return;
                }
                
                // Add subcategories to dropdown
                childCategories.forEach(category => {
                    const option = document.createElement('option');
                    option.value = category.id;
                    const isEn = document.documentElement.lang === 'en' || (window.appLocale && window.appLocale === 'en');
                    option.textContent = isEn && category.category_en ? category.category_en : category.category_fa;
                    
                    // If we have a selected ID, set it
                    if (selectedId && selectedId == category.id) {
                        option.selected = true;
                        this.setSelectedCategory(selectedId);
                    }
                    
                    this.subCategorySelect.appendChild(option);
                });
                
                // Enable the subcategory dropdown
                this.subCategorySelect.disabled = false;
                
                // If we have selectedId but it's not in the list, it's likely a new category not yet in the dropdown
                // This can happen during validation failures with old input data
                if (selectedId && !Array.from(this.subCategorySelect.options).some(opt => opt.value == selectedId)) {
                    // Try to find it in the original data
                    const selectedCategory = data.find(cat => cat.id == selectedId);
                    if (selectedCategory) {
                        const option = document.createElement('option');
                        option.value = selectedCategory.id;
                        const isEn = document.documentElement.lang === 'en' || (window.appLocale && window.appLocale === 'en');
                        option.textContent = isEn && selectedCategory.category_en ? selectedCategory.category_en : selectedCategory.category_fa;
                        option.selected = true;
                        this.subCategorySelect.appendChild(option);
                        this.setSelectedCategory(selectedId);
                    }
                }
                
                // If selectedId not set but we have a categoryIdInput with a value, and it matches a child
                if (!selectedId && this.categoryIdInput && this.categoryIdInput.value) {
                    const categoryId = this.categoryIdInput.value;
                    // Check if the category ID is one of the children
                    const matchingOption = Array.from(this.subCategorySelect.options).find(opt => opt.value == categoryId);
                    if (matchingOption) {
                        matchingOption.selected = true;
                    }
                }
                
                console.log('Loaded subcategories:', childCategories.length);
            })
            .catch(error => {
                console.error('Error loading subcategories:', error);
                this.subCategorySelect.innerHTML = '<option value="">خطا در بارگذاری زیردسته‌ها</option>';
                this.subCategorySelect.disabled = true;
            });
    }
}

// Geographical Regions Hierarchical Selection
class GeoSelector {
    constructor() {
        // Find all the geographical select elements
        this.countrySelect = document.getElementById('country_id');
        this.provinceSelect = document.getElementById('province_id');
        this.countySelect = document.getElementById('county_id');
        this.districtSelect = document.getElementById('district_id');
        this.citySelect = document.getElementById('city_id');
        this.villageSelect = document.getElementById('village_id');
        this.zoneSelect = document.getElementById('zone_id');
        
        // Address field for automatic population
        this.addressField = document.getElementById('address');
        
        // Initialize empty selected values
        this.selectedRegions = {
            country: null,
            province: null,
            county: null,
            district: null,
            city: null,
            village: null,
            zone: null
        };
        
        this.setupEventListeners();
    }
    
    setupEventListeners() {
        // Country change -> load provinces
        if (this.countrySelect) {
            this.countrySelect.addEventListener('change', () => {
                const countryId = this.countrySelect.value;
                if (countryId) {
                    this.loadProvinces(countryId);
                    this.selectedRegions.country = {
                        id: countryId,
                        name: this.getSelectedOptionText(this.countrySelect)
                    };
                    this.resetSelects('province');
                    this.updateAddress();
                }
            });
        }
        
        // Province change -> load counties
        if (this.provinceSelect) {
            this.provinceSelect.addEventListener('change', () => {
                const provinceId = this.provinceSelect.value;
                if (provinceId) {
                    this.loadCounties(provinceId);
                    this.selectedRegions.province = {
                        id: provinceId,
                        name: this.getSelectedOptionText(this.provinceSelect)
                    };
                    this.resetSelects('county');
                    this.updateAddress();
                }
            });
        }
        
        // County change -> load districts
        if (this.countySelect) {
            this.countySelect.addEventListener('change', () => {
                const countyId = this.countySelect.value;
                if (countyId) {
                    this.loadDistricts(countyId);
                    this.selectedRegions.county = {
                        id: countyId,
                        name: this.getSelectedOptionText(this.countySelect)
                    };
                    this.resetSelects('district');
                    this.updateAddress();
                }
            });
        }
        
        // District change -> load cities and villages
        if (this.districtSelect) {
            this.districtSelect.addEventListener('change', () => {
                const districtId = this.districtSelect.value;
                if (districtId) {
                    this.loadCities(districtId);
                    this.loadVillages(districtId);
                    this.selectedRegions.district = {
                        id: districtId,
                        name: this.getSelectedOptionText(this.districtSelect)
                    };
                    this.resetSelects('city');
                    this.updateAddress();
                }
            });
        }
        
        // City change -> load zones
        if (this.citySelect) {
            this.citySelect.addEventListener('change', () => {
                const cityId = this.citySelect.value;
                if (cityId) {
                    this.loadZones(cityId, 'city');
                    this.selectedRegions.city = {
                        id: cityId,
                        name: this.getSelectedOptionText(this.citySelect)
                    };
                    this.resetSelects('zone');
                    this.selectedRegions.village = null;
                    this.updateAddress();
                }
            });
        }
        
        // Village change -> load zones
        if (this.villageSelect) {
            this.villageSelect.addEventListener('change', () => {
                const villageId = this.villageSelect.value;
                if (villageId) {
                    this.loadZones(villageId, 'village');
                    this.selectedRegions.village = {
                        id: villageId,
                        name: this.getSelectedOptionText(this.villageSelect)
                    };
                    this.resetSelects('zone');
                    this.selectedRegions.city = null;
                    this.updateAddress();
                }
            });
        }
        
        // Zone change
        if (this.zoneSelect) {
            this.zoneSelect.addEventListener('change', () => {
                const zoneId = this.zoneSelect.value;
                if (zoneId) {
                    this.selectedRegions.zone = {
                        id: zoneId,
                        name: this.getSelectedOptionText(this.zoneSelect)
                    };
                    this.updateAddress();
                }
            });
        }
    }
    
    getSelectedOptionText(selectElement) {
        if (!selectElement || !selectElement.options || !selectElement.options[selectElement.selectedIndex]) {
            return '';
        }
        return selectElement.options[selectElement.selectedIndex].text;
    }
    
    async loadProvinces(countryId) {
        try {
            const response = await fetch(`/admin/api/geography/provinces/${countryId}`);
            if (!response.ok) throw new Error('Failed to fetch provinces');
            const provinces = await response.json();
            this.populateSelect(this.provinceSelect, provinces);
        } catch (error) {
            console.error('Error loading provinces:', error);
        }
    }
    
    async loadCounties(provinceId) {
        try {
            const response = await fetch(`/admin/api/geography/counties/${provinceId}`);
            if (!response.ok) throw new Error('Failed to fetch counties');
            const counties = await response.json();
            this.populateSelect(this.countySelect, counties);
        } catch (error) {
            console.error('Error loading counties:', error);
        }
    }
    
    async loadDistricts(countyId) {
        try {
            const response = await fetch(`/admin/api/geography/districts/${countyId}`);
            if (!response.ok) throw new Error('Failed to fetch districts');
            const districts = await response.json();
            this.populateSelect(this.districtSelect, districts);
        } catch (error) {
            console.error('Error loading districts:', error);
        }
    }
    
    async loadCities(districtId) {
        try {
            const response = await fetch(`/admin/api/geography/cities/${districtId}`);
            if (!response.ok) throw new Error('Failed to fetch cities');
            const cities = await response.json();
            this.populateSelect(this.citySelect, cities);
        } catch (error) {
            console.error('Error loading cities:', error);
        }
    }
    
    async loadVillages(districtId) {
        try {
            const response = await fetch(`/admin/api/geography/villages/${districtId}`);
            if (!response.ok) throw new Error('Failed to fetch villages');
            const villages = await response.json();
            this.populateSelect(this.villageSelect, villages);
        } catch (error) {
            console.error('Error loading villages:', error);
        }
    }
    
    async loadZones(parentId, parentType) {
        try {
            const response = await fetch(`/admin/api/geography/zones/${parentType}/${parentId}`);
            if (!response.ok) throw new Error('Failed to fetch zones');
            const zones = await response.json();
            this.populateSelect(this.zoneSelect, zones);
        } catch (error) {
            console.error('Error loading zones:', error);
        }
    }
    
    populateSelect(selectElement, options) {
        if (!selectElement) return;
        
        // Save currently selected value if any
        const currentValue = selectElement.value;
        
        // Clear existing options
        selectElement.innerHTML = '<option value="">انتخاب کنید</option>';
        
        // Add new options
        options.forEach(option => {
            const optionElement = document.createElement('option');
            optionElement.value = option.id;
            optionElement.textContent = option.name;
            selectElement.appendChild(optionElement);
        });
        
        // Try to restore previously selected value
        if (currentValue) {
            selectElement.value = currentValue;
        }
        
        // Trigger change event to cascade updates
        if (selectElement.value) {
            selectElement.dispatchEvent(new Event('change'));
        }
    }
    
    resetSelects(startFrom) {
        const selects = {
            'province': [this.provinceSelect, this.countySelect, this.districtSelect, this.citySelect, this.villageSelect, this.zoneSelect],
            'county': [this.countySelect, this.districtSelect, this.citySelect, this.villageSelect, this.zoneSelect],
            'district': [this.districtSelect, this.citySelect, this.villageSelect, this.zoneSelect],
            'city': [this.citySelect, this.zoneSelect],
            'village': [this.villageSelect, this.zoneSelect],
            'zone': [this.zoneSelect]
        };
        
        if (!selects[startFrom]) return;
        
        // Reset all selects starting from the specified level
        selects[startFrom].forEach(select => {
            if (select) {
                select.innerHTML = '<option value="">انتخاب کنید</option>';
            }
        });
        
        // Also reset the selected regions data
        const regions = ['country', 'province', 'county', 'district', 'city', 'village', 'zone'];
        const startIndex = regions.indexOf(startFrom);
        if (startIndex >= 0) {
            for (let i = startIndex; i < regions.length; i++) {
                this.selectedRegions[regions[i]] = null;
            }
        }
    }
    
    updateAddress() {
        if (!this.addressField) return;
        // Only update if the address field is empty or the user has allowed auto-updates
        if (!this.addressField.value || this.addressField.getAttribute('data-auto-update') === 'true') {
            // Build the address from the selected regions
            const addressParts = [];
            // Add regions in reverse order (from specific to general)
            const regions = ['zone', 'village', 'city', 'district', 'county', 'province', 'country'];
            const lang = document.documentElement.lang || 'fa';
            for (const region of regions) {
                if (this.selectedRegions[region]) {
                    if (lang === 'en' && this.selectedRegions[region].name_en) {
                        addressParts.unshift(this.selectedRegions[region].name_en);
                    } else if (this.selectedRegions[region].name) {
                        addressParts.unshift(this.selectedRegions[region].name);
                    }
                }
            }
            // Update the address field
            if (addressParts.length > 0) {
                this.addressField.value = addressParts.join(lang === 'en' ? ', ' : '، ');
                this.addressField.setAttribute('data-auto-update', 'true');
            }
        }
    }
}

// Map Location Selector with multiple layers
class MapSelector {
    constructor(options = {}) {
        this.mapContainer = document.getElementById(options.mapContainerId || 'location-map');
        this.latInput = document.getElementById(options.latInputId || 'lat');
        this.lngInput = document.getElementById(options.lngInputId || 'lng');
        this.addressField = document.getElementById(options.addressFieldId || 'address');
        this.geoSelector = options.geoSelector || null;
        
        this.map = null;
        this.marker = null;
        this.layers = {};
        
        if (this.mapContainer) {
            this.initMap();
        }
    }
    
    initMap() {
        // Check if Leaflet is available
        if (typeof L === 'undefined') {
            console.error('Leaflet library not loaded');
            return;
        }
        
        // Initialize the map
        this.map = L.map(this.mapContainer).setView([32.4279, 53.6880], 5); // Default view of Iran
        
        // Add base layers
        this.layers.osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(this.map);
        
        this.layers.satellite = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
            attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
        });
        
        // Add a marker if coordinates are already set
        if (this.latInput && this.lngInput && this.latInput.value && this.lngInput.value) {
            const lat = parseFloat(this.latInput.value);
            const lng = parseFloat(this.lngInput.value);
            if (!isNaN(lat) && !isNaN(lng)) {
                this.setMarker(lat, lng);
                this.map.setView([lat, lng], 15);
            }
        }
        
        // Add layer control
        L.control.layers({
            'نقشه استاندارد': this.layers.osm,
            'تصویر ماهواره‌ای': this.layers.satellite
        }).addTo(this.map);
        
        // Add click event to set marker
        this.map.on('click', e => {
            this.setMarker(e.latlng.lat, e.latlng.lng);
            
            // Update input fields
            if (this.latInput) this.latInput.value = e.latlng.lat.toFixed(7);
            if (this.lngInput) this.lngInput.value = e.latlng.lng.toFixed(7);
            
            // Reverse geocode to get address
            this.reverseGeocode(e.latlng.lat, e.latlng.lng);
        });
    }
    
    setMarker(lat, lng) {
        // Remove existing marker if any
        if (this.marker) {
            this.map.removeLayer(this.marker);
        }
        
        // Add new marker
        this.marker = L.marker([lat, lng], {
            draggable: true
        }).addTo(this.map);
        
        // Handle marker drag events
        this.marker.on('dragend', e => {
            const latlng = e.target.getLatLng();
            if (this.latInput) this.latInput.value = latlng.lat.toFixed(7);
            if (this.lngInput) this.lngInput.value = latlng.lng.toFixed(7);
            
            // Reverse geocode to get address
            this.reverseGeocode(latlng.lat, latlng.lng);
        });
    }
    
    async reverseGeocode(lat, lng) {
        try {
            // Use Nominatim or your custom geocoding service
            const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}&zoom=18&addressdetails=1`);
            if (!response.ok) throw new Error('Failed to geocode location');
            
            const data = await response.json();
            
            // Update address field if available
            if (this.addressField && data.display_name) {
                this.addressField.value = data.display_name;
                this.addressField.setAttribute('data-auto-update', 'true');
            }
            
            // If we have a geo selector, try to update selections based on reverse geocode data
            if (this.geoSelector && data.address) {
                this.updateGeoSelectorFromAddress(data.address);
            }
            
        } catch (error) {
            console.error('Error during reverse geocoding:', error);
        }
    }
    
    updateGeoSelectorFromAddress(addressData) {
        // Implementation depends on your geocoding service's response format
        // This is a simplified example that would need to be adapted
        
        // Map address components to geographical hierarchy
        // You would need to implement the actual logic based on your data
        console.log('Address data for geo selection:', addressData);
    }
}

// Initialize components when the DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    console.log('Initializing hierarchical selects...');
    
    // Initialize time inputs
    const openHoursInput = document.getElementById('open_hours');
    const closingHoursInput = document.getElementById('closing_hours');
    
    if (openHoursInput) {
        openHoursInput.type = 'time';
    }
    
    if (closingHoursInput) {
        closingHoursInput.type = 'time';
    }
    
    // Check if we're on a page that needs the category selector
    const hasMainCategorySelect = document.getElementById('main_category_id') || 
                                 document.getElementById('parent_category_id');
    const hasSubCategorySelect = document.getElementById('sub_category_id');
    
    // Only initialize category selector if at least one of the required elements exists
    if (hasMainCategorySelect || hasSubCategorySelect) {
        console.log('Initializing category selector...');
        const categorySelector = new CategorySelector();
        window.categorySelector = categorySelector;
    } else {
        console.log('Skipping category selector initialization - no category elements found');
    }
    
    // Initialize geographical selector
    const geoSelector = new GeoSelector();
    
    // Initialize map selector
    const mapSelector = new MapSelector({
        geoSelector: geoSelector
    });
    
    // Make the instances globally available if needed
    window.geoSelector = geoSelector;
    window.mapSelector = mapSelector;
}); 