import { map } from './map-manager.js';
import { showStatus } from './utils.js';
import { openAddModal } from './location-manager.js';

let edmontonParcelsLayer = null;
let isLoading = false;
let isLayerVisible = false;
let lastBounds = null;
let lastZoom = null;

/**
 * Toggles the visibility of the Edmonton Parcel Addresses layer.
 * Uses smart loading based on map bounds and zoom level.
 */
export async function toggleEdmontonParcelsLayer() {
    const toggleBtn = document.getElementById('toggle-edmonton-layer-btn');
    const mobileToggleBtn = document.getElementById('mobile-toggle-edmonton-layer-btn');

    if (isLoading) {
        console.log('Edmonton layer is already loading...');
        return;
    }

    if (isLayerVisible) {
        // Hide the layer
        if (edmontonParcelsLayer && map.hasLayer(edmontonParcelsLayer)) {
            map.removeLayer(edmontonParcelsLayer);
        }
        isLayerVisible = false;
        toggleBtn?.classList.remove('active');
        mobileToggleBtn?.classList.remove('active');
        console.log('Edmonton addresses layer hidden');
        
        // Remove map event listeners
        map.off('moveend', onMapMoveEnd);
        map.off('zoomend', onMapZoomEnd);
    } else {
        // Show the layer
        isLayerVisible = true;
        toggleBtn?.classList.add('active');
        mobileToggleBtn?.classList.add('active');
        console.log('Edmonton addresses layer enabled');
        
        // Add map event listeners for dynamic loading
        map.on('moveend', onMapMoveEnd);
        map.on('zoomend', onMapZoomEnd);
        
        // Load data for current view
        await loadEdmontonData();
    }
}

/**
 * Loads Edmonton data for the current map bounds and zoom level
 */
async function loadEdmontonData(force = false) {
    if (!isLayerVisible || isLoading) return;
    
    const currentBounds = map.getBounds();
    const currentZoom = map.getZoom();
    
    // Check if we need to reload data
    if (!force && lastBounds && lastZoom === currentZoom && 
        lastBounds.contains(currentBounds)) {
        return; // Current view is already covered
    }
    
    // Only load data if zoomed in enough (reduces server load)
    if (currentZoom < 11) {
        if (edmontonParcelsLayer && map.hasLayer(edmontonParcelsLayer)) {
            map.removeLayer(edmontonParcelsLayer);
        }
        console.log('Zoom level too low for Edmonton data, zoom in to see addresses');
        return;
    }
    
    isLoading = true;
    const toggleBtn = document.getElementById('toggle-edmonton-layer-btn');
    const mobileToggleBtn = document.getElementById('mobile-toggle-edmonton-layer-btn');
    
    if (toggleBtn) toggleBtn.disabled = true;
    if (mobileToggleBtn) mobileToggleBtn.disabled = true;
    
    try {
        // Expand bounds slightly to avoid edge loading issues
        const expandedBounds = currentBounds.pad(0.1);
        const boundsString = [
            expandedBounds.getSouth(),
            expandedBounds.getWest(), 
            expandedBounds.getNorth(),
            expandedBounds.getEast()
        ].join(',');
        
        const params = new URLSearchParams({
            bounds: boundsString,
            zoom: currentZoom.toString(),
            limit: currentZoom > 15 ? '2000' : currentZoom > 12 ? '1000' : '500'
        });
        
        console.log(`Loading Edmonton addresses for zoom level ${currentZoom}, bounds: ${boundsString}`);
        
        const response = await fetch(`/api/external/edmonton-parcels?${params}`);
        if (!response.ok) {
            throw new Error('Failed to fetch layer data from server.');
        }
        const result = await response.json();

        if (result.success) {
            // Remove existing layer
            if (edmontonParcelsLayer && map.hasLayer(edmontonParcelsLayer)) {
                map.removeLayer(edmontonParcelsLayer);
            }
            
            // Create new layer with clustering optimized for the zoom level
            const clusterRadius = currentZoom > 15 ? 30 : currentZoom > 12 ? 50 : 80;
            edmontonParcelsLayer = L.markerClusterGroup({
                chunkedLoading: true,
                maxClusterRadius: clusterRadius,
                disableClusteringAtZoom: 18,
                showCoverageOnHover: false,
                zoomToBoundsOnClick: true,
                spiderfyOnMaxZoom: true,
                removeOutsideVisibleBounds: true
            });

            const geoJsonLayer = L.geoJSON(result.data, {
                pointToLayer: (feature, latlng) => {
                    const isMultiUnit = feature.properties.isMultiUnit;
                    
                    if (isMultiUnit) {
                        // Use a custom HTML marker for multi-unit buildings (square)
                        const size = Math.max(12, Math.min(24, (currentZoom - 10) * 2));
                        const icon = L.divIcon({
                            className: 'multi-unit-marker',
                            html: `<div class="apartment-marker" style="
                                width: ${size}px; 
                                height: ${size}px; 
                                background-color: #ff6b35; 
                                border: 2px solid #ffffff;
                                border-radius: 0;
                                box-shadow: 0 2px 5px rgba(0,0,0,0.3);
                            "></div>`,
                            iconSize: [size, size],
                            iconAnchor: [size/2, size/2],
                            popupAnchor: [0, -size/2]
                        });
                        return L.marker(latlng, { icon: icon });
                    } else {
                        // Use circle marker for single units (round, red)
                        return L.circleMarker(latlng, {
                            radius: Math.max(3, Math.min(6, currentZoom - 10)),
                            fillColor: "#ba001e",
                            color: "#ffffff",
                            weight: 1,
                            opacity: 0.9,
                            fillOpacity: 0.7
                        });
                    }
                },
                onEachFeature: (feature, layer) => {
                    const props = feature.properties;
                    
                    if (props.isMultiUnit) {
                        // Create apartment-style popup for multi-unit buildings
                        const popup = L.popup({
                            maxWidth: 320,
                            minWidth: 280,
                            closeButton: true,
                            className: 'apartment-popup'
                        }).setContent(createApartmentPopup(props));
                        
                        layer.bindPopup(popup);
                        
                        // Add event listener for when popup opens
                        layer.on('popupopen', function(e) {
                            setupApartmentPopupListeners(props);
                        });
                    } else {
                        // Simple popup for single units
                        const suite = props.suites && props.suites[0] ? props.suites[0] : {};
                        
                        // Better suite/unit display logic
                        let suiteDisplay = '';
                        if (suite.suite && suite.suite.trim()) {
                            const unitLabel = (suite.object_type && suite.object_type.toLowerCase().includes('suite')) ? 'Suite' : 'Unit';
                            suiteDisplay = `<span style="color: #666;">${unitLabel}: ${suite.suite.trim()}</span><br>`;
                        }
                        
                        const popupContent = `
                            <div style="font-size: 12px; line-height: 1.4; min-width: 160px;">
                                <b>🏠 ${props.address}</b><br>
                                ${suiteDisplay}
                                ${props.neighborhood ? `<span style="color: #666;">📍 ${props.neighborhood}</span><br>` : ''}
                                ${suite.object_type ? `<span style="color: #888; font-size: 11px;">${suite.object_type}</span><br>` : ''}
                                <small style="color: #888;">City of Edmonton Data</small>
                                <div style="margin-top: 8px; padding-top: 8px; border-top: 1px solid #e9ecef;">
                                    <button class="add-to-database-btn" 
                                            data-address="${props.address}" 
                                            data-lat="${props.lat}" 
                                            data-lng="${props.lng}"
                                            data-neighborhood="${props.neighborhood || ''}"
                                            data-suite="${suite.suite || ''}"
                                            data-object-type="${suite.object_type || ''}"
                                            style="background: #28a745; color: white; border: none; padding: 4px 8px; border-radius: 3px; font-size: 11px; cursor: pointer; width: 100%;">
                                        ➕ Add to Database
                                    </button>
                                </div>
                            </div>
                        `;
                        layer.bindPopup(popupContent, {
                            maxWidth: 200,
                            closeButton: true
                        });
                        
                        // Add event listener for popup open to attach button listeners
                        layer.on('popupopen', function(e) {
                            setupSingleUnitPopupListeners();
                        });
                    }
                }
            });

            edmontonParcelsLayer.addLayer(geoJsonLayer);
            map.addLayer(edmontonParcelsLayer);
            
            // Update tracking variables
            lastBounds = expandedBounds;
            lastZoom = currentZoom;
            
            const statusMessage = result.data.metadata?.hasMore 
                ? `Loaded ${result.data.features.length} addresses (more available at higher zoom)`
                : `Loaded ${result.data.features.length} Edmonton addresses`;
            console.log(statusMessage);
        } else {
            throw new Error(result.error || 'Could not load layer data.');
        }
    } catch (error) {
        console.error('Error loading Edmonton parcels layer:', error);
        // Only show error status, not success messages
        showStatus(error.message, 'error');
    } finally {
        isLoading = false;
        if (toggleBtn) toggleBtn.disabled = false;
        if (mobileToggleBtn) mobileToggleBtn.disabled = false;
    }
}

/**
 * Handle map move events
 */
function onMapMoveEnd() {
    // Debounce the loading to avoid too many requests
    clearTimeout(onMapMoveEnd.timeout);
    onMapMoveEnd.timeout = setTimeout(() => {
        loadEdmontonData();
    }, 500);
}

/**
 * Handle map zoom events  
 */
function onMapZoomEnd() {
    // Force reload on zoom change
    loadEdmontonData(true);
}

/**
 * Creates an apartment-style popup for multi-unit buildings
 */
function createApartmentPopup(props) {
    const suites = props.suites || [];
    const totalSuites = suites.length;
    
    const popupId = `apartment-popup-${Math.random().toString(36).substr(2, 9)}`;
    
    // Truncate address if too long for mobile
    const displayAddress = props.address.length > 30 ? 
        props.address.substring(0, 30) + '...' : props.address;
    
    const popupContent = `
        <div class="apartment-building-popup" data-popup-id="${popupId}" style="font-family: Arial, sans-serif;">
            <div class="building-header">
                <div style="display: flex; align-items: center; justify-content: space-between; gap: 8px;">
                    <div style="flex: 1; min-width: 0;">
                        <div style="font-weight: bold; font-size: 15px; margin-bottom: 2px; line-height: 1.3;" title="${props.address}">🏢 ${displayAddress}</div>
                        <div style="font-size: 12px; opacity: 0.9; line-height: 1.2;">${totalSuites} units • ${props.neighborhood || 'Edmonton'}</div>
                    </div>
                    <div style="background: rgba(255,255,255,0.25); padding: 4px 8px; border-radius: 10px; font-size: 10px; font-weight: 500; white-space: nowrap;">
                        Apt
                    </div>
                </div>
            </div>
            
            <div class="suite-navigator" style="margin-bottom: 12px;">
                <div style="margin-bottom: 6px;">
                    <label style="font-size: 11px; color: #666; display: block; margin-bottom: 3px;">
                        Suite (${totalSuites} total):
                    </label>
                    <select class="suite-selector" style="width: 100%; padding: 6px; border: 1px solid #ddd; border-radius: 4px; font-size: 11px; background: white; cursor: pointer;">
                        ${suites
                            .map((suite, originalIndex) => ({ ...suite, originalIndex }))
                            .sort((a, b) => {
                                // Extract numeric part for sorting
                                const aNum = a.suite ? parseInt(a.suite.replace(/\D/g, '')) || 0 : a.originalIndex;
                                const bNum = b.suite ? parseInt(b.suite.replace(/\D/g, '')) || 0 : b.originalIndex;
                                return aNum - bNum;
                            })
                            .map((suite) => {
                                const displayName = suite.suite ? suite.suite.trim() : `Unit ${suite.originalIndex + 1}`;
                                const objectType = suite.object_type || 'Residential';
                                // Truncate option text for mobile
                                const optionText = `${displayName} (${objectType})`;
                                const truncatedText = optionText.length > 25 ? 
                                    optionText.substring(0, 25) + '...' : optionText;
                                return `<option value="${suite.originalIndex}" title="${optionText}">${truncatedText}</option>`;
                            }).join('')}
                    </select>
                </div>
                
                <div class="suite-content" style="min-height: 70px; padding: 8px; background: #f8f9fa; border-radius: 4px; border-left: 3px solid #ff6b35;">
                    <div class="suite-details">
                        <div style="font-weight: bold; font-size: 13px; color: #333; margin-bottom: 3px;">
                            ${suites[0].suite ? `Suite ${suites[0].suite.trim()}` : `Unit 1`}
                        </div>
                        <div style="font-size: 11px; color: #666; margin-bottom: 4px;">
                            ${suites[0].object_type || 'Residential Unit'}
                        </div>
                        ${suites[0].house_number && suites[0].street_name ? `
                            <div style="font-size: 10px; color: #888; margin-bottom: 3px;">
                                📍 ${suites[0].house_number} ${suites[0].street_name}
                            </div>` : ''}
                        ${suites[0].record_id ? `
                            <div style="font-size: 9px; color: #888;">
                                ID: ${suites[0].record_id}
                            </div>` : ''}
                    </div>
                </div>
            </div>
            
            <div style="text-align: center; font-size: 9px; color: #888; border-top: 1px solid #e9ecef; padding-top: 6px; margin-top: 10px;">
                City of Edmonton Open Data
            </div>
            
            <div style="margin-top: 6px; padding-top: 6px; border-top: 1px solid #e9ecef;">
                <button class="add-apartment-to-database-btn" 
                        data-address="${props.address}" 
                        data-lat="${props.lat}" 
                        data-lng="${props.lng}"
                        data-neighborhood="${props.neighborhood || ''}"
                        data-suites='${JSON.stringify(suites)}'
                        style="background: #28a745; color: white; border: none; padding: 6px 10px; border-radius: 4px; font-size: 10px; cursor: pointer; width: 100%; font-weight: 500;">
                    ➕ Add Building to Database
                </button>
            </div>
        </div>
    `;
    
    return popupContent;
}

/**
 * Sets up event listeners for apartment popup suite selection
 */
function setupApartmentPopupListeners(props) {
    const suites = props.suites || [];
    
    // Find the popup container in the DOM
    const container = document.querySelector('.apartment-building-popup');
    if (!container) {
        console.log('Apartment popup container not found');
        return;
    }
    
    const suiteSelector = container.querySelector('.suite-selector');
    const suiteDetails = container.querySelector('.suite-details');
    
    if (!suiteSelector || !suiteDetails) {
        console.log('Apartment popup elements not found');
        return;
    }
    
    function updateSuiteDisplay(selectedIndex) {
        const suite = suites[selectedIndex];
        
        // Better logic for displaying unit/suite information
        let unitLabel = 'Unit';
        let unitNumber = suite.suite ? suite.suite.trim() : '';
        
        // If no suite number but has object type that suggests it's a suite
        if (!unitNumber && suite.object_type && suite.object_type.toLowerCase().includes('suite')) {
            unitNumber = `${selectedIndex + 1}`;
        }
        
        // If still no unit number, use sequential numbering
        if (!unitNumber) {
            unitNumber = `${selectedIndex + 1}`;
        }
        
        // Determine if it's a suite or unit based on the data
        if (suite.object_type && suite.object_type.toLowerCase().includes('suite')) {
            unitLabel = 'Suite';
        }
        
        suiteDetails.innerHTML = `
            <div style="font-weight: bold; font-size: 14px; color: #333; margin-bottom: 4px;">
                ${unitLabel} ${unitNumber}
            </div>
            <div style="font-size: 12px; color: #666; margin-bottom: 6px;">
                ${suite.object_type || 'Residential Unit'}
            </div>
            ${suite.house_number && suite.street_name ? `
                <div style="font-size: 11px; color: #888; margin-bottom: 4px;">
                    📍 ${suite.house_number} ${suite.street_name}
                </div>` : ''}
            ${suite.record_id ? `
                <div style="font-size: 10px; color: #888;">
                    ID: ${suite.record_id}
                </div>` : ''}
        `;
    }
    
    // Set up suite selector dropdown event listener
    suiteSelector.addEventListener('change', (e) => {
        e.stopPropagation();
        const selectedIndex = parseInt(e.target.value);
        console.log('Suite selected:', selectedIndex);
        updateSuiteDisplay(selectedIndex);
    });
    
    // Initialize with first suite selected
    updateSuiteDisplay(0);
    
    console.log(`Apartment popup suite selector set up for ${suites.length} suites`);
    
    // Set up the "Add to Database" button listener for apartments
    const addBtn = container.querySelector('.add-apartment-to-database-btn');
    if (addBtn) {
        addBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            const address = addBtn.getAttribute('data-address');
            const lat = parseFloat(addBtn.getAttribute('data-lat'));
            const lng = parseFloat(addBtn.getAttribute('data-lng'));
            const neighborhood = addBtn.getAttribute('data-neighborhood');
            const suitesData = JSON.parse(addBtn.getAttribute('data-suites') || '[]');
            
            // Get the currently selected suite from dropdown
            const selectedSuiteIndex = parseInt(suiteSelector.value);
            const selectedSuite = suitesData[selectedSuiteIndex] || suitesData[0];
            
            // Close the popup first
            map.closePopup();
            
            // Open the add modal but prevent the automatic address lookup
            openAddModal(lat, lng, false);
            
            // Pre-fill the form with Edmonton data, focusing on the selected suite
            setTimeout(() => {
                prefillAddForm({
                    address: address,
                    neighborhood: neighborhood,
                    lat: lat,
                    lng: lng,
                    suite: selectedSuite.suite || '',
                    objectType: selectedSuite.object_type || '',
                    notes: `Selected unit from multi-unit building (${suitesData.length} total units). Imported from City of Edmonton data.`,
                    isMultiUnit: true,
                    suites: suitesData,
                    selectedSuite: selectedSuite
                });
            }, 100);
        });
    }
}

/**
 * Sets up event listeners for single unit popup "Add to Database" button
 */
function setupSingleUnitPopupListeners() {
    // Wait for popup to be rendered in DOM
    setTimeout(() => {
        const addBtn = document.querySelector('.add-to-database-btn');
        if (addBtn) {
            addBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                const address = addBtn.getAttribute('data-address');
                const lat = parseFloat(addBtn.getAttribute('data-lat'));
                const lng = parseFloat(addBtn.getAttribute('data-lng'));
                const neighborhood = addBtn.getAttribute('data-neighborhood');
                const suite = addBtn.getAttribute('data-suite');
                const objectType = addBtn.getAttribute('data-object-type');
                
                // Close the popup first
                map.closePopup();
                
                // Open the add modal but prevent the automatic address lookup
                openAddModal(lat, lng, false);
                
                // Pre-fill the form with Edmonton data
                setTimeout(() => {
                    prefillAddForm({
                        address: address,
                        neighborhood: neighborhood,
                        lat: lat,
                        lng: lng,
                        suite: suite,
                        objectType: objectType,
                        notes: `Imported from City of Edmonton data.${objectType ? ` (${objectType})` : ''}`,
                        isMultiUnit: false
                    });
                }, 100);
            });
        }
    }, 50);
}

/**
 * Pre-fills the add location form with city data
 */
async function prefillAddForm(data) {
    try {
        // Import UI controls dynamically to avoid circular dependencies
        const { resetAddressConfirmation } = await import('./ui-controls.js');
        
        // First, reset any existing state
        resetAddressConfirmation('add');

        // Basic form fields
        if (data.address) {
            const addressField = document.getElementById('location-address');
            if (addressField) {
                addressField.value = data.address;
            }
        }
        
        // Put suite number in the unit field
        if (data.suite && data.suite.trim()) {
            const unitField = document.getElementById('location-unit');
            if (unitField) {
                unitField.value = data.suite.trim();
            }
        }
        
        // Notes field with additional context
        const notesField = document.getElementById('location-notes');
        if (notesField) {
            let notes = data.notes || '';
            
            // Add neighborhood information if available
            if (data.neighborhood && data.neighborhood.trim()) {
                notes += `\nNeighborhood: ${data.neighborhood}`;
            }
            
            // Add object type if available
            if (data.objectType && data.objectType.trim()) {
                notes += `\nUnit Type: ${data.objectType}`;
            }
            
            // For multi-unit buildings, add information about the selected suite
            if (data.isMultiUnit && data.selectedSuite) {
                notes += `\nSelected Suite: ${data.selectedSuite.suite || 'N/A'}`;
                notes += `\nSuite Type: ${data.selectedSuite.object_type || 'N/A'}`;
            }
            // For single units, add basic suite information
            else if (data.suite && data.suite.trim()) {
                notes += `\nSuite: ${data.suite}`;
            }
            
            notesField.value = notes.trim();
        }
        
        // Set coordinates (already set by openAddModal, but ensure they're correct)
        const latField = document.getElementById('location-lat');
        const lngField = document.getElementById('location-lng');
        const geoField = document.getElementById('geo-location');
        
        if (latField && data.lat) {
            latField.value = data.lat.toFixed(8);
        }
        if (lngField && data.lng) {
            lngField.value = data.lng.toFixed(8);
        }
        if (geoField && data.lat && data.lng) {
            geoField.value = `${data.lat.toFixed(8)};${data.lng.toFixed(8)}`;
        }
        
        // Mark the address as confirmed since it's coming from a trusted source
        const { setAddressConfirmed } = await import('./ui-controls.js');
        setAddressConfirmed('add', true);
        
        console.log('Form pre-filled and confirmed with city data:', data);
        
    } catch (error) {
        console.error('Error pre-filling form:', error);
        showStatus('Error pre-filling form with city data', 'error');
    }
}
