"""
Material Analysis Tool
Evaluates material balance, piece values, and trading opportunities.

Returns structured analysis of:
- Total material count for each side
- Material imbalances (which side is up/down)
- Piece-specific advantages
- Trading recommendations
"""

import chess
from typing import Dict, List


# Standard piece values in centipawns
PIECE_VALUES = {
    chess.PAWN: 100,
    chess.KNIGHT: 320,
    chess.BISHOP: 330,
    chess.ROOK: 500,
    chess.QUEEN: 900,
    chess.KING: 0  # King has no material value
}


def analyze_material(fen: str) -> Dict:
    """
    Analyze material balance for a position.
    
    Args:
        fen: Position in FEN notation
    
    Returns:
        Dictionary with:
            - score: Material imbalance in centipawns (positive = white ahead)
            - factors: List of contributing factors (piece counts, imbalances)
            - evidence: Human-readable explanations
            - details: Detailed breakdown by piece type
    
    Example:
        >>> result = analyze_material("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
        >>> result['score']
        0
        >>> result['evidence'][0]
        'Material is equal (0.00 pawns)'
    """
    board = chess.Board(fen)
    
    # Count pieces for each side
    white_material = _count_material(board, chess.WHITE)
    black_material = _count_material(board, chess.BLACK)
    
    # Calculate material balance
    material_diff = white_material['total'] - black_material['total']
    
    # Build factors list
    factors = []
    evidence = []
    
    # Overall balance
    if material_diff > 0:
        pawns_ahead = material_diff / 100
        factors.append({
            'type': 'material_advantage',
            'side': 'white',
            'value': material_diff
        })
        evidence.append(f"White is ahead by {pawns_ahead:.2f} pawns ({material_diff} centipawns)")
    elif material_diff < 0:
        pawns_ahead = abs(material_diff) / 100
        factors.append({
            'type': 'material_advantage',
            'side': 'black',
            'value': abs(material_diff)
        })
        evidence.append(f"Black is ahead by {pawns_ahead:.2f} pawns ({abs(material_diff)} centipawns)")
    else:
        factors.append({
            'type': 'material_balance',
            'value': 0
        })
        evidence.append("Material is equal (0.00 pawns)")
    
    # Piece-by-piece comparison
    piece_comparison = _compare_pieces(white_material, black_material)
    factors.extend(piece_comparison['factors'])
    evidence.extend(piece_comparison['evidence'])
    
    # Trading advice
    trading_advice = _generate_trading_advice(material_diff, white_material, black_material, board.turn)
    if trading_advice:
        evidence.append(f"Trading advice: {trading_advice}")
    
    return {
        'score': material_diff,
        'factors': factors,
        'evidence': evidence,
        'details': {
            'white': white_material,
            'black': black_material,
            'difference': material_diff
        }
    }


def _count_material(board: chess.Board, color: chess.Color) -> Dict:
    """
    Count material for one side.
    
    Args:
        board: Chess board
        color: Color to count (WHITE or BLACK)
    
    Returns:
        Dictionary with piece counts and total value
    """
    counts = {
        'pawns': len(board.pieces(chess.PAWN, color)),
        'knights': len(board.pieces(chess.KNIGHT, color)),
        'bishops': len(board.pieces(chess.BISHOP, color)),
        'rooks': len(board.pieces(chess.ROOK, color)),
        'queens': len(board.pieces(chess.QUEEN, color)),
    }
    
    total = (
        counts['pawns'] * PIECE_VALUES[chess.PAWN] +
        counts['knights'] * PIECE_VALUES[chess.KNIGHT] +
        counts['bishops'] * PIECE_VALUES[chess.BISHOP] +
        counts['rooks'] * PIECE_VALUES[chess.ROOK] +
        counts['queens'] * PIECE_VALUES[chess.QUEEN]
    )
    
    return {
        **counts,
        'total': total
    }


def _compare_pieces(white_material: Dict, black_material: Dict) -> Dict:
    """
    Compare piece counts between sides.
    
    Returns:
        Dictionary with factors and evidence about piece imbalances
    """
    factors = []
    evidence = []
    
    piece_types = [
        ('queens', 'queen', PIECE_VALUES[chess.QUEEN]),
        ('rooks', 'rook', PIECE_VALUES[chess.ROOK]),
        ('bishops', 'bishop', PIECE_VALUES[chess.BISHOP]),
        ('knights', 'knight', PIECE_VALUES[chess.KNIGHT]),
        ('pawns', 'pawn', PIECE_VALUES[chess.PAWN])
    ]
    
    for key, name, value in piece_types:
        white_count = white_material[key]
        black_count = black_material[key]
        
        if white_count > black_count:
            diff = white_count - black_count
            plural = 's' if diff > 1 else ''
            factors.append({
                'type': 'piece_advantage',
                'piece': name,
                'side': 'white',
                'count': diff,
                'value': diff * value
            })
            evidence.append(f"White has {diff} extra {name}{plural}")
        elif black_count > white_count:
            diff = black_count - white_count
            plural = 's' if diff > 1 else ''
            factors.append({
                'type': 'piece_advantage',
                'piece': name,
                'side': 'black',
                'count': diff,
                'value': diff * value
            })
            evidence.append(f"Black has {diff} extra {name}{plural}")
    
    return {
        'factors': factors,
        'evidence': evidence
    }


def _generate_trading_advice(material_diff: int, white_material: Dict, black_material: Dict, to_move: chess.Color) -> str:
    """
    Generate trading advice based on material situation.
    
    Args:
        material_diff: Material difference (positive = white ahead)
        white_material: White's material breakdown
        black_material: Black's material breakdown
        to_move: Which side is to move
    
    Returns:
        Trading advice string or empty string
    """
    side_name = "White" if to_move == chess.WHITE else "Black"
    
    # If material is roughly equal, no specific advice
    if abs(material_diff) < 100:
        return ""
    
    # If side to move is ahead in material
    if (to_move == chess.WHITE and material_diff > 100) or (to_move == chess.BLACK and material_diff < -100):
        return f"{side_name} should trade pieces to simplify into a winning endgame"
    
    # If side to move is behind in material
    if (to_move == chess.WHITE and material_diff < -100) or (to_move == chess.BLACK and material_diff > 100):
        return f"{side_name} should avoid trades and seek complications to create counterplay"
    
    return ""
