/**
 * main.js - Application entry point
 * Initializes game and connects all components
 */

import { GameController } from './controllers/GameController.js';
import { BoardRenderer } from './views/BoardRenderer.js';
import { DragDropHandler } from './controllers/DragDropHandler.js';

class ChessApp {
    constructor() {
        // Initialize components
        this.game = new GameController({
            autoSave: true,
            enableTimer: false
        });

        this.renderer = new BoardRenderer(
            document.getElementById('chess-board'),
            {
                showCoordinates: true,
                pieceStyle: 'symbols',
                highlightLastMove: true
            }
        );

        this.dragDropHandler = new DragDropHandler(this.game, this.renderer);

        // Initialize UI
        this.initializeUI();
        this.setupEventListeners();
        this.setupGameEventListeners();

        // Start new game
        this.game.newGame();
        this.updateDisplay();
    }

    /**
     * Initialize UI components
     */
    initializeUI() {
        // Render initial board
        this.renderer.renderBoard(this.game.board, this.game.gameState);

        // Setup drag and drop
        this.dragDropHandler.setupEventListeners();

        // Update status
        this.updateTurnIndicator();
    }

    /**
     * Setup button event listeners
     */
    setupEventListeners() {
        // New Game
        document.getElementById('btn-new-game').addEventListener('click', () => {
            if (confirm('Start a new game? Current game will be lost.')) {
                this.game.newGame();
                this.updateDisplay();
                this.showMessage('New game started!');
            }
        });

        // Undo
        document.getElementById('btn-undo').addEventListener('click', () => {
            if (this.game.undo()) {
                this.updateDisplay();
                this.showMessage('Move undone');
            } else {
                this.showMessage('Nothing to undo');
            }
        });

        // Redo
        document.getElementById('btn-redo').addEventListener('click', () => {
            if (this.game.redo()) {
                this.updateDisplay();
                this.showMessage('Move redone');
            } else {
                this.showMessage('Nothing to redo');
            }
        });

        // Offer Draw
        const offerDrawBtn = document.getElementById('btn-offer-draw');
        if (offerDrawBtn) {
            offerDrawBtn.addEventListener('click', () => {
                this.game.offerDraw();
                this.showMessage('Draw offered to opponent');
            });
        }

        // Resign
        document.getElementById('btn-resign').addEventListener('click', () => {
            if (confirm('Are you sure you want to resign?')) {
                this.game.resign();
            }
        });
    }

    /**
     * Setup game event listeners
     */
    setupGameEventListeners() {
        // Move made
        this.game.on('move', (data) => {
            this.updateDisplay();
            this.playMoveSound();
        });

        // Check
        this.game.on('check', (data) => {
            this.showMessage(`Check! ${data.color} king is in check`);
            this.playCheckSound();
        });

        // Checkmate
        this.game.on('checkmate', (data) => {
            this.showMessage(`Checkmate! ${data.winner} wins!`, 'success');
            this.dragDropHandler.disable();
            this.playCheckmateSound();
        });

        // Stalemate
        this.game.on('stalemate', () => {
            this.showMessage('Stalemate! Game is a draw', 'info');
            this.dragDropHandler.disable();
        });

        // Draw
        this.game.on('draw', (data) => {
            this.showMessage(`Draw by ${data.reason}`, 'info');
            this.dragDropHandler.disable();
        });

        // Resign
        this.game.on('resign', (data) => {
            const winner = data.loser === 'white' ? 'Black' : 'White';
            this.showMessage(`${data.loser} resigned. ${winner} wins!`, 'success');
            this.dragDropHandler.disable();
        });

        // Promotion
        this.game.on('promotion', (data) => {
            this.showPromotionDialog(data.pawn, data.position);
        });

        // New Game
        this.game.on('newgame', () => {
            this.dragDropHandler.enable();
            this.updateDisplay();
        });
    }

    /**
     * Update all display elements
     */
    updateDisplay() {
        // Re-render board
        this.renderer.renderBoard(this.game.board, this.game.gameState);

        // Update turn indicator
        this.updateTurnIndicator();

        // Update move history
        this.updateMoveHistory();

        // Update captured pieces
        this.updateCapturedPieces();
    }

    /**
     * Update turn indicator
     */
    updateTurnIndicator() {
        const indicator = document.getElementById('current-turn');
        if (!indicator) {
            console.error('Turn indicator element not found');
            return;
        }
        const turn = this.game.currentTurn;
        indicator.textContent = `${turn.charAt(0).toUpperCase() + turn.slice(1)}'s Turn`;
        indicator.style.color = turn === 'white' ? '#ffffff' : '#333333';
    }

    /**
     * Update move history display
     */
    updateMoveHistory() {
        const moveList = document.getElementById('move-history');
        const history = this.game.gameState.moveHistory;

        if (history.length === 0) {
            moveList.innerHTML = '<p style="color: #999; font-style: italic;">No moves yet</p>';
            return;
        }

        let html = '';
        for (let i = 0; i < history.length; i += 2) {
            const moveNumber = Math.floor(i / 2) + 1;
            const whiteMove = history[i];
            const blackMove = history[i + 1];

            html += `<div>${moveNumber}. ${whiteMove.notation}`;
            if (blackMove) {
                html += ` ${blackMove.notation}`;
            }
            html += '</div>';
        }

        moveList.innerHTML = html;
        moveList.scrollTop = moveList.scrollHeight;
    }

    /**
     * Update captured pieces display
     */
    updateCapturedPieces() {
        const whiteCaptured = document.getElementById('captured-white-pieces');
        const blackCaptured = document.getElementById('captured-black-pieces');

        const captured = this.game.gameState.capturedPieces;

        // "Captured by Black" shows white pieces that black captured
        whiteCaptured.innerHTML = captured.white.map(piece =>
            `<span class="captured-piece white">${piece.getSymbol()}</span>`
        ).join('') || '-';

        // "Captured by White" shows black pieces that white captured
        blackCaptured.innerHTML = captured.black.map(piece =>
            `<span class="captured-piece black">${piece.getSymbol()}</span>`
        ).join('') || '-';
    }

    /**
     * Show message to user
     * @param {string} message - Message text
     * @param {string} type - Message type (info, success, error)
     */
    showMessage(message, type = 'info') {
        const statusMessage = document.getElementById('status-message');
        if (!statusMessage) {
            console.warn('Status message element not found, using console:', message);
            return;
        }

        // Add type class for styling
        statusMessage.className = `status-message ${type}`;
        statusMessage.textContent = message;
        statusMessage.style.display = 'block';

        // Auto-hide after 3 seconds
        setTimeout(() => {
            statusMessage.style.display = 'none';
        }, 3000);
    }

    /**
     * Show promotion dialog
     * @param {Pawn} pawn - Pawn to promote
     * @param {Position} position - Pawn position
     */
    showPromotionDialog(pawn, position) {
        const dialog = document.getElementById('promotion-dialog');

        if (!dialog) {
            console.error('Promotion dialog not found');
            return;
        }

        // Show dialog using HTML5 dialog element API
        dialog.showModal();

        // Update symbols for current color
        const symbols = pawn.color === 'white' ?
            { queen: '♕', rook: '♖', bishop: '♗', knight: '♘' } :
            { queen: '♛', rook: '♜', bishop: '♝', knight: '♞' };

        document.querySelectorAll('.promotion-piece .piece-icon').forEach(el => {
            const type = el.parentElement.dataset.piece;
            el.textContent = symbols[type];
        });

        // Handle selection
        const handleSelection = (e) => {
            const pieceType = e.currentTarget.dataset.piece;

            // Promote pawn
            import('./engine/SpecialMoves.js').then(({ SpecialMoves }) => {
                SpecialMoves.promote(this.game.board, pawn, pieceType);
                this.updateDisplay();
            });

            // Close dialog using HTML5 dialog element API
            dialog.close();

            // Remove listeners
            document.querySelectorAll('.promotion-piece').forEach(el => {
                el.removeEventListener('click', handleSelection);
            });
        };

        document.querySelectorAll('.promotion-piece').forEach(el => {
            el.addEventListener('click', handleSelection);
        });
    }

    /**
     * Play move sound (optional - can be implemented)
     */
    playMoveSound() {
        // TODO: Add sound effect
    }

    /**
     * Play check sound (optional - can be implemented)
     */
    playCheckSound() {
        // TODO: Add sound effect
    }

    /**
     * Play checkmate sound (optional - can be implemented)
     */
    playCheckmateSound() {
        // TODO: Add sound effect
    }
}

// Initialize app when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
    window.chessApp = new ChessApp();
    console.log('Chess game initialized successfully!');
});
