"""Elo rating system"""
from typing import Dict, Optional
import math


class EloRating:
    """Simple Elo rating calculator"""
    
    K_FACTOR = 32
    INITIAL_RATING = 1500
    
    @staticmethod
    def expected_score(rating_a: float, rating_b: float) -> float:
        """Calculate expected score for team A"""
        return 1 / (1 + 10 ** ((rating_b - rating_a) / 400))
    
    @staticmethod
    def update_rating(
        rating: float,
        expected: float,
        actual: float,
        k_factor: float = K_FACTOR
    ) -> float:
        """Update rating based on result"""
        return rating + k_factor * (actual - expected)
    
    @staticmethod
    def calculate_ratings(
        team_ratings: Dict[int, float],
        home_team_id: int,
        away_team_id: int,
        home_score: int,
        away_score: int
    ) -> Dict[int, float]:
        """Calculate new ratings after a match"""
        home_rating = team_ratings.get(home_team_id, EloRating.INITIAL_RATING)
        away_rating = team_ratings.get(away_team_id, EloRating.INITIAL_RATING)
        
        # Home advantage: add 100 points
        home_rating_adjusted = home_rating + 100
        
        # Expected scores
        home_expected = EloRating.expected_score(home_rating_adjusted, away_rating)
        away_expected = 1 - home_expected
        
        # Actual scores (1 for win, 0.5 for draw, 0 for loss)
        if home_score > away_score:
            home_actual = 1.0
            away_actual = 0.0
        elif home_score == away_score:
            home_actual = 0.5
            away_actual = 0.5
        else:
            home_actual = 0.0
            away_actual = 1.0
        
        # Update ratings
        new_home_rating = EloRating.update_rating(home_rating, home_expected, home_actual)
        new_away_rating = EloRating.update_rating(away_rating, away_expected, away_actual)
        
        team_ratings[home_team_id] = new_home_rating
        team_ratings[away_team_id] = new_away_rating
        
        return team_ratings

