/**
 * @file move-validation-flow.js
 * @description Complete example of move validation workflow
 * Shows how all components work together
 */

/**
 * MOVE VALIDATION FLOW
 * ====================
 *
 * When a player attempts to move a piece, the system must validate
 * the move through multiple levels:
 *
 * LEVEL 1: Piece Movement Rules
 * - Can the piece move to that square according to its movement pattern?
 * - Example: Can a knight move from e4 to f6?
 *
 * LEVEL 2: Path Obstruction
 * - For sliding pieces, is the path clear?
 * - Knights skip this check (they jump)
 *
 * LEVEL 3: Capture Validation
 * - If capturing, is there an enemy piece at destination?
 * - Can't capture own pieces
 *
 * LEVEL 4: King Safety
 * - Does this move expose our king to check?
 * - This is the most complex validation
 *
 * LEVEL 5: Special Rules
 * - Castling requirements
 * - En passant validity
 * - Pawn promotion
 */

import MoveValidator from '../engine/MoveValidator.js';
import CheckDetector from '../engine/CheckDetector.js';

/**
 * Example validation workflow
 */
class MoveValidationExample {
  constructor(board, gameState) {
    this.board = board;
    this.gameState = gameState;
    this.validator = new MoveValidator();
    this.checkDetector = new CheckDetector();
  }

  /**
   * Complete move validation example
   *
   * @param {Piece} piece - Piece to move
   * @param {Object} from - Start position {row, col}
   * @param {Object} to - End position {row, col}
   * @returns {Object} Validation result with details
   */
  validateMove(piece, from, to) {
    const result = {
      valid: false,
      reason: '',
      details: {}
    };

    // LEVEL 1: Basic piece movement
    const validMoves = piece.getValidMoves(this.board);
    const isPieceMove = validMoves.some(move =>
      move.row === to.row && move.col === to.col
    );

    if (!isPieceMove) {
      result.reason = 'Invalid move for this piece type';
      result.details.validMoves = validMoves;
      return result;
    }

    // LEVEL 2: Path obstruction (for sliding pieces)
    if (this._isSlidingPiece(piece)) {
      if (!this._isPathClear(from, to)) {
        result.reason = 'Path is blocked';
        return result;
      }
    }

    // LEVEL 3: Capture validation
    const targetPiece = this.board.getPieceAt(to);
    if (targetPiece) {
      if (targetPiece.color === piece.color) {
        result.reason = 'Cannot capture own piece';
        return result;
      }
      result.details.capture = targetPiece;
    }

    // LEVEL 4: King safety check
    // This is the critical check - would this move expose king?
    if (this._wouldExposeKing(piece, from, to)) {
      result.reason = 'Move would expose king to check';
      return result;
    }

    // LEVEL 5: Special moves validation
    if (piece.type === 'king' && this._isCastlingMove(from, to)) {
      if (!this._validateCastling(piece, from, to)) {
        result.reason = 'Invalid castling';
        return result;
      }
      result.details.castling = true;
    }

    if (piece.type === 'pawn' && this._isEnPassant(from, to)) {
      if (!this._validateEnPassant(piece, from, to)) {
        result.reason = 'Invalid en passant';
        return result;
      }
      result.details.enPassant = true;
    }

    // All checks passed!
    result.valid = true;
    result.reason = 'Move is legal';
    return result;
  }

  /**
   * The critical check: Does this move expose our king?
   *
   * Algorithm:
   * 1. Clone the board
   * 2. Execute the move on the clone
   * 3. Check if our king is in check on the cloned board
   * 4. If yes, move is illegal
   *
   * @private
   */
  _wouldExposeKing(piece, from, to) {
    // Clone board to test move
    const testBoard = this.board.clone();

    // Execute move on test board
    testBoard.movePiece(from, to);

    // Check if our king is in check after this move
    const ourColor = piece.color;
    const isInCheck = this.checkDetector.isKingInCheck(ourColor, testBoard);

    return isInCheck;
  }

  /**
   * Check if path is clear for sliding pieces
   *
   * @private
   */
  _isPathClear(from, to) {
    // Get all squares between from and to
    const path = this._getPathBetween(from, to);

    // Check if any square is occupied
    return path.every(pos => !this.board.getPieceAt(pos));
  }

  /**
   * Validate castling move
   *
   * Requirements:
   * 1. King hasn't moved
   * 2. Rook hasn't moved
   * 3. Squares between are empty
   * 4. King is not in check
   * 5. King doesn't pass through check
   * 6. King doesn't end in check
   *
   * @private
   */
  _validateCastling(king, from, to) {
    // Check 1: King hasn't moved
    if (king.hasMoved) {
      return false;
    }

    // Check 2: Not currently in check
    if (this.checkDetector.isKingInCheck(king.color, this.board)) {
      return false;
    }

    // Determine kingside or queenside
    const isKingside = to.col > from.col;
    const rookCol = isKingside ? 7 : 0;
    const rook = this.board.getPieceAt({ row: from.row, col: rookCol });

    // Check 3: Rook exists and hasn't moved
    if (!rook || rook.type !== 'rook' || rook.hasMoved) {
      return false;
    }

    // Check 4: Squares between are empty
    const path = this._getPathBetween(from, to);
    if (!path.every(pos => !this.board.getPieceAt(pos))) {
      return false;
    }

    // Check 5: King doesn't pass through check
    for (const pos of path) {
      const testBoard = this.board.clone();
      testBoard.movePiece(from, pos);
      if (this.checkDetector.isKingInCheck(king.color, testBoard)) {
        return false;
      }
    }

    return true;
  }

  /**
   * Validate en passant capture
   *
   * Requirements:
   * 1. Target square is the en passant square from game state
   * 2. Enemy pawn is in correct position
   * 3. Enemy pawn just moved two squares
   *
   * @private
   */
  _validateEnPassant(pawn, from, to) {
    const enPassantTarget = this.gameState.enPassantTarget;

    if (!enPassantTarget) {
      return false;
    }

    // Check if target matches en passant square
    if (to.row !== enPassantTarget.row || to.col !== enPassantTarget.col) {
      return false;
    }

    // Verify enemy pawn is in position
    const enemyPawnRow = pawn.color === 'white' ? to.row + 1 : to.row - 1;
    const enemyPawn = this.board.getPieceAt({ row: enemyPawnRow, col: to.col });

    if (!enemyPawn || enemyPawn.type !== 'pawn' || enemyPawn.color === pawn.color) {
      return false;
    }

    return true;
  }

  // Helper methods
  _isSlidingPiece(piece) {
    return ['rook', 'bishop', 'queen'].includes(piece.type);
  }

  _isCastlingMove(from, to) {
    return Math.abs(to.col - from.col) === 2;
  }

  _isEnPassant(from, to) {
    // En passant is diagonal move to empty square
    return Math.abs(to.col - from.col) === 1 && !this.board.getPieceAt(to);
  }

  _getPathBetween(from, to) {
    // Returns array of positions between from and to (exclusive)
    // Implementation omitted for brevity
    return [];
  }
}

/**
 * USAGE EXAMPLE
 * =============
 */

// Setup
const board = new Board();
const gameState = new GameState();
const validator = new MoveValidationExample(board, gameState);

// Attempt to move a piece
const pawn = board.getPieceAt({ row: 6, col: 4 });
const from = { row: 6, col: 4 };
const to = { row: 4, col: 4 };

// Validate
const result = validator.validateMove(pawn, from, to);

if (result.valid) {
  console.log('Move is legal:', result.reason);
  if (result.details.capture) {
    console.log('Captures:', result.details.capture);
  }
  // Execute the move
} else {
  console.log('Move is illegal:', result.reason);
  // Show error to user
}

/**
 * COMMON PITFALLS
 * ===============
 *
 * 1. INFINITE RECURSION
 *    - Don't call isKingInCheck inside getValidMoves
 *    - Use two-pass validation: basic moves → filter exposing king
 *
 * 2. FORGETTING TO CLONE
 *    - Always clone board before testing moves
 *    - Modifying original board breaks game state
 *
 * 3. MOVE ORDER DEPENDENCY
 *    - Some checks must come before others
 *    - King safety check must be last (most expensive)
 *
 * 4. EN PASSANT STATE
 *    - Must be cleared after any move that isn't en passant capture
 *    - Only valid immediately after opponent's two-square pawn move
 *
 * 5. CASTLING EDGE CASES
 *    - Check ALL conditions
 *    - Most common bug: forgetting to check if king passes through check
 */

export default MoveValidationExample;
