/**
 * Piece.js - Base class for all chess pieces
 * Defines common interface and behavior
 */

export class Piece {
    /**
     * @param {string} color - 'white' or 'black'
     * @param {Position} position - {row, col}
     */
    constructor(color, position) {
        this.color = color;
        this.position = position;
        this.type = null; // Set by subclasses
        this.hasMoved = false;
        this.value = 0; // Set by subclasses
    }

    /**
     * Get all valid moves (without check validation)
     * Must be implemented by subclasses
     * @param {Board} board - Game board
     * @returns {Position[]} Array of valid positions
     */
    getValidMoves(board) {
        throw new Error(`getValidMoves must be implemented by ${this.constructor.name}`);
    }

    /**
     * Check if move to position is valid
     * @param {Board} board - Game board
     * @param {number} toRow - Target row
     * @param {number} toCol - Target column
     * @returns {boolean} True if valid
     */
    isValidMove(board, toRow, toCol) {
        const validMoves = this.getValidMoves(board);
        return validMoves.some(move => move.row === toRow && move.col === toCol);
    }

    /**
     * Check if position is within board bounds
     * @param {number} row - Row index
     * @param {number} col - Column index
     * @returns {boolean} True if in bounds
     */
    isInBounds(row, col) {
        return row >= 0 && row < 8 && col >= 0 && col < 8;
    }

    /**
     * Create deep copy of piece
     * @returns {Piece} Cloned piece
     */
    clone() {
        const PieceClass = this.constructor;
        const cloned = new PieceClass(this.color, { ...this.position });
        cloned.hasMoved = this.hasMoved;
        return cloned;
    }

    /**
     * Get Unicode symbol for piece
     * @returns {string} Unicode character
     */
    getSymbol() {
        const symbols = {
            white: {
                king: '♔',
                queen: '♕',
                rook: '♖',
                bishop: '♗',
                knight: '♘',
                pawn: '♙'
            },
            black: {
                king: '♚',
                queen: '♛',
                rook: '♜',
                bishop: '♝',
                knight: '♞',
                pawn: '♟'
            }
        };

        return symbols[this.color]?.[this.type] || '';
    }

    /**
     * Get FEN character for piece
     * @returns {string} FEN character
     */
    toFENChar() {
        const chars = {
            king: 'k',
            queen: 'q',
            rook: 'r',
            bishop: 'b',
            knight: 'n',
            pawn: 'p'
        };

        const char = chars[this.type] || '';
        return this.color === 'white' ? char.toUpperCase() : char;
    }

    /**
     * Check if position has enemy piece
     * @param {Board} board - Game board
     * @param {number} row - Row index
     * @param {number} col - Column index
     * @returns {boolean} True if enemy piece present
     */
    hasEnemyPiece(board, row, col) {
        const piece = board.getPiece(row, col);
        return piece !== null && piece.color !== this.color;
    }

    /**
     * Check if position is empty
     * @param {Board} board - Game board
     * @param {number} row - Row index
     * @param {number} col - Column index
     * @returns {boolean} True if empty
     */
    isEmpty(board, row, col) {
        return board.getPiece(row, col) === null;
    }

    /**
     * Add sliding moves in given directions
     * @param {Board} board - Game board
     * @param {Array<[number, number]>} directions - Direction vectors
     * @returns {Position[]} Valid positions
     */
    getSlidingMoves(board, directions) {
        const moves = [];

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

            while (this.isInBounds(currentRow, currentCol)) {
                const targetPiece = board.getPiece(currentRow, currentCol);

                if (!targetPiece) {
                    // Empty square
                    moves.push({ row: currentRow, col: currentCol });
                } else {
                    // Piece in the way
                    if (targetPiece.color !== this.color) {
                        // Can capture opponent piece
                        moves.push({ row: currentRow, col: currentCol });
                    }
                    break; // Can't move further
                }

                currentRow += dRow;
                currentCol += dCol;
            }
        }

        return moves;
    }
}
