import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

let scene, camera, renderer, map, controls;
const countries = [];
const highlightedCountries = [];
let allCountries = []; // 存储所有国家名称
let worldData; // 存储世界地理数据
let worldDataLoaded = false; // 标记世界数据是否已加载
let highlightColor = 0xFFFF00; // 默认高亮颜色
let currentMapType = 'standard';
const mapTextures = {
  standard: '/static/images/eo_base_2020_clean_3600x1800.png',
  night: '/static/images/BlackMarble_2016_01deg.jpg',
  gray: '/static/images/world.oceanmask.5400x2700.png',
  satellite: '/static/images/world.topo.bathy.200412.3x5400x2700.jpg'
};

export { init, addCountry, removeCountry, exportMap, shareMap };

function init() {
    if (scene) {
        console.log('Scene already initialized');
        return;
    }

    scene = new THREE.Scene();
    const aspect = window.innerWidth / window.innerHeight;
    const frustumSize = 180;
    camera = new THREE.OrthographicCamera(
        frustumSize * aspect / -2, frustumSize * aspect / 2,
        frustumSize / 2, frustumSize / -2,
        0.1, 1000
    );
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.getElementById('map').appendChild(renderer.domElement);

    const mapTexture = new THREE.TextureLoader().load(mapTextures[currentMapType]);
    const material = new THREE.MeshBasicMaterial({ map: mapTexture });
    map = new THREE.Mesh(new THREE.PlaneGeometry(360, 180), material);
    scene.add(map);

    camera.position.z = 100;

    setupControls();
    setupColorPicker();
    loadHighlightColor();
    loadSavedMapType();

    loadWorldData();
    animate();
    loadCountries();
    loadAllCountries();
    setupAutocomplete();

    window.addEventListener('resize', onWindowResize, false);

    // Move the event listeners setup to a separate function
    setupEventListeners();

    // Update renderer size
    updateRendererSize();
}

function setupControls() {
    controls = new OrbitControls(camera, renderer.domElement);
    controls.enableRotate = false;
    controls.enablePan = true;
    controls.enableZoom = true;
    controls.panSpeed = 0.5;
    controls.zoomSpeed = 0.5;
    controls.screenSpacePanning = true;
    controls.mouseButtons = {
        LEFT: THREE.MOUSE.PAN,
        MIDDLE: THREE.MOUSE.DOLLY,
        RIGHT: THREE.MOUSE.ROTATE
    };

    // Adjust these values as needed
    controls.minZoom = 0.5;
    controls.maxZoom = 2;
    controls.update();
}

function setupEventListeners() {
    const zoomInButton = document.getElementById('zoom-in');
    const zoomOutButton = document.getElementById('zoom-out');
    const sidebarToggle = document.querySelector('button[x-on\\:click]');

    if (zoomInButton) {
        zoomInButton.addEventListener('click', () => {
            zoomMap(0.9); // Zoom in
        });
    } else {
        console.error('Zoom in button not found');
    }

    if (zoomOutButton) {
        zoomOutButton.addEventListener('click', () => {
            zoomMap(1.1); // Zoom out
        });
    } else {
        console.error('Zoom out button not found');
    }

    if (sidebarToggle) {
        sidebarToggle.addEventListener('click', updateRendererSize);
    }

    setupMapSelection();
}

function onWindowResize() {
    const aspect = window.innerWidth / window.innerHeight;
    const frustumSize = 180;
    camera.left = -frustumSize * aspect / 2;
    camera.right = frustumSize * aspect / 2;
    camera.top = frustumSize / 2;
    camera.bottom = -frustumSize / 2;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
}

function loadWorldData() {
    fetch('https://raw.githubusercontent.com/datasets/geo-countries/master/data/countries.geojson')
        .then(response => response.json())
        .then(data => {
            worldData = data;
            console.log('Loaded country names:', data.features.map(f => ({
                ADMIN: f.properties.ADMIN,
                NAME: f.properties.NAME,
                SOVEREIGNT: f.properties.SOVEREIGNT
            })));
            drawCountryBorders();
            worldDataLoaded = true;
            updateHighlights();
            loadAllCountries();
            setupAutocomplete();
        });
}

function drawCountryBorders() {
    const material = new THREE.LineBasicMaterial({ color: 0x000000, transparent: true, opacity: 0.3 });
    worldData.features.forEach(feature => {
        if (feature.geometry.type === "Polygon") {
            drawPolygon(feature.geometry.coordinates[0], material);
        } else if (feature.geometry.type === "MultiPolygon") {
            feature.geometry.coordinates.forEach(polygon => {
                drawPolygon(polygon[0], material);
            });
        }
    });
}

function drawPolygon(coords, material) {
    const points = coords.map(coord => new THREE.Vector3(coord[0], coord[1], 0.1));
    const geometry = new THREE.BufferGeometry().setFromPoints(points);
    const line = new THREE.Line(geometry, material);
    scene.add(line);
}

function highlightCountry(countryName) {
    if (!worldDataLoaded) {
        console.log('World data not loaded yet. Skipping highlight for:', countryName);
        return;
    }
    const aliasName = getCountryAlias(countryName);
    const feature = worldData.features.find(f => {
        const admin = (f.properties.ADMIN || '').toLowerCase();
        const name = (f.properties.NAME || '').toLowerCase();
        const sovereignt = (f.properties.SOVEREIGNT || '').toLowerCase();
        const aliasLower = aliasName.toLowerCase();
        return admin === aliasLower || name === aliasLower || sovereignt === aliasLower ||
               admin.includes(aliasLower) || name.includes(aliasLower) || sovereignt.includes(aliasLower);
    });
    if (feature) {
        const material = new THREE.MeshBasicMaterial({
            color: highlightColor,
            transparent: true,
            opacity: 0.5,
            side: THREE.DoubleSide,
            depthWrite: false,
            depthTest: false
        });
        if (feature.geometry.type === "Polygon") {
            const mesh = createPolygonMesh(feature.geometry.coordinates[0], material);
            mesh.name = countryName;
            scene.add(mesh);
            highlightedCountries.push(mesh);
        } else if (feature.geometry.type === "MultiPolygon") {
            feature.geometry.coordinates.forEach(polygon => {
                const mesh = createPolygonMesh(polygon[0], material);
                mesh.name = countryName;
                scene.add(mesh);
                highlightedCountries.push(mesh);
            });
        }
    } else {
        console.log('Country not found in world data:', countryName, 'Alias:', aliasName);
    }
}

function createPolygonMesh(coords, material) {
    const shape = new THREE.Shape();
    coords.forEach((coord, index) => {
        if (index === 0) {
            shape.moveTo(coord[0], coord[1]);
        } else {
            shape.lineTo(coord[0], coord[1]);
        }
    });
    const geometry = new THREE.ShapeGeometry(shape);
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.z = 0.1;
    return mesh;
}

function addCountry() {
    const input = document.getElementById('new-country');
    const country = input.value.trim();
    if (country) {
        fetch('/add_country', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ country }),
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                loadCountries();
                input.value = '';
            } else {
                alert(data.message);
            }
        })
        .catch(error => {
            console.error('Error adding country:', error);
        });
    }
}

function removeCountry(country) {
    fetch('/remove_country', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ country }),
    })
    .then(() => {
        loadCountries();
    });
}

function loadCountries() {
    fetch('/countries')
        .then(response => response.json())
        .then(data => {
            countries.length = 0;
            countries.push(...data);
            updateCountryList();
            if (worldDataLoaded) {
                updateHighlights();
            }
        });
}

function updateCountryList() {
    const ul = document.getElementById('countries');
    ul.innerHTML = '';
    countries.forEach(country => {
        const li = document.createElement('li');
        li.className = 'flex justify-between items-center bg-gray-800 p-2 rounded';
        const span = document.createElement('span');
        span.textContent = country;
        span.className = 'text-gray-200';
        li.appendChild(span);
        const removeButton = document.createElement('button');
        removeButton.textContent = '删除';
        removeButton.className = 'bg-red-600 text-white px-2 py-1 rounded text-sm hover:bg-red-700 transition duration-200';
        removeButton.onclick = () => removeCountry(country);
        li.appendChild(removeButton);
        ul.appendChild(li);
    });
}

function animate() {
    requestAnimationFrame(animate);
    controls.update(); // 确保这行存在
    renderer.render(scene, camera);
}

function updateHighlights() {
    if (!worldDataLoaded) {
        console.log('World data not loaded yet. Skipping update highlights.');
        return;
    }
    // 清除之前的高亮
    highlightedCountries.forEach(mesh => {
        scene.remove(mesh);
    });
    highlightedCountries.length = 0;

    // 重新高亮所有国家
    countries.forEach(country => {
        highlightCountry(country);
    });
}

function getCountryAlias(countryName) {
    const aliases = {
        "United States": "United States of America",
        "USA": "United States of America",
        "US": "United States of America",
        "UK": "United Kingdom",
        "Britain": "United Kingdom",
        "Great Britain": "United Kingdom",
        "Russia": "Russian Federation",
        "China": "China",
        "People's Republic of China": "China",
        "Taiwan": "Taiwan",
        "North Korea": "Korea, Democratic People's Republic of",
        "South Korea": "Korea, Republic of",
        // 可以根据需要添加更多别名
    };
    return aliases[countryName] || countryName;
}

function loadAllCountries() {
    fetch('https://restcountries.com/v3.1/all')
        .then(response => response.json())
        .then(data => {
            allCountries = data.map(country => country.name.common).sort();
            updateCountrySuggestions(allCountries);
        })
        .catch(error => {
            console.error('Error loading all countries:', error);
        });
}

function updateCountrySuggestions(suggestions) {
    const datalist = document.getElementById('country-suggestions');
    datalist.innerHTML = '';
    suggestions.forEach(country => {
        const option = document.createElement('option');
        option.value = country;
        datalist.appendChild(option);
    });
}

function setupAutocomplete() {
    const input = document.getElementById('new-country');
    input.addEventListener('input', function() {
        const value = this.value.toLowerCase();
        const filteredCountries = allCountries.filter(country =>
            country.toLowerCase().startsWith(value)
        );
        updateCountrySuggestions(filteredCountries);
    });
}

function setupColorPicker() {
    const colors = [0xFFFF00, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF00FF, 0x00FFFF];
    const colorPicker = document.getElementById('color-picker');
    colors.forEach(color => {
        const colorBox = document.createElement('div');
        colorBox.className = 'w-8 h-8 rounded-full cursor-pointer border-2 border-gray-300 hover:border-gray-500 transition duration-200';
        colorBox.style.backgroundColor = '#' + color.toString(16).padStart(6, '0');
        colorBox.addEventListener('click', () => setHighlightColor(color));
        colorPicker.appendChild(colorBox);
    });
}

function setHighlightColor(color) {
    highlightColor = color;
    updateHighlights();
    saveHighlightColor(color);
}

function loadHighlightColor() {
    fetch('/get_highlight_color')
        .then(response => response.json())
        .then(data => {
            if (data.color) {
                highlightColor = parseInt(data.color, 16);
                updateHighlights();
            }
        });
}

function saveHighlightColor(color) {
    fetch('/save_highlight_color', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ color: color.toString(16) }),
    });
}

function exportMap() {
    // Create a new scene and camera for rendering the full map
    const exportScene = new THREE.Scene();
    const exportCamera = new THREE.OrthographicCamera(-180, 180, 90, -90, 0.1, 1000);
    exportCamera.position.z = 100;

    // Add the map and highlighted countries to the export scene
    const exportMap = new THREE.Mesh(
        new THREE.PlaneGeometry(360, 180),
        new THREE.MeshBasicMaterial({ map: map.material.map })
    );
    exportScene.add(exportMap);
    highlightedCountries.forEach(country => {
        exportScene.add(country.clone());
    });

    // Create a new renderer with a fixed size
    const exportRenderer = new THREE.WebGLRenderer({ antialias: true });
    exportRenderer.setSize(3600, 1800); // 10 times the original map size for better quality

    // Render the scene
    exportRenderer.render(exportScene, exportCamera);

    // Convert the rendered image to a data URL
    const dataURL = exportRenderer.domElement.toDataURL('image/png');

    // Create a temporary link element
    const link = document.createElement('a');
    link.href = dataURL;
    link.download = 'world_map.png';

    // Programmatically click the link to trigger the download
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);

    // After exporting, show share button
    showShareButton();
}

function showShareButton() {
    const shareButton = document.createElement('button');
    shareButton.textContent = '分享地图';
    shareButton.className = 'w-full bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 transition duration-200 mt-4';
    shareButton.onclick = shareMap;
    document.querySelector('#export-btn').insertAdjacentElement('afterend', shareButton);
}

function shareMap() {
    const mapData = {
        countries: countries,
        highlight_color: highlightColor.toString(16),
        map_type: currentMapType
    };

    fetch('/share_map', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(mapData),
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            const shareUrl = window.location.origin + data.share_url;
            alert(`您的地图已分享。分享链接：${shareUrl}`);
        } else {
            alert('分享失败，请重试。');
        }
    })
    .catch(error => {
        console.error('Error sharing map:', error);
        alert('分享失败，请重试。');
    });
}

function updateRendererSize() {
    const mapContainer = document.getElementById('map');
    const width = mapContainer.clientWidth;
    const height = mapContainer.clientHeight;

    camera.aspect = width / height;
    camera.updateProjectionMatrix();

    renderer.setSize(width, height);
}

function setupMapSelection() {
    const mapTypeSelector = document.getElementById('map-type-selector');
    if (mapTypeSelector) {
        // Load preview images for map type options
        Object.entries(mapTextures).forEach(([type, url]) => {
            const option = mapTypeSelector.querySelector(`[data-map-type="${type}"]`);
            if (option) {
                option.style.backgroundImage = `url(${url})`;
                option.style.backgroundSize = 'cover';
                option.style.backgroundPosition = 'center';
                option.addEventListener('click', () => changeMapType(type));

                // Set initial selected state
                if (type === currentMapType) {
                    option.classList.add('ring-2', 'ring-blue-500', 'border-blue-500');
                    option.classList.remove('border-gray-600');
                }
            }
        });
    } else {
        console.error('Map type selector element not found');
    }
}

function changeMapType(mapType) {
    if (mapType !== currentMapType) {
        currentMapType = mapType;
        const newTexture = new THREE.TextureLoader().load(mapTextures[mapType]);
        map.material.map = newTexture;
        map.material.needsUpdate = true;
        saveMapType(mapType);

        // Update selected state visually
        const mapTypeSelector = document.getElementById('map-type-selector');
        mapTypeSelector.querySelectorAll('.map-type-option').forEach(option => {
            if (option.dataset.mapType === mapType) {
                option.classList.add('ring-2', 'ring-blue-500', 'border-blue-500');
                option.classList.remove('border-gray-600');
            } else {
                option.classList.remove('ring-2', 'ring-blue-500', 'border-blue-500');
                option.classList.add('border-gray-600');
            }
        });
    }
}

function loadSavedMapType() {
    fetch('/get_map_type')
        .then(response => response.json())
        .then(data => {
            if (data.mapType) {
                changeMapType(data.mapType);
            }
        });
}

function saveMapType(mapType) {
    fetch('/save_map_type', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ mapType: mapType }),
    });
}

function zoomMap(factor) {
    camera.zoom /= factor;
    camera.updateProjectionMatrix();
    controls.update();
}

// Ensure setupMapSelection is called after DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    init();
    setupMapSelection();
});
