"""Pure-Python, versioned staff effect policy.

This module intentionally has no Django imports so replay/balance tests can run
without configuring Django.
"""
from dataclasses import dataclass
from decimal import Decimal, ROUND_HALF_UP

from .constants import (
    FITNESS_ATTRIBUTES,
    GOALKEEPER_ATTRIBUTES,
    NEUTRAL_MULTIPLIER,
    STAFF_POLICY_KEY,
    STAFF_POLICY_VERSION,
)

_Q6 = Decimal("0.000001")
_MIN = Decimal("0.850000")
_MAX = Decimal("1.200000")


@dataclass(frozen=True)
class CapabilityState:
    level: int
    leadership: int
    tactical: int
    development: int
    fitness: int
    goalkeeping: int


@dataclass(frozen=True)
class StaffTrainingContext:
    head_coach: CapabilityState | None = None
    assistant_coach: CapabilityState | None = None
    fitness_coach: CapabilityState | None = None
    goalkeeper_coach: CapabilityState | None = None


@dataclass(frozen=True)
class StaffTrainingEffect:
    multiplier: Decimal
    policy_key: str = STAFF_POLICY_KEY
    policy_version: str = STAFF_POLICY_VERSION


class StaffTrainingEffectPolicyV1:
    policy_key = STAFF_POLICY_KEY
    policy_version = STAFF_POLICY_VERSION

    @classmethod
    def calculate(cls, *, target_attribute: str, context: StaffTrainingContext) -> StaffTrainingEffect:
        delta = Decimal("0")
        if context.head_coach:
            score = cls._effective_score(
                context.head_coach,
                ("leadership", "tactical", "development"),
            )
            delta += cls._contribution(score, Decimal("0.040000"))
        if context.assistant_coach:
            score = cls._effective_score(
                context.assistant_coach,
                ("tactical", "development", "leadership"),
            )
            delta += cls._contribution(score, Decimal("0.025000"))
        if target_attribute in FITNESS_ATTRIBUTES and context.fitness_coach:
            score = cls._effective_score(
                context.fitness_coach,
                ("fitness", "development", "leadership"),
            )
            delta += cls._contribution(score, Decimal("0.060000"))
        if target_attribute in GOALKEEPER_ATTRIBUTES and context.goalkeeper_coach:
            score = cls._effective_score(
                context.goalkeeper_coach,
                ("goalkeeping", "development", "leadership"),
            )
            delta += cls._contribution(score, Decimal("0.060000"))
        multiplier = NEUTRAL_MULTIPLIER + delta
        multiplier = max(_MIN, min(_MAX, multiplier)).quantize(_Q6, rounding=ROUND_HALF_UP)
        return StaffTrainingEffect(multiplier=multiplier)

    @staticmethod
    def _effective_score(capability: CapabilityState, fields: tuple[str, ...]) -> Decimal:
        base = sum(Decimal(getattr(capability, field)) for field in fields) / Decimal(len(fields))
        level_adjustment = Decimal(capability.level - 3) * Decimal("2.5")
        return max(Decimal("1"), min(Decimal("100"), base + level_adjustment))

    @staticmethod
    def _contribution(score: Decimal, max_delta: Decimal) -> Decimal:
        # 50 is neutral. 100 reaches +max_delta; 1 approaches -max_delta.
        normalized = (score - Decimal("50")) / Decimal("50")
        return normalized * max_delta
