/**
 * SaltyBot Dashboard JavaScript
 * Handles WebSocket communication and UI updates
 */

// Connection state
let socket;
let isConnected = false;

// Initialize when page loads
document.addEventListener('DOMContentLoaded', () => {
    initializeSocket();
    initializeMap();
});

// Initialize WebSocket connection
function initializeSocket() {
    socket = io({
        reconnection: true,
        reconnectionDelay: 1000,
        reconnectionDelayMax: 5000,
        reconnectionAttempts: 5
    });

    socket.on('connect', () => {
        console.log('Connected to dashboard');
        isConnected = true;
        updateConnectionStatus(true);
    });

    socket.on('disconnect', () => {
        console.log('Disconnected from dashboard');
        isConnected = false;
        updateConnectionStatus(false);
    });

    socket.on('dashboard_update', (data) => {
        updateDashboard(data);
    });

    socket.on('error', (error) => {
        console.error('Socket error:', error);
    });
}

// Update connection status indicator
function updateConnectionStatus(connected) {
    const indicator = document.getElementById('status-indicator');
    const statusText = document.getElementById('status-text');

    if (connected) {
        indicator.classList.add('connected');
        statusText.textContent = 'Connected';
    } else {
        indicator.classList.remove('connected');
        statusText.textContent = 'Disconnected';
    }
}

// Update entire dashboard with new data
function updateDashboard(data) {
    updateBattery(data.battery_percent, data.battery_voltage);
    updateState(data.robot_state);
    updateMotors(data.motor_speeds);
    updateWiFi(data.wifi_signal);
    updateSensorHealth(data.sensor_health);
    updateEventLog(data.event_log);
    updateMap(data.map_data);
    updateTimestamp(data.timestamp);
}

// Update battery display
function updateBattery(percent, voltage) {
    const fill = document.getElementById('battery-fill');
    const percentText = document.getElementById('battery-percent');
    const voltageText = document.getElementById('battery-voltage');

    fill.style.width = percent + '%';
    percentText.textContent = Math.round(percent) + '%';
    voltageText.textContent = voltage.toFixed(1) + 'V';

    // Change color based on battery level
    if (percent < 20) {
        fill.style.background = 'linear-gradient(90deg, #f44336, #e91e63)';
    } else if (percent < 50) {
        fill.style.background = 'linear-gradient(90deg, #FF9800, #FFC107)';
    } else {
        fill.style.background = 'linear-gradient(90deg, #4CAF50, #8BC34A)';
    }
}

// Update robot state
function updateState(state) {
    const stateElement = document.getElementById('robot-state');
    stateElement.textContent = state || 'UNKNOWN';

    // Color coding for states
    const stateColors = {
        'IDLE': '#2196F3',
        'MOVING': '#4CAF50',
        'EXPLORING': '#FF9800',
        'CHARGING': '#8BC34A',
        'ERROR': '#f44336'
    };

    stateElement.style.background = stateColors[state] || '#2196F3';
}

// Update motor speeds
function updateMotors(speeds) {
    if (speeds.left !== undefined) {
        const leftMotor = document.getElementById('left-motor');
        const leftSpeed = document.getElementById('left-speed');
        const leftPercent = Math.min(Math.abs(speeds.left) / 1000 * 100, 100);
        leftMotor.style.width = leftPercent + '%';
        leftSpeed.textContent = Math.round(speeds.left) + ' RPM';
    }

    if (speeds.right !== undefined) {
        const rightMotor = document.getElementById('right-motor');
        const rightSpeed = document.getElementById('right-speed');
        const rightPercent = Math.min(Math.abs(speeds.right) / 1000 * 100, 100);
        rightMotor.style.width = rightPercent + '%';
        rightSpeed.textContent = Math.round(speeds.right) + ' RPM';
    }
}

// Update WiFi signal display
function updateWiFi(signal) {
    document.getElementById('wifi-strength').textContent = signal + ' dBm';
}

// Update sensor health indicators
function updateSensorHealth(health) {
    const sensors = {
        'camera': 'camera-health',
        'lidar': 'lidar-health',
        'audio': 'audio-health',
        'imu': 'imu-health'
    };

    for (const [sensor, elementId] of Object.entries(sensors)) {
        const element = document.getElementById(elementId);
        if (element) {
            const isHealthy = health[sensor] !== false;
            element.textContent = isHealthy ? '✓' : '✗';
            element.classList.toggle('health-ok', isHealthy);
            element.classList.toggle('health-error', !isHealthy);
        }
    }
}

// Update event log
function updateEventLog(events) {
    const logContainer = document.getElementById('event-log');

    if (!events || events.length === 0) {
        logContainer.innerHTML = '<p class="placeholder">Waiting for events...</p>';
        return;
    }

    logContainer.innerHTML = events.map(event => {
        const timestamp = new Date(event.timestamp * 1000).toLocaleTimeString();
        const message = event.message || event.type || 'Unknown event';
        return `
            <div class="event-item">
                <div class="event-time">${timestamp}</div>
                <div>${message}</div>
            </div>
        `;
    }).join('');
}

// Map visualization
let mapCanvas;
let mapContext;

function initializeMap() {
    mapCanvas = document.getElementById('map-canvas');
    mapContext = mapCanvas.getContext('2d');
    drawMapPlaceholder();
}

function drawMapPlaceholder() {
    mapContext.fillStyle = '#0a0e27';
    mapContext.fillRect(0, 0, mapCanvas.width, mapCanvas.height);
    mapContext.fillStyle = '#666';
    mapContext.font = '16px Arial';
    mapContext.textAlign = 'center';
    mapContext.fillText('Waiting for map data...', mapCanvas.width / 2, mapCanvas.height / 2);
}

function updateMap(mapData) {
    if (!mapData) {
        drawMapPlaceholder();
        return;
    }

    const canvas = mapCanvas;
    const ctx = mapContext;

    // Clear canvas
    ctx.fillStyle = '#0a0e27';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // Draw grid
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 0.5;
    for (let i = 0; i < canvas.width; i += 20) {
        ctx.beginPath();
        ctx.moveTo(i, 0);
        ctx.lineTo(i, canvas.height);
        ctx.stroke();
    }
    for (let i = 0; i < canvas.height; i += 20) {
        ctx.beginPath();
        ctx.moveTo(0, i);
        ctx.lineTo(canvas.width, i);
        ctx.stroke();
    }

    // Draw robot center
    const centerX = canvas.width / 2;
    const centerY = canvas.height / 2;
    ctx.fillStyle = '#4CAF50';
    ctx.beginPath();
    ctx.arc(centerX, centerY, 8, 0, Math.PI * 2);
    ctx.fill();

    // Update map info
    document.getElementById('map-res').textContent =
        (mapData.resolution || 0).toFixed(2) + ' m/px';
    document.getElementById('map-size').textContent =
        mapData.width + 'x' + mapData.height + ' cells';
}

// Update last update timestamp
function updateTimestamp(timestamp) {
    const date = new Date(timestamp * 1000);
    document.getElementById('update-time').textContent =
        'Last update: ' + date.toLocaleTimeString();
}

// Auto-refresh fallback (if WebSocket fails, use HTTP polling)
setInterval(() => {
    if (!isConnected) {
        fetch('/api/status')
            .then(response => response.json())
            .then(data => {
                data.timestamp = Date.now() / 1000;
                updateDashboard(data);
            })
            .catch(error => console.error('Fetch error:', error));
    }
}, 1000);
