/**
 * King.js - King piece implementation
 * Handles one-square movement and castling
 */

import { Piece } from './Piece.js';

export class King extends Piece {
    constructor(color, position) {
        super(color, position);
        this.type = 'king';
    }

    /**
     * Get valid moves for king
     * King moves one square in any direction
     * @param {Board} board - Game board
     * @param {Board} boardForCheck - Optional board for check validation
     * @param {GameState} gameState - Optional game state for castling
     * @returns {Position[]} Array of valid positions
     */
    getValidMoves(board, boardForCheck = null, gameState = null) {
        const moves = [];

        // All 8 directions, but only one square
        const directions = [
            [-1, -1], [-1, 0], [-1, 1],
            [0, -1],           [0, 1],
            [1, -1],  [1, 0],  [1, 1]
        ];

        for (const [dRow, dCol] of directions) {
            const targetRow = this.position.row + dRow;
            const targetCol = this.position.col + dCol;

            if (!this.isInBounds(targetRow, targetCol)) {
                continue;
            }

            try {
                const targetPiece = board.getPiece(targetRow, targetCol);

                // Can move to empty square or capture opponent piece
                if (!targetPiece || targetPiece.color !== this.color) {
                    // Check if move would put king in check
                    if (boardForCheck && this.isSquareAttacked(board, targetRow, targetCol)) {
                        continue;
                    }
                    moves.push({ row: targetRow, col: targetCol });
                }
            } catch (e) {
                // Out of bounds
                continue;
            }
        }

        // Add castling moves if gameState provided
        if (gameState) {
            const castlingMoves = this.getCastlingMoves(board, gameState);
            moves.push(...castlingMoves);
        }

        return moves;
    }

    /**
     * Check if a square is attacked by opponent pieces
     * @param {Board} board - Game board
     * @param {number} row - Target row
     * @param {number} col - Target column
     * @returns {boolean} True if square is attacked
     */
    isSquareAttacked(board, row, col) {
        const opponentColor = this.color === 'white' ? 'black' : 'white';

        // Check all opponent pieces
        for (let r = 0; r < 8; r++) {
            for (let c = 0; c < 8; c++) {
                try {
                    const piece = board.getPiece(r, c);
                    if (piece && piece.color === opponentColor) {
                        // Special handling for king (only check one square around)
                        if (piece.type === 'king') {
                            const rowDiff = Math.abs(r - row);
                            const colDiff = Math.abs(c - col);
                            if (rowDiff <= 1 && colDiff <= 1) {
                                return true;
                            }
                        } else if (piece.type === 'rook') {
                            // Check rook attacks (horizontal/vertical lines)
                            if (r === row || c === col) {
                                // Check if path is clear
                                if (this.isPathClear(board, r, c, row, col)) {
                                    return true;
                                }
                            }
                        } else if (piece.getValidMoves) {
                            // Check if this piece can attack the target square
                            const moves = piece.getValidMoves(board);
                            if (moves.some(m => m.row === row && m.col === col)) {
                                return true;
                            }
                        }
                    }
                } catch (e) {
                    // Skip invalid positions
                    continue;
                }
            }
        }

        return false;
    }

    /**
     * Check if path between two positions is clear
     * @param {Board} board - Game board
     * @param {number} fromRow - Start row
     * @param {number} fromCol - Start column
     * @param {number} toRow - End row
     * @param {number} toCol - End column
     * @returns {boolean} True if path is clear
     */
    isPathClear(board, fromRow, fromCol, toRow, toCol) {
        const rowStep = toRow === fromRow ? 0 : (toRow > fromRow ? 1 : -1);
        const colStep = toCol === fromCol ? 0 : (toCol > fromCol ? 1 : -1);

        let currentRow = fromRow + rowStep;
        let currentCol = fromCol + colStep;

        while (currentRow !== toRow || currentCol !== toCol) {
            try {
                if (board.getPiece(currentRow, currentCol) !== null) {
                    return false;
                }
            } catch (e) {
                return false;
            }
            currentRow += rowStep;
            currentCol += colStep;
        }

        return true;
    }

    /**
     * Get castling move positions
     * @param {Board} board - Game board
     * @param {GameState} gameState - Game state
     * @returns {Position[]} Castling target positions
     */
    getCastlingMoves(board, gameState) {
        const moves = [];

        // Can't castle if king has moved
        if (this.hasMoved) {
            return moves;
        }

        const row = this.position.row;

        // Cannot castle if currently in check
        if (this.isSquareAttacked(board, this.position.row, this.position.col)) {
            return moves;
        }

        try {
            // Kingside castling (king to g-file)
            const kingsideRook = board.getPiece(row, 7);
            if (kingsideRook &&
                kingsideRook.type === 'rook' &&
                kingsideRook.color === this.color &&
                !kingsideRook.hasMoved) {

                // Check if squares between king and rook are empty
                if (this.isEmpty(board, row, 5) &&
                    this.isEmpty(board, row, 6)) {

                    // Cannot castle through check - check f1/f8 and g1/g8
                    if (!this.isSquareAttacked(board, row, 5) &&
                        !this.isSquareAttacked(board, row, 6)) {
                        moves.push({ row, col: 6, castling: 'kingside' });
                    }
                }
            }
        } catch (e) {
            // Skip if out of bounds
        }

        try {
            // Queenside castling (king to c-file)
            const queensideRook = board.getPiece(row, 0);
            if (queensideRook &&
                queensideRook.type === 'rook' &&
                queensideRook.color === this.color &&
                !queensideRook.hasMoved) {

                // Check if squares between king and rook are empty
                if (this.isEmpty(board, row, 1) &&
                    this.isEmpty(board, row, 2) &&
                    this.isEmpty(board, row, 3)) {

                    // Cannot castle through check - check d1/d8 and c1/c8
                    if (!this.isSquareAttacked(board, row, 3) &&
                        !this.isSquareAttacked(board, row, 2)) {
                        moves.push({ row, col: 2, castling: 'queenside' });
                    }
                }
            }
        } catch (e) {
            // Skip if out of bounds
        }

        return moves;
    }
}
