const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const nextCanvas = document.getElementById('nextCanvas');
const nextCtx = nextCanvas.getContext('2d');
const holdCanvas = document.getElementById('holdCanvas');
const holdCtx = holdCanvas.getContext('2d');

const CELL_SIZE = 30;
const COLORS = [
    '#000000', // Empty
    '#00f5ff', // I - Cyan
    '#ffff00', // O - Yellow  
    '#800080', // T - Purple
    '#00ff00', // S - Green
    '#ff0000', // Z - Red
    '#0000ff', // J - Blue
    '#ffa500'  // L - Orange
];

let gameState = null;
let eventSource = null;

// Tetrimino shapes for rendering (only first rotation needed for display)
const shapes = {
    1: [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], // I
    2: [[0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]], // O
    3: [[0, 1, 0, 0], [1, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]], // T
    4: [[0, 1, 1, 0], [1, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], // S
    5: [[1, 1, 0, 0], [0, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]], // Z
    6: [[1, 0, 0, 0], [1, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]], // J
    7: [[0, 0, 1, 0], [1, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]]  // L
};

// Current piece shapes with all rotations
const currentPieceShapes = {
    1: [ // I piece
        [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],
        [[0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]],
        [[0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0]],
        [[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]]
    ],
    2: [ // O piece
        [[0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
        [[0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
        [[0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
        [[0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
    ],
    3: [ // T piece
        [[0, 1, 0, 0], [1, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
        [[0, 1, 0, 0], [0, 1, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]],
        [[0, 0, 0, 0], [1, 1, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]],
        [[0, 1, 0, 0], [1, 1, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0]]
    ],
    4: [ // S piece
        [[0, 1, 1, 0], [1, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
        [[0, 1, 0, 0], [0, 1, 1, 0], [0, 0, 1, 0], [0, 0, 0, 0]],
        [[0, 0, 0, 0], [0, 1, 1, 0], [1, 1, 0, 0], [0, 0, 0, 0]],
        [[1, 0, 0, 0], [1, 1, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0]]
    ],
    5: [ // Z piece
        [[1, 1, 0, 0], [0, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
        [[0, 0, 1, 0], [0, 1, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]],
        [[0, 0, 0, 0], [1, 1, 0, 0], [0, 1, 1, 0], [0, 0, 0, 0]],
        [[0, 1, 0, 0], [1, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 0]]
    ],
    6: [ // J piece
        [[1, 0, 0, 0], [1, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
        [[0, 1, 1, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0]],
        [[0, 0, 0, 0], [1, 1, 1, 0], [0, 0, 1, 0], [0, 0, 0, 0]],
        [[0, 1, 0, 0], [0, 1, 0, 0], [1, 1, 0, 0], [0, 0, 0, 0]]
    ],
    7: [ // L piece
        [[0, 0, 1, 0], [1, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
        [[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 1, 0], [0, 0, 0, 0]],
        [[0, 0, 0, 0], [1, 1, 1, 0], [1, 0, 0, 0], [0, 0, 0, 0]],
        [[1, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0]]
    ]
};

function connectEventSource() {
    if (eventSource) {
        eventSource.close();
    }

    eventSource = new EventSource('/events');

    eventSource.onopen = function () {
        updateConnectionStatus('Connected', true);
    };

    eventSource.onmessage = function (event) {
        gameState = JSON.parse(event.data);
        render();
        updateUI();
    };

    eventSource.onerror = function (event) {
        console.log('EventSource failed:', event);
        updateConnectionStatus('Disconnected', false);
        setTimeout(connectEventSource, 2000);
    };
}

function updateConnectionStatus(status, connected) {
    const statusElement = document.getElementById('connectionStatus');
    statusElement.textContent = status;
    statusElement.className = connected ? 'connection-status' : 'connection-status disconnected';
}

function sendAction(action, direction = '') {
    const url = '/action?action=' + action + (direction ? '&direction=' + direction : '');
    fetch(url, { method: 'POST' }).catch(console.error);
}

function startGame() {
    document.getElementById('gameOver').style.display = 'none';
    sendAction('start');
}

function render() {
    if (!gameState) return;

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

    // Draw board (only visible part: rows 0-19, but our array is 0-39)
    for (let y = 0; y < 20; y++) {
        for (let x = 0; x < 10; x++) {
            const cellValue = gameState.board[y][x];
            if (cellValue > 0) {
                ctx.fillStyle = COLORS[cellValue];
                ctx.fillRect(x * CELL_SIZE, (19 - y) * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                ctx.strokeStyle = '#333';
                ctx.strokeRect(x * CELL_SIZE, (19 - y) * CELL_SIZE, CELL_SIZE, CELL_SIZE);
            }
        }
    }

    // Draw current piece
    if (gameState.current_piece && gameState.game_running) {
        const piece = gameState.current_piece;
        const shape = currentPieceShapes[piece.type][piece.rotation];
        if (shape) {
            ctx.fillStyle = COLORS[piece.type];
            for (let py = 0; py < 4; py++) {
                for (let px = 0; px < 4; px++) {
                    if (shape[py][px]) {
                        const boardX = piece.x + px;
                        const boardY = piece.y + py;
                        if (boardY < 20) { // Only draw visible part
                            ctx.fillRect(boardX * CELL_SIZE, (19 - boardY) * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                            ctx.strokeStyle = '#666';
                            ctx.strokeRect(boardX * CELL_SIZE, (19 - boardY) * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                        }
                    }
                }
            }
        }
    }

    // Draw grid
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 1;
    for (let x = 0; x <= 10; x++) {
        ctx.beginPath();
        ctx.moveTo(x * CELL_SIZE, 0);
        ctx.lineTo(x * CELL_SIZE, canvas.height);
        ctx.stroke();
    }
    for (let y = 0; y <= 20; y++) {
        ctx.beginPath();
        ctx.moveTo(0, y * CELL_SIZE);
        ctx.lineTo(canvas.width, y * CELL_SIZE);
        ctx.stroke();
    }

    renderNextPieces();
    renderHoldPiece();
}

function renderNextPieces() {
    nextCtx.fillStyle = '#111';
    nextCtx.fillRect(0, 0, nextCanvas.width, nextCanvas.height);

    if (!gameState || !gameState.next_pieces) return;

    for (let i = 0; i < Math.min(6, gameState.next_pieces.length); i++) {
        const pieceType = gameState.next_pieces[i];
        const shape = shapes[pieceType];
        if (shape) {
            nextCtx.fillStyle = COLORS[pieceType];
            const offsetY = i * 50 + 5;
            for (let py = 0; py < 4; py++) {
                for (let px = 0; px < 4; px++) {
                    if (shape[py][px]) {
                        nextCtx.fillRect(px * 15 + 10, py * 15 + offsetY, 15, 15);
                        nextCtx.strokeStyle = '#666';
                        nextCtx.strokeRect(px * 15 + 10, py * 15 + offsetY, 15, 15);
                    }
                }
            }
        }
    }
}

function renderHoldPiece() {
    holdCtx.fillStyle = '#111';
    holdCtx.fillRect(0, 0, holdCanvas.width, holdCanvas.height);

    if (!gameState || !gameState.hold_piece) return;

    const pieceType = gameState.hold_piece;
    const shape = shapes[pieceType];
    if (shape) {
        holdCtx.fillStyle = gameState.can_hold ? COLORS[pieceType] : '#666';
        for (let py = 0; py < 4; py++) {
            for (let px = 0; px < 4; px++) {
                if (shape[py][px]) {
                    holdCtx.fillRect(px * 15 + 10, py * 15 + 10, 15, 15);
                    holdCtx.strokeStyle = '#444';
                    holdCtx.strokeRect(px * 15 + 10, py * 15 + 10, 15, 15);
                }
            }
        }
    }
}

function updateUI() {
    if (!gameState) return;

    document.getElementById('score').textContent = gameState.score.toLocaleString();
    document.getElementById('level').textContent = gameState.level;
    document.getElementById('lines').textContent = gameState.lines_cleared;
    document.getElementById('goal').textContent = gameState.level * gameState.lines_for_level;

    // Update game status
    let gameStatus = 'Not Started';
    if (gameState.game_over) {
        gameStatus = 'Game Over';
    } else if (gameState.game_running) {
        gameStatus = 'Playing';
    }
    document.getElementById('gameStatus').textContent = gameStatus;

    if (gameState.game_over) {
        document.getElementById('finalScore').textContent = gameState.score.toLocaleString();
        document.getElementById('finalLevel').textContent = gameState.level;
        document.getElementById('finalLines').textContent = gameState.lines_cleared;
        document.getElementById('gameOver').style.display = 'block';
    }
}

// Keyboard controls
document.addEventListener('keydown', function (event) {
    if (!gameState || !gameState.game_running) return;

    switch (event.code) {
        case 'ArrowLeft':
            event.preventDefault();
            sendAction('move', 'left');
            break;
        case 'ArrowRight':
            event.preventDefault();
            sendAction('move', 'right');
            break;
        case 'ArrowDown':
            event.preventDefault();
            sendAction('move', 'down');
            break;
        case 'Space':
            event.preventDefault();
            sendAction('hard_drop');
            break;
        case 'KeyZ':
            event.preventDefault();
            sendAction('rotate', 'ccw');
            break;
        case 'KeyX':
        case 'ArrowUp':
            event.preventDefault();
            sendAction('rotate', 'cw');
            break;
        case 'KeyC':
            event.preventDefault();
            sendAction('hold');
            break;
        case 'KeyR':
            if (event.ctrlKey) {
                event.preventDefault();
                location.reload();
            }
            break;
    }
});

// Prevent context menu on right click
document.addEventListener('contextmenu', function (e) {
    e.preventDefault();
});

// Initialize connection when page loads
window.addEventListener('load', function () {
    connectEventSource();
});

// Handle page visibility changes
document.addEventListener('visibilitychange', function () {
    if (document.hidden) {
        if (eventSource) {
            eventSource.close();
        }
    } else {
        connectEventSource();
    }
});