"""
Difficulty Variants for CoGames Missions

This module defines difficulty levels that can be applied to any mission to create
varied challenges. Each difficulty level modifies mission-level parameters like
energy regen, move cost, and capacity limits.
"""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING, override

from pydantic import Field

from cogames.core import CoGameMissionVariant

if TYPE_CHECKING:
    from cogames.cogs_vs_clips.mission import CvCMission
from mettagrid.config.mettagrid_config import MettaGridConfig

logger = logging.getLogger(__name__)


# Allow zero to persist for difficulties that force no passive regen
ENERGY_REGEN_FLOOR = 0


# =============================================================================
# Difficulty Registry
# =============================================================================


class DifficultyLevel(CoGameMissionVariant):
    """Configuration for a difficulty level."""

    name: str = Field(description="Difficulty name (easy, medium, hard, brutal, etc.)")
    description: str = Field(description="What makes this difficulty challenging", default="")

    # Solar override (if set, overrides weather day/night deltas)
    solar_override: int | None = Field(default=None)
    move_energy_cost_override: int | None = Field(default=None)
    energy_capacity_override: int | None = Field(default=None)
    cargo_capacity_override: int | None = Field(default=None)
    max_steps_override: int | None = Field(default=None)

    @override
    def modify_mission(self, mission: CvCMission):
        """Apply a difficulty level to a mission instance."""
        pass  # No mission-level modifications needed currently

    @override
    def modify_env(self, mission: CvCMission, env: MettaGridConfig):
        if self.max_steps_override is not None:
            env.game.max_steps = self.max_steps_override


# =============================================================================
# Standard Difficulty Levels
# =============================================================================

STANDARD = DifficultyLevel(
    name="standard",
    description="Baseline mission parameters (legacy medium)",
)

HARD = DifficultyLevel(
    name="hard",
    description="Minimal passive regen and higher move cost",
    solar_override=1,  # Minimal regen prevents deadlock
    move_energy_cost_override=2,
)

SINGLE_USE = DifficultyLevel(
    name="single_use",
    description="Minimal regen - no second chances",
    solar_override=1,
)

SPEED_RUN = DifficultyLevel(
    name="speed_run",
    description="Short clock, cheap movement",
    solar_override=2,
    move_energy_cost_override=1,
    max_steps_override=600,
)

ENERGY_CRISIS = DifficultyLevel(
    name="energy_crisis",
    description="Minimal passive regen - plan every move",
    solar_override=1,  # Minimal regen prevents deadlock
)

# Export variants for use with --variant CLI flag.
# Ordered in canonical difficulty order.
DIFFICULTY_VARIANTS: list[DifficultyLevel] = [
    STANDARD,
    HARD,
    SINGLE_USE,
    SPEED_RUN,
    ENERGY_CRISIS,
]


def get_difficulty(name: str) -> DifficultyLevel:
    """Get a difficulty level by name."""
    return next(difficulty for difficulty in DIFFICULTY_VARIANTS if difficulty.name == name)


def list_difficulties() -> None:
    """Print all available difficulty levels."""
    print("\nAvailable Difficulty Levels")
    print("=" * 80)
    for diff in DIFFICULTY_VARIANTS:
        print(f"\n{diff.name.upper()}: {diff.description}")
        print(f"  Solar override: {diff.solar_override}")


if __name__ == "__main__":
    list_difficulties()
