/**
 * Pawn.js - Pawn piece implementation
 * Handles forward movement, diagonal captures, en passant, and promotion
 */

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

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

    /**
     * Get valid moves for pawn
     * @param {Board} board - Game board
     * @param {GameState} gameState - Optional game state for en passant
     * @returns {Position[]} Array of valid positions
     */
    getValidMoves(board, gameState = null) {
        const moves = [];
        const direction = this.color === 'white' ? -1 : 1;
        const startRow = this.color === 'white' ? 6 : 1;
        const promotionRank = this.color === 'white' ? 0 : 7;

        // Forward one square
        const oneForward = this.position.row + direction;
        if (this.isInBounds(oneForward, this.position.col) &&
            this.isEmpty(board, oneForward, this.position.col)) {
            const move = { row: oneForward, col: this.position.col };
            if (oneForward === promotionRank) {
                move.promotion = true;
            }
            moves.push(move);

            // Forward two squares from starting position
            if (this.position.row === startRow) {
                const twoForward = this.position.row + (direction * 2);
                if (this.isEmpty(board, twoForward, this.position.col)) {
                    moves.push({ row: twoForward, col: this.position.col });
                }
            }
        }

        // Diagonal captures
        const captureOffsets = [-1, 1];
        for (const offset of captureOffsets) {
            const captureRow = this.position.row + direction;
            const captureCol = this.position.col + offset;

            if (this.isInBounds(captureRow, captureCol)) {
                if (this.hasEnemyPiece(board, captureRow, captureCol)) {
                    const move = { row: captureRow, col: captureCol };
                    if (captureRow === promotionRank) {
                        move.promotion = true;
                    }
                    moves.push(move);
                }
            }
        }

        // En passant
        if (gameState && gameState.lastMove) {
            const enPassantMoves = this.getEnPassantMoves(board, gameState);
            for (const enPassantMove of enPassantMoves) {
                moves.push({ ...enPassantMove, enPassant: true });
            }
        }

        return moves;
    }

    /**
     * Check if pawn can be promoted
     * @returns {boolean} True if at promotion rank
     */
    canPromote() {
        const promotionRank = this.color === 'white' ? 0 : 7;
        return this.position.row === promotionRank;
    }

    /**
     * Get en passant target positions
     * @param {Board} board - Game board
     * @param {GameState} gameState - Game state with move history
     * @returns {Position[]} En passant target positions
     */
    getEnPassantMoves(board, gameState) {
        const moves = [];
        const direction = this.color === 'white' ? -1 : 1;
        const enPassantRank = this.color === 'white' ? 3 : 4;

        // Must be on correct rank
        if (this.position.row !== enPassantRank) {
            return moves;
        }

        // Check adjacent squares for enemy pawns that just moved two squares
        const offsets = [-1, 1];
        for (const offset of offsets) {
            const adjacentCol = this.position.col + offset;

            if (!this.isInBounds(this.position.row, adjacentCol)) {
                continue;
            }

            const adjacentPiece = board.getPiece(this.position.row, adjacentCol);

            if (adjacentPiece &&
                adjacentPiece.type === 'pawn' &&
                adjacentPiece.color !== this.color) {

                // Check if this pawn just moved two squares
                const lastMove = gameState.lastMove || (gameState.getLastMove && gameState.getLastMove());
                if (lastMove &&
                    lastMove.piece === adjacentPiece &&
                    Math.abs(lastMove.to.row - lastMove.from.row) === 2) {

                    const targetRow = this.position.row + direction;
                    moves.push({ row: targetRow, col: adjacentCol });
                }
            }
        }

        return moves;
    }
}
