// Import Three.js modules
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

// Import our modular components
import { WebSocketManager } from './modules/websocket.js?v=2';
import { AircraftManager } from './modules/aircraft-manager.js?v=2';
import { MapManager } from './modules/map-manager.js?v=2';
import { UIManager } from './modules/ui-manager.js?v=2';

class SkyView {
    constructor() {
        console.log('🚀 SkyView v2 - KISS approach loaded');
        // Initialize managers
        this.wsManager = null;
        this.aircraftManager = null;
        this.mapManager = null;
        this.uiManager = null;
        
        // 3D Radar
        this.radar3d = null;
        
        // Charts
        this.charts = {};
        
        this.init();
    }

    async init() {
        try {
            console.log('Initializing SkyView application...');
            
            // Initialize UI manager first
            this.uiManager = new UIManager();
            this.uiManager.initializeViews();
            this.uiManager.initializeEventListeners();
            
            // Initialize map manager and get the main map
            this.mapManager = new MapManager();
            const map = await this.mapManager.initializeMap();
            
            // Initialize aircraft manager with the map
            this.aircraftManager = new AircraftManager(map);
            
            // Initialize WebSocket with callbacks
            this.wsManager = new WebSocketManager(
                (message) => this.handleWebSocketMessage(message),
                (status) => this.uiManager.updateConnectionStatus(status)
            );
            
            await this.wsManager.connect();
            
            // Initialize other components
            this.initializeCharts();
            this.uiManager.updateClocks();
            this.initialize3DRadar();
            
            // Set up map controls
            this.setupMapControls();
            
            // Set up aircraft selection listener
            this.setupAircraftSelection();
            
            this.startPeriodicTasks();
            
            console.log('SkyView application initialized successfully');
        } catch (error) {
            console.error('Initialization failed:', error);
            this.uiManager.showError('Failed to initialize application');
        }
    }

    setupMapControls() {
        const centerMapBtn = document.getElementById('center-map');
        const resetMapBtn = document.getElementById('reset-map');
        const toggleTrailsBtn = document.getElementById('toggle-trails');
        const toggleRangeBtn = document.getElementById('toggle-range');
        const toggleSourcesBtn = document.getElementById('toggle-sources');
        
        if (centerMapBtn) {
            centerMapBtn.addEventListener('click', () => this.aircraftManager.centerMapOnAircraft());
        }
        
        if (resetMapBtn) {
            resetMapBtn.addEventListener('click', () => this.mapManager.resetMap());
        }
        
        if (toggleTrailsBtn) {
            toggleTrailsBtn.addEventListener('click', () => {
                const showTrails = this.aircraftManager.toggleTrails();
                toggleTrailsBtn.textContent = showTrails ? 'Hide Trails' : 'Show Trails';
            });
        }
        
        if (toggleRangeBtn) {
            toggleRangeBtn.addEventListener('click', () => {
                const showRange = this.mapManager.toggleRangeCircles();
                toggleRangeBtn.textContent = showRange ? 'Hide Range' : 'Show Range';
            });
        }
        
        if (toggleSourcesBtn) {
            toggleSourcesBtn.addEventListener('click', () => {
                const showSources = this.mapManager.toggleSources();
                toggleSourcesBtn.textContent = showSources ? 'Hide Sources' : 'Show Sources';
            });
        }
        
        // Coverage controls
        const toggleHeatmapBtn = document.getElementById('toggle-heatmap');
        const coverageSourceSelect = document.getElementById('coverage-source');
        
        if (toggleHeatmapBtn) {
            toggleHeatmapBtn.addEventListener('click', async () => {
                const isActive = await this.mapManager.toggleHeatmap();
                toggleHeatmapBtn.textContent = isActive ? 'Hide Heatmap' : 'Show Heatmap';
            });
        }
        
        if (coverageSourceSelect) {
            coverageSourceSelect.addEventListener('change', (e) => {
                this.mapManager.setSelectedSource(e.target.value);
                this.mapManager.updateCoverageDisplay();
            });
        }
    }

    setupAircraftSelection() {
        document.addEventListener('aircraftSelected', (e) => {
            const { icao, aircraft } = e.detail;
            this.uiManager.switchView('map-view');
            
            // DON'T change map view - just open popup like Leaflet expects
            if (this.mapManager.map && aircraft.Latitude && aircraft.Longitude) {
                const marker = this.aircraftManager.aircraftMarkers.get(icao);
                if (marker) {
                    marker.openPopup();
                }
            }
        });
    }

    handleWebSocketMessage(message) {
        switch (message.type) {
            case 'initial_data':
                console.log('Received initial data - setting up source markers');
                this.updateData(message.data);
                // Setup source markers only on initial data load
                this.mapManager.updateSourceMarkers();
                break;
            case 'aircraft_update':
                this.updateData(message.data);
                break;
            default:
                console.log('Unknown message type:', message.type);
        }
    }

    updateData(data) {
        // Update all managers with new data
        this.uiManager.updateData(data);
        this.aircraftManager.updateAircraftData(data);
        this.mapManager.updateSourcesData(data);
        
        // Update UI components
        this.aircraftManager.updateMarkers();
        this.uiManager.updateAircraftTable();
        this.uiManager.updateStatistics();
        this.uiManager.updateHeaderInfo();
        
        // Update coverage controls
        this.mapManager.updateCoverageControls();
        
        if (this.uiManager.currentView === 'radar3d-view') {
            this.update3DRadar();
        }
    }

    // View switching
    async switchView(viewId) {
        const actualViewId = this.uiManager.switchView(viewId);
        
        // Handle view-specific initialization
        const baseName = actualViewId.replace('-view', '');
        switch (baseName) {
            case 'coverage':
                await this.mapManager.initializeCoverageMap();
                break;
            case 'radar3d':
                this.update3DRadar();
                break;
        }
    }

    // Charts
    initializeCharts() {
        const aircraftChartCanvas = document.getElementById('aircraft-chart');
        if (!aircraftChartCanvas) {
            console.warn('Aircraft chart canvas not found');
            return;
        }
        
        try {
            this.charts.aircraft = new Chart(aircraftChartCanvas, {
                type: 'line',
                data: {
                    labels: [],
                    datasets: [{
                        label: 'Aircraft Count',
                        data: [],
                        borderColor: '#00d4ff',
                        backgroundColor: 'rgba(0, 212, 255, 0.1)',
                        tension: 0.4
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: { display: false }
                    },
                    scales: {
                        x: { display: false },
                        y: { 
                            beginAtZero: true,
                            ticks: { color: '#888' }
                        }
                    }
                }
            });
        } catch (error) {
            console.warn('Chart.js not available, skipping charts initialization');
        }
    }

    updateCharts() {
        if (!this.charts.aircraft) return;
        
        const now = new Date();
        const timeLabel = now.toLocaleTimeString();
        
        // Update aircraft count chart
        const chart = this.charts.aircraft;
        chart.data.labels.push(timeLabel);
        chart.data.datasets[0].data.push(this.aircraftManager.aircraftData.size);
        
        if (chart.data.labels.length > 20) {
            chart.data.labels.shift();
            chart.data.datasets[0].data.shift();
        }
        
        chart.update('none');
    }

    // 3D Radar (basic implementation)
    initialize3DRadar() {
        try {
            const container = document.getElementById('radar3d-container');
            if (!container) return;
            
            // Create scene
            this.radar3d = {
                scene: new THREE.Scene(),
                camera: new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000),
                renderer: new THREE.WebGLRenderer({ alpha: true, antialias: true }),
                controls: null,
                aircraftMeshes: new Map()
            };
            
            // Set up renderer
            this.radar3d.renderer.setSize(container.clientWidth, container.clientHeight);
            this.radar3d.renderer.setClearColor(0x0a0a0a, 0.9);
            container.appendChild(this.radar3d.renderer.domElement);
            
            // Add lighting
            const ambientLight = new THREE.AmbientLight(0x404040, 0.6);
            this.radar3d.scene.add(ambientLight);
            
            const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
            directionalLight.position.set(10, 10, 5);
            this.radar3d.scene.add(directionalLight);
            
            // Set up camera
            this.radar3d.camera.position.set(0, 50, 50);
            this.radar3d.camera.lookAt(0, 0, 0);
            
            // Add controls
            this.radar3d.controls = new OrbitControls(this.radar3d.camera, this.radar3d.renderer.domElement);
            this.radar3d.controls.enableDamping = true;
            this.radar3d.controls.dampingFactor = 0.05;
            
            // Add ground plane
            const groundGeometry = new THREE.PlaneGeometry(200, 200);
            const groundMaterial = new THREE.MeshLambertMaterial({ 
                color: 0x2a4d3a, 
                transparent: true, 
                opacity: 0.5 
            });
            const ground = new THREE.Mesh(groundGeometry, groundMaterial);
            ground.rotation.x = -Math.PI / 2;
            this.radar3d.scene.add(ground);
            
            // Add grid
            const gridHelper = new THREE.GridHelper(200, 20, 0x44aa44, 0x44aa44);
            this.radar3d.scene.add(gridHelper);
            
            // Start render loop
            this.render3DRadar();
            
            console.log('3D Radar initialized successfully');
        } catch (error) {
            console.error('Failed to initialize 3D radar:', error);
        }
    }

    update3DRadar() {
        if (!this.radar3d || !this.radar3d.scene || !this.aircraftManager) return;
        
        try {
            // Update aircraft positions in 3D space
            this.aircraftManager.aircraftData.forEach((aircraft, icao) => {
                if (aircraft.Latitude && aircraft.Longitude) {
                    const key = icao.toString();
                    
                    if (!this.radar3d.aircraftMeshes.has(key)) {
                        // Create new aircraft mesh
                        const geometry = new THREE.ConeGeometry(0.5, 2, 6);
                        const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 });
                        const mesh = new THREE.Mesh(geometry, material);
                        this.radar3d.aircraftMeshes.set(key, mesh);
                        this.radar3d.scene.add(mesh);
                    }
                    
                    const mesh = this.radar3d.aircraftMeshes.get(key);
                    
                    // Convert lat/lon to local coordinates (simplified)
                    const x = (aircraft.Longitude - (-0.4600)) * 111320 * Math.cos(aircraft.Latitude * Math.PI / 180) / 1000;
                    const z = -(aircraft.Latitude - 51.4700) * 111320 / 1000;
                    const y = (aircraft.Altitude || 0) / 1000; // Convert feet to km for display
                    
                    mesh.position.set(x, y, z);
                    
                    // Orient mesh based on track
                    if (aircraft.Track !== undefined) {
                        mesh.rotation.y = -aircraft.Track * Math.PI / 180;
                    }
                }
            });
            
            // Remove old aircraft
            this.radar3d.aircraftMeshes.forEach((mesh, key) => {
                if (!this.aircraftManager.aircraftData.has(key)) {
                    this.radar3d.scene.remove(mesh);
                    this.radar3d.aircraftMeshes.delete(key);
                }
            });
        } catch (error) {
            console.error('Failed to update 3D radar:', error);
        }
    }

    render3DRadar() {
        if (!this.radar3d) return;
        
        requestAnimationFrame(() => this.render3DRadar());
        
        if (this.radar3d.controls) {
            this.radar3d.controls.update();
        }
        
        this.radar3d.renderer.render(this.radar3d.scene, this.radar3d.camera);
    }

    startPeriodicTasks() {
        // Update clocks every second
        setInterval(() => this.uiManager.updateClocks(), 1000);
        
        // Update charts every 10 seconds
        setInterval(() => this.updateCharts(), 10000);
        
        // Periodic cleanup
        setInterval(() => {
            // Clean up old trail data, etc.
        }, 30000);
    }
}

// Initialize application when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
    window.skyview = new SkyView();
});