// Map visualization with pan, zoom, and interactive features
let canvas, ctx;
let mapData = { locations: [], connections: [], interactables: [], spawn_tables: {} };
let viewOffset = { x: 0, y: 0 };
let viewScale = 1.0;
let isDragging = false;
let lastMouse = { x: 0, y: 0 };
let showLabels = true;
let selectedLocation = null;

// Visual settings
const gridSize = 100; // pixels per game unit
const nodeRadius = 12;
const colors = {
    background: '#0a0a1a',
    grid: '#1a1a2e',
    connection: '#3a3a6a',
    nodeSafe: '#4fc3f7',
    nodeLowDanger: '#ffa726',
    nodeMediumDanger: '#ff7043',
    nodeHighDanger: '#e53935',
    nodeSelected: '#00ff88',
    text: '#ffffff',
    label: '#e0e0e0'
};

// Initialize
window.addEventListener('load', async () => {
    canvas = document.getElementById('mapCanvas');
    ctx = canvas.getContext('2d');
    
    resizeCanvas();
    window.addEventListener('resize', resizeCanvas);
    
    // Load map data
    await loadMapData();
    
    // Event listeners
    canvas.addEventListener('mousedown', onMouseDown);
    canvas.addEventListener('mousemove', onMouseMove);
    canvas.addEventListener('mouseup', onMouseUp);
    canvas.addEventListener('mouseleave', onMouseUp);
    canvas.addEventListener('wheel', onWheel);
    canvas.addEventListener('click', onClick);
    
    // Touch event listeners for mobile
    canvas.addEventListener('touchstart', onTouchStart, { passive: false });
    canvas.addEventListener('touchmove', onTouchMove, { passive: false });
    canvas.addEventListener('touchend', onTouchEnd);
    
    document.getElementById('zoomIn').addEventListener('click', () => zoom(1.2));
    document.getElementById('zoomOut').addEventListener('click', () => zoom(0.8));
    document.getElementById('resetView').addEventListener('click', resetView);
    document.getElementById('toggleLabels').addEventListener('click', toggleLabels);
    
    // Image modal setup
    setupImageModal();
    
    draw();
});

function resizeCanvas() {
    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;
    draw();
}

async function loadMapData() {
    try {
        const response = await fetch('/map_data.json');
        mapData = await response.json();
        centerView();
        updateStatistics();
        draw();
    } catch (error) {
        console.error('Failed to load map data:', error);
    }
}

function updateStatistics() {
    document.getElementById('totalLocations').textContent = mapData.locations.length;
    document.getElementById('totalConnections').textContent = mapData.connections.length;
    document.getElementById('totalInteractables').textContent = mapData.interactables.length;
    
    const uniqueEnemies = new Set();
    Object.values(mapData.spawn_tables).forEach(enemies => {
        enemies.forEach(enemy => uniqueEnemies.add(enemy.npc_id));
    });
    document.getElementById('totalEnemies').textContent = uniqueEnemies.size;
}

function worldToScreen(x, y) {
    return {
        x: (x * gridSize * viewScale) + viewOffset.x + canvas.width / 2,
        y: (-y * gridSize * viewScale) + viewOffset.y + canvas.height / 2
    };
}

function screenToWorld(sx, sy) {
    return {
        x: ((sx - canvas.width / 2 - viewOffset.x) / gridSize) / viewScale,
        y: -((sy - canvas.height / 2 - viewOffset.y) / gridSize) / viewScale
    };
}

function centerView() {
    if (mapData.locations.length === 0) return;
    
    // Calculate bounds
    let minX = Infinity, maxX = -Infinity;
    let minY = Infinity, maxY = -Infinity;
    
    mapData.locations.forEach(loc => {
        minX = Math.min(minX, loc.x);
        maxX = Math.max(maxX, loc.x);
        minY = Math.min(minY, loc.y);
        maxY = Math.max(maxY, loc.y);
    });
    
    const centerX = (minX + maxX) / 2;
    const centerY = (minY + maxY) / 2;
    
    viewOffset.x = -centerX * gridSize * viewScale;
    viewOffset.y = centerY * gridSize * viewScale;
}

function resetView() {
    viewScale = 1.0;
    centerView();
    draw();
}

function toggleLabels() {
    showLabels = !showLabels;
    draw();
}

function zoom(factor) {
    const oldScale = viewScale;
    viewScale *= factor;
    viewScale = Math.max(0.3, Math.min(3.0, viewScale));
    
    const scaleDiff = viewScale - oldScale;
    viewOffset.x -= (canvas.width / 2) * scaleDiff / oldScale;
    viewOffset.y -= (canvas.height / 2) * scaleDiff / oldScale;
    
    draw();
}

function onMouseDown(e) {
    isDragging = true;
    lastMouse = { x: e.clientX, y: e.clientY };
    canvas.style.cursor = 'grabbing';
}

function onMouseMove(e) {
    if (isDragging) {
        const dx = e.clientX - lastMouse.x;
        const dy = e.clientY - lastMouse.y;
        viewOffset.x += dx;
        viewOffset.y += dy;
        lastMouse = { x: e.clientX, y: e.clientY };
        draw();
    }
}

function onMouseUp() {
    isDragging = false;
    canvas.style.cursor = 'grab';
}

// Touch event handlers for mobile
let lastTouch = { x: 0, y: 0 };
let touchStartTime = 0;
let lastTouchDistance = 0;

function onTouchStart(e) {
    e.preventDefault();
    
    if (e.touches.length === 1) {
        // Single touch - pan
        isDragging = true;
        const touch = e.touches[0];
        lastTouch = { x: touch.clientX, y: touch.clientY };
        lastMouse = { x: touch.clientX, y: touch.clientY };
        touchStartTime = Date.now();
    } else if (e.touches.length === 2) {
        // Two touches - pinch zoom
        isDragging = false;
        const touch1 = e.touches[0];
        const touch2 = e.touches[1];
        lastTouchDistance = Math.sqrt(
            Math.pow(touch2.clientX - touch1.clientX, 2) +
            Math.pow(touch2.clientY - touch1.clientY, 2)
        );
    }
}

function onTouchMove(e) {
    e.preventDefault();
    
    if (e.touches.length === 1 && isDragging) {
        // Single touch - pan
        const touch = e.touches[0];
        const dx = touch.clientX - lastTouch.x;
        const dy = touch.clientY - lastTouch.y;
        viewOffset.x += dx;
        viewOffset.y += dy;
        lastTouch = { x: touch.clientX, y: touch.clientY };
        draw();
    } else if (e.touches.length === 2) {
        // Two touches - pinch zoom
        const touch1 = e.touches[0];
        const touch2 = e.touches[1];
        const newDistance = Math.sqrt(
            Math.pow(touch2.clientX - touch1.clientX, 2) +
            Math.pow(touch2.clientY - touch1.clientY, 2)
        );
        
        if (lastTouchDistance > 0) {
            const zoomFactor = newDistance / lastTouchDistance;
            
            // Calculate center point between two touches
            const centerX = (touch1.clientX + touch2.clientX) / 2;
            const centerY = (touch1.clientY + touch2.clientY) / 2;
            
            const rect = canvas.getBoundingClientRect();
            const mouseX = centerX - rect.left;
            const mouseY = centerY - rect.top;
            
            const worldBefore = screenToWorld(mouseX, mouseY);
            zoom(zoomFactor);
            const worldAfter = screenToWorld(mouseX, mouseY);
            
            viewOffset.x += (worldAfter.x - worldBefore.x) * gridSize * viewScale;
            viewOffset.y -= (worldAfter.y - worldBefore.y) * gridSize * viewScale;
        }
        
        lastTouchDistance = newDistance;
        draw();
    }
}

function onTouchEnd(e) {
    if (e.touches.length === 0) {
        isDragging = false;
        lastTouchDistance = 0;
        
        // Check if it was a quick tap (< 200ms) for click action
        const touchDuration = Date.now() - touchStartTime;
        if (touchDuration < 200 && e.changedTouches.length === 1) {
            const touch = e.changedTouches[0];
            // Simulate click event
            const clickEvent = {
                clientX: touch.clientX,
                clientY: touch.clientY
            };
            onClick(clickEvent);
        }
    } else if (e.touches.length === 1) {
        // One finger remaining, reset for pan
        const touch = e.touches[0];
        lastTouch = { x: touch.clientX, y: touch.clientY };
        isDragging = true;
        lastTouchDistance = 0;
    }
}

function onWheel(e) {
    e.preventDefault();
    const zoomSpeed = 0.001;
    const delta = -e.deltaY * zoomSpeed;
    const factor = 1 + delta;
    
    const rect = canvas.getBoundingClientRect();
    const mouseX = e.clientX - rect.left;
    const mouseY = e.clientY - rect.top;
    
    const worldBefore = screenToWorld(mouseX, mouseY);
    zoom(factor);
    const worldAfter = screenToWorld(mouseX, mouseY);
    
    viewOffset.x += (worldAfter.x - worldBefore.x) * gridSize * viewScale;
    viewOffset.y -= (worldAfter.y - worldBefore.y) * gridSize * viewScale;
    
    draw();
}

function onClick(e) {
    if (isDragging) return;
    
    const rect = canvas.getBoundingClientRect();
    const mouseX = e.clientX - rect.left;
    const mouseY = e.clientY - rect.top;
    const worldPos = screenToWorld(mouseX, mouseY);
    
    // Find clicked location
    for (const location of mapData.locations) {
        const dist = Math.sqrt(
            Math.pow(location.x - worldPos.x, 2) +
            Math.pow(location.y - worldPos.y, 2)
        );
        
        if (dist < 0.3) { // Click threshold
            selectedLocation = location;
            showLocationInfo(location);
            draw();
            return;
        }
    }
}

function getDangerLevel(locationId) {
    const spawns = mapData.spawn_tables[locationId];
    if (!spawns || spawns.length === 0) return 'safe';
    
    // Calculate average enemy strength
    let totalXP = 0;
    spawns.forEach(enemy => {
        totalXP += enemy.xp_reward * (enemy.spawn_weight / 100);
    });
    
    if (totalXP < 20) return 'low';
    if (totalXP < 40) return 'medium';
    return 'high';
}

function getNodeColor(locationId) {
    const danger = getDangerLevel(locationId);
    switch (danger) {
        case 'safe': return colors.nodeSafe;
        case 'low': return colors.nodeLowDanger;
        case 'medium': return colors.nodeMediumDanger;
        case 'high': return colors.nodeHighDanger;
        default: return colors.nodeSafe;
    }
}

function draw() {
    // Clear canvas
    ctx.fillStyle = colors.background;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    
    // Draw grid
    drawGrid();
    
    // Draw connections
    ctx.lineWidth = 2 * viewScale;
    mapData.connections.forEach(conn => {
        const from = mapData.locations.find(l => l.id === conn.from);
        const to = mapData.locations.find(l => l.id === conn.to);
        
        if (from && to) {
            const fromScreen = worldToScreen(from.x, from.y);
            const toScreen = worldToScreen(to.x, to.y);
            
            ctx.strokeStyle = colors.connection;
            ctx.beginPath();
            ctx.moveTo(fromScreen.x, fromScreen.y);
            ctx.lineTo(toScreen.x, toScreen.y);
            ctx.stroke();
            
            // Draw distance label
            if (showLabels && viewScale > 0.6) {
                const midX = (fromScreen.x + toScreen.x) / 2;
                const midY = (fromScreen.y + toScreen.y) / 2;
                const stamina = Math.ceil(conn.distance * 3);
                
                ctx.fillStyle = 'rgba(42, 42, 74, 0.9)';
                ctx.fillRect(midX - 20, midY - 10, 40, 20);
                
                ctx.fillStyle = colors.label;
                ctx.font = `${10 * viewScale}px sans-serif`;
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillText(`${stamina}⚡`, midX, midY);
            }
        }
    });
    
    // Draw locations
    mapData.locations.forEach(location => {
        const screen = worldToScreen(location.x, location.y);
        const radius = nodeRadius * viewScale;
        
        // Node circle
        const isSelected = selectedLocation && selectedLocation.id === location.id;
        ctx.fillStyle = isSelected ? colors.nodeSelected : getNodeColor(location.id);
        ctx.strokeStyle = '#ffffff';
        ctx.lineWidth = isSelected ? 3 * viewScale : 2 * viewScale;
        
        ctx.beginPath();
        ctx.arc(screen.x, screen.y, radius, 0, Math.PI * 2);
        ctx.fill();
        ctx.stroke();
        
        // Interactable indicator
        if (location.interactable_count > 0) {
            ctx.fillStyle = '#ffd700';
            ctx.font = `${8 * viewScale}px sans-serif`;
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            ctx.fillText(location.interactable_count, screen.x, screen.y);
        }
        
        // Label
        if (showLabels) {
            ctx.fillStyle = colors.label;
            ctx.font = `${12 * viewScale}px sans-serif`;
            ctx.textAlign = 'center';
            ctx.textBaseline = 'top';
            ctx.fillText(location.name, screen.x, screen.y + radius + 5);
        }
    });
}

function drawGrid() {
    ctx.strokeStyle = colors.grid;
    ctx.lineWidth = 1;
    
    const step = gridSize * viewScale;
    const startX = (viewOffset.x % step) - step;
    const startY = (viewOffset.y % step) - step;
    
    for (let x = startX; x < canvas.width; x += step) {
        ctx.beginPath();
        ctx.moveTo(x, 0);
        ctx.lineTo(x, canvas.height);
        ctx.stroke();
    }
    
    for (let y = startY; y < canvas.height; y += step) {
        ctx.beginPath();
        ctx.moveTo(0, y);
        ctx.lineTo(canvas.width, y);
        ctx.stroke();
    }
}

function showLocationInfo(location) {
    // Location details
    const locationHTML = `
        ${location.image_path ? 
            `<img src="/${location.image_path}" class="location-image" onerror="this.style.display='none';" />` : 
            `<div class="image-placeholder">🗺️</div>`
        }
        <h3>${location.name}</h3>
        <div class="description">${location.description}</div>
        <p><strong>Coordinates:</strong> (${location.x}, ${location.y})</p>
        <p><strong>Interactables:</strong> ${location.interactable_count}</p>
        <h3>🧭 Connections</h3>
        <div class="connections">
            ${mapData.connections
                .filter(c => c.from === location.id)
                .map(c => {
                    const dest = mapData.locations.find(l => l.id === c.to);
                    const stamina = Math.ceil(c.distance * 3);
                    return `<div class="connection-item">
                        <strong>${c.direction.toUpperCase()}</strong><br>
                        ${dest ? dest.name : c.to}<br>
                        ${stamina}⚡ stamina
                    </div>`;
                })
                .join('')
            }
        </div>
    `;
    document.getElementById('locationInfo').innerHTML = locationHTML;
    
    // Add click handler to location image
    setTimeout(() => {
        const locationImg = document.querySelector('.location-image');
        if (locationImg) {
            locationImg.addEventListener('click', () => openImageModal(locationImg.src, location.name));
        }
    }, 0);
    
    // Interactables
    const locationInteractables = mapData.interactables.filter(i => i.location_id === location.id);
    if (locationInteractables.length > 0) {
        const interactablesHTML = `
            <div class="interactable-list">
                ${locationInteractables.map(inter => `
                    <div class="interactable-card">
                        <div class="interactable-header">
                            <div class="interactable-icon">
                                ${inter.image_path ? 
                                    `<img src="/${inter.image_path}" class="interactable-image" onerror="this.outerHTML='<div class=\\'interactable-image-placeholder\\'>📦</div>';" />` : 
                                    `<div class="interactable-image-placeholder">📦</div>`
                                }
                            </div>
                            <div class="interactable-name">${inter.name}</div>
                        </div>
                        ${inter.actions.map(action => `
                            <div class="action-item">
                                <div class="action-header">${action.label} (${action.stamina_cost}⚡)</div>
                                ${action.outcomes.map(outcome => `
                                    <div class="outcome-item outcome-${outcome.type}">
                                        <strong>${outcome.type}:</strong> ${outcome.text}
                                        ${Object.keys(outcome.items).length > 0 ? 
                                            `<br>Items: ${Object.entries(outcome.items).map(([id, qty]) => `${id} x${qty}`).join(', ')}` : ''}
                                        ${outcome.damage > 0 ? `<br>⚠️ Damage: ${outcome.damage} HP` : ''}
                                    </div>
                                `).join('')}
                            </div>
                        `).join('')}
                    </div>
                `).join('')}
            </div>
        `;
        document.getElementById('interactablesInfo').innerHTML = interactablesHTML;
        
        // Add click handlers to interactable images
        setTimeout(() => {
            document.querySelectorAll('.interactable-image').forEach(img => {
                img.addEventListener('click', () => openImageModal(img.src, img.alt || 'Interactable'));
            });
        }, 0);
    } else {
        document.getElementById('interactablesInfo').innerHTML = '<p class="no-data">No interactables at this location</p>';
    }
    
    // Enemies
    const enemies = mapData.spawn_tables[location.id];
    if (enemies && enemies.length > 0) {
        const enemiesHTML = `
            <p><strong>Encounter Rate:</strong> ${enemies[0].encounter_rate}% when traveling</p>
            <div class="enemy-list">
                ${enemies.map(enemy => `
                    <div class="enemy-card">
                        <div class="enemy-header">
                            <div class="enemy-icon">
                                ${enemy.image_url ? 
                                    `<img src="/${enemy.image_url}" class="enemy-image" onerror="this.outerHTML='<div class=\\'enemy-image-placeholder\\'>${enemy.emoji}</div>';" />` : 
                                    `<div class="enemy-image-placeholder">${enemy.emoji}</div>`
                                }
                            </div>
                            <div class="enemy-name">${enemy.name}</div>
                            <div>${enemy.spawn_chance}%</div>
                        </div>
                        <div class="enemy-stats">
                            <div class="stat-item">❤️ HP: ${enemy.hp_range[0]}-${enemy.hp_range[1]}</div>
                            <div class="stat-item">⚔️ DMG: ${enemy.damage_range[0]}-${enemy.damage_range[1]}</div>
                            <div class="stat-item">⭐ XP: ${enemy.xp_reward}</div>
                            <div class="stat-item">🎲 Weight: ${enemy.spawn_weight}</div>
                        </div>
                    </div>
                `).join('')}
            </div>
        `;
        document.getElementById('enemiesInfo').innerHTML = enemiesHTML;
        
        // Add click handlers to enemy images
        setTimeout(() => {
            document.querySelectorAll('.enemy-image').forEach(img => {
                img.addEventListener('click', () => openImageModal(img.src, img.alt || 'Enemy'));
            });
        }, 0);
    } else {
        document.getElementById('enemiesInfo').innerHTML = '<p class="no-data">✅ Safe zone - no enemies spawn here</p>';
    }
}

// Image Modal Functions
function setupImageModal() {
    const modal = document.getElementById('imageModal');
    const closeBtn = document.querySelector('.image-modal-close');
    
    // Close modal when clicking close button, backdrop, or pressing Escape
    closeBtn.addEventListener('click', closeImageModal);
    modal.addEventListener('click', (e) => {
        if (e.target === modal) {
            closeImageModal();
        }
    });
    document.addEventListener('keydown', (e) => {
        if (e.key === 'Escape' && modal.classList.contains('active')) {
            closeImageModal();
        }
    });
}

function openImageModal(imageSrc, imageTitle) {
    const modal = document.getElementById('imageModal');
    const modalImg = document.getElementById('modalImage');
    const modalInfo = document.getElementById('modalInfo');
    
    modalImg.src = imageSrc;
    modalImg.alt = imageTitle;
    modalInfo.textContent = imageTitle + ' - Click anywhere to close';
    modal.classList.add('active');
    
    // Prevent body scrolling when modal is open
    document.body.style.overflow = 'hidden';
}

function closeImageModal() {
    const modal = document.getElementById('imageModal');
    modal.classList.remove('active');
    
    // Re-enable body scrolling
    document.body.style.overflow = 'auto';
}
