"""Version 2 drill weights. Credits retain the existing rating/potential policy."""
from decimal import Decimal
from hashlib import sha256

from .constants import TRAINABLE_PLAYER_ATTRIBUTES
from .exceptions import TrainingValidationError

KEY = "ftg.training.drill.v2"
VERSION = "2.0.0"
RELATED = {
    "passing": ("vision", "first_touch", "teamwork"),
    "crossing": ("passing", "ball_control", "vision"),
    "finishing": ("composure", "shooting", "off_ball"),
    "shooting": ("finishing", "long_shots", "balance"),
    "long_shots": ("shooting", "composure", "ball_control"),
    "dribbling": ("ball_control", "agility", "balance"),
    "ball_control": ("first_touch", "dribbling", "balance"),
    "first_touch": ("ball_control", "passing", "anticipation"),
    "heading": ("jumping", "positioning", "strength"),
    "tackling": ("marking", "anticipation", "balance"),
    "marking": ("positioning", "concentration", "tackling"),
    "set_pieces": ("shooting", "crossing", "composure"),
    "vision": ("passing", "decision_making", "anticipation"),
    "positioning": ("anticipation", "concentration", "marking"),
    "decision_making": ("vision", "composure", "concentration"),
    "composure": ("concentration", "decision_making", "finishing"),
    "concentration": ("anticipation", "decision_making", "positioning"),
    "anticipation": ("positioning", "vision", "concentration"),
    "off_ball": ("positioning", "acceleration", "teamwork"),
    "aggression": ("work_rate", "strength", "tackling"),
    "work_rate": ("stamina", "teamwork", "natural_fitness"),
    "teamwork": ("passing", "off_ball", "work_rate"),
    "pace": ("acceleration", "stamina", "natural_fitness"),
    "acceleration": ("pace", "agility", "balance"),
    "agility": ("balance", "acceleration", "dribbling"),
    "balance": ("agility", "strength", "ball_control"),
    "strength": ("balance", "jumping", "natural_fitness"),
    "stamina": ("natural_fitness", "work_rate", "pace"),
    "jumping": ("strength", "heading", "balance"),
    "natural_fitness": ("stamina", "strength", "agility"),
    "gk_diving": ("gk_reflexes", "agility", "jumping"),
    "gk_handling": ("concentration", "gk_positioning", "balance"),
    "gk_reflexes": ("gk_diving", "agility", "anticipation"),
    "gk_positioning": ("anticipation", "concentration", "gk_handling"),
    "gk_kicking": ("passing", "vision", "ball_control"),
    "gk_one_on_one": ("gk_reflexes", "composure", "gk_positioning"),
}
assert set(RELATED) == set(TRAINABLE_PLAYER_ATTRIBUTES)


def weights(target):
    if target not in RELATED:
        raise TrainingValidationError("Unknown training skill.")
    return {target: Decimal("1"), **dict(zip(RELATED[target], map(Decimal, ("0.30", "0.20", "0.10"))))}


def formation_identity(formation, slots=None):
    from matches.constants import FORMATION_SLOTS
    if formation not in FORMATION_SLOTS:
        raise TrainingValidationError("Unknown formation; use a valid eleven-player system.")
    expected = FORMATION_SLOTS[formation]
    if formation != "CUSTOM":
        if slots and set(slots) != set(expected):
            raise TrainingValidationError("Slots do not match formation.")
        return formation, list(expected)
    if not isinstance(slots, list) or len(slots) != 11 or any(not isinstance(s, str) for s in slots) or len(set(slots)) != 11 or "GK" not in slots or not set(slots) <= set(expected):
        raise TrainingValidationError("Custom formation requires eleven distinct valid slots including GK.")
    signature = sha256("|".join(sorted(slots)).encode()).hexdigest()[:32]
    return f"CUSTOM:{signature}", slots
