/**
 * Boundary Manager for Geographic Regions
 * Handles displaying boundaries on Leaflet maps
 */
class BoundaryManager {
    constructor(map) {
        this.map = map;
        this.boundaryLayer = null;
        this.currentRegion = {
            type: null,
            id: null
        };
    }

    /**
     * Display boundary for a specific region
     * @param {string} regionType - Type of region (country, province, county, etc.)
     * @param {number} regionId - ID of the region
     */
    async displayBoundary(regionType, regionId) {
        try {
            console.log(`[BoundaryManager] Fetching boundary for ${regionType} ID: ${regionId}`);

            // Clear any existing boundary
            this.clearBoundary();

            // Choose the appropriate API endpoint based on region type
            let apiUrl;
            if (regionType === 'country') {
                apiUrl = `/api/countries/${regionId}/boundaries`;
            } else {
                apiUrl = `/api/boundaries/${regionType}/${regionId}`;
            }

            console.log(`[BoundaryManager] Using API URL: ${apiUrl}`);

            // Fetch boundary data from API
            const response = await fetch(apiUrl);

            console.log(`[BoundaryManager] API response status: ${response.status}`);

            if (!response.ok) {
                if (response.status === 404) {
                    console.info(`[BoundaryManager] No boundary data available for ${regionType} ID: ${regionId}`);
                    return false;
                }
                const errorText = await response.text();
                console.error(`[BoundaryManager] API Error: ${response.status} ${response.statusText}`, errorText);
                throw new Error(`Failed to fetch boundary data: ${response.status} ${response.statusText}`);
            }

            const data = await response.json();
            console.log('[BoundaryManager] Boundary data received:', data);

            if (!data.boundaries) {
                console.warn(`[BoundaryManager] No boundary data available for ${regionType} ID: ${regionId}`);
                return false;
            }

            // Parse and display the boundary
            const success = this.parseBoundaryData(data.boundaries);

            if (success) {
                // Update current region info
                this.currentRegion = {
                    type: regionType,
                    id: regionId
                };
                console.log(`[BoundaryManager] Successfully displayed boundary for ${regionType} ID: ${regionId}`);
            }

            return success;

        } catch (error) {
            console.error('[BoundaryManager] Error displaying boundary:', error);
            return false;
        }
    }

    /**
     * Parse boundary data and add to map
     * @param {Object|string} boundaryData - The boundary data to parse
     */
    parseBoundaryData(boundaryData) {
        try {
            let geoJSON;

            // If boundaries is already a GeoJSON object, use it directly
            if (typeof boundaryData === 'object') {
                geoJSON = boundaryData;
            } else if (typeof boundaryData === 'string') {
                // Try to parse it from a string
                geoJSON = JSON.parse(boundaryData);
            } else {
                console.error('Invalid boundary data format');
                return false;
            }

            console.log('Parsed GeoJSON:', geoJSON);

            // Validate GeoJSON structure
            if (!this.isValidGeoJSON(geoJSON)) {
                console.error('Invalid GeoJSON structure');
                return false;
            }

            // Create a GeoJSON layer with the boundary data
            this.boundaryLayer = L.geoJSON(geoJSON, {
                style: {
                    color: '#ff0000',     // Red border
                    weight: 2,            // Border width
                    opacity: 0.8,         // Opacity of border
                    fillColor: '#ff0000', // Fill color
                    fillOpacity: 0.1      // Fill opacity
                }
            }).addTo(this.map);

            console.log('Boundary layer added to map');

            // Fit the map to the boundary bounds
            if (this.boundaryLayer.getBounds && this.boundaryLayer.getBounds().isValid()) {
                this.map.fitBounds(this.boundaryLayer.getBounds());
                console.log('Map fitted to boundary bounds');
            } else {
                console.warn('Invalid boundary bounds, cannot fit map');
            }

            return true;

        } catch (error) {
            console.error('Failed to parse boundary data:', error);
            return false;
        }
    }

    /**
     * Validate GeoJSON structure
     * @param {Object} geoJSON - The GeoJSON object to validate
     */
    isValidGeoJSON(geoJSON) {
        if (!geoJSON || typeof geoJSON !== 'object') {
            return false;
        }

        // Check if it's a valid GeoJSON type
        const validTypes = ['Feature', 'FeatureCollection', 'Polygon', 'MultiPolygon', 'Point', 'MultiPoint', 'LineString', 'MultiLineString'];

        if (!geoJSON.type || !validTypes.includes(geoJSON.type)) {
            return false;
        }

        // Basic structure validation
        if (geoJSON.type === 'Feature') {
            return geoJSON.geometry && geoJSON.geometry.type && geoJSON.geometry.coordinates;
        } else if (geoJSON.type === 'FeatureCollection') {
            return Array.isArray(geoJSON.features);
        } else {
            // It's a geometry object
            return geoJSON.coordinates && Array.isArray(geoJSON.coordinates);
        }
    }

    /**
     * Clear the current boundary from the map
     */
    clearBoundary() {
        if (this.boundaryLayer) {
            this.map.removeLayer(this.boundaryLayer);
            this.boundaryLayer = null;
            console.log('[BoundaryManager] Boundary layer cleared');
        }

        // Reset current region
        this.currentRegion = {
            type: null,
            id: null
        };
    }

    /**
     * Get current region information
     */
    getCurrentRegion() {
        return this.currentRegion;
    }

    /**
     * Check if a boundary is currently displayed
     */
    hasBoundary() {
        return this.boundaryLayer !== null;
    }
}

// Export for use in other scripts
if (typeof module !== 'undefined' && module.exports) {
    module.exports = BoundaryManager;
} else {
    window.BoundaryManager = BoundaryManager;
}
