"""
英雄定义 —— 属性 & 技能数据
所有距离单位为像素（世界坐标 4000×3000）
所有速度单位为像素/tick（20 tick/s 基准，运行时由 _TICK_SCALE 缩放）
"""
from __future__ import annotations

import math
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional


# ─── 枚举 ─────────────────────────────────────────────────
class DamageType(str, Enum):
    PHYSICAL = "physical"
    MAGICAL  = "magical"


class SkillTargetType(str, Enum):
    NONE       = "none"        # 无需指定方向（自身周围）
    DIRECTION  = "direction"   # 指定方向（鼠标朝向）
    POSITION   = "position"    # 指定位置（鼠标点击）


# ─── 数据类 ────────────────────────────────────────────────
class AttackType(str, Enum):
    FAN      = "fan"         # 扇形近战（红夫人）
    TARGETED = "targeted"    # 指向最近敌人发射弹丸


@dataclass(frozen=True)
class HeroStats:
    hp: int
    physical_attack: int
    magical_attack: int
    physical_defense: int
    magical_defense: int
    speed: float              # 像素/tick
    attack_range: float       # 普攻范围（像素）
    attack_angle: float       # 普攻扇形半角（弧度）
    attack_cd: float          # 普攻冷却（秒）
    attack_type: AttackType = AttackType.FAN


@dataclass(frozen=True)
class SkillDef:
    id: str                   # e.g. "red_lady_f"
    name: str
    key: str                  # "f" / "r" / "e"
    target_type: SkillTargetType
    cooldown: float           # 冷却时间（秒）
    description: str


@dataclass(frozen=True)
class HeroDef:
    id: str
    name: str
    title: str
    color: str                # 主题色 hex
    stats: HeroStats
    skills: tuple[SkillDef, SkillDef, SkillDef]

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "name": self.name,
            "title": self.title,
            "color": self.color,
            "stats": {
                "hp": self.stats.hp,
                "physical_attack": self.stats.physical_attack,
                "magical_attack": self.stats.magical_attack,
                "physical_defense": self.stats.physical_defense,
                "magical_defense": self.stats.magical_defense,
                "speed": self.stats.speed,
                "attack_range": self.stats.attack_range,
                "attack_type": self.stats.attack_type.value,
            },
            "skills": [
                {
                    "id": s.id,
                    "name": s.name,
                    "key": s.key,
                    "target_type": s.target_type.value,
                    "cooldown": s.cooldown,
                    "description": s.description,
                }
                for s in self.skills
            ],
        }


# ═══════════════════════════════════════════════════════════
# 英雄注册表
# ═══════════════════════════════════════════════════════════

RED_LADY = HeroDef(
    id="red_lady",
    name="红夫人",
    title="镜花水月",
    color="#c0392b",
    stats=HeroStats(
        hp=3000,
        physical_attack=200,
        magical_attack=0,
        physical_defense=100,
        magical_defense=100,
        speed=8.0,           # 像素/tick（20tick/s → 160px/s）
        attack_range=160.0,   # 普攻范围（像素）
        attack_angle=math.pi / 3,  # 60° 扇形半角 → 120° 扇形
        attack_cd=0.8,        # 普攻间隔 0.8 秒
    ),
    skills=(
        SkillDef(
            id="red_lady_f",
            name="水镜",
            key="f",
            target_type=SkillTargetType.POSITION,
            cooldown=10.0,
            description="在指定位置放置水镜，创生出一个会模仿自身的镜像。水镜最多持续14秒，再次使用技能可以使其提前消失。",
        ),
        SkillDef(
            id="red_lady_e",
            name="旋舞",
            key="e",
            target_type=SkillTargetType.NONE,
            cooldown=0.0,
            description="对周围敌人造成（120%物攻）物理伤害，0.5秒后与镜像交换位置。存在自己的水镜时才能使用，每面水镜最多使用一次。",
        ),
        SkillDef(
            id="red_lady_r",
            name="碎裂镜片",
            key="r",
            target_type=SkillTargetType.DIRECTION,
            cooldown=6.0,
            description="向指定方向扇形发射3片碎裂镜片。中间镜片造成（100%物攻）物理伤害，两侧各造成（70%物攻）物理伤害。",
        ),
    ),
)

SOUL_WEAVER = HeroDef(
    id="soul_weaver",
    name="缀魂者",
    title="灵能操纵",
    color="#8e44ad",
    stats=HeroStats(
        hp=2500,
        physical_attack=180,
        magical_attack=200,
        physical_defense=80,
        magical_defense=120,
        speed=9.0,            # 像素/tick（20tick/s → 180px/s）
        attack_range=500.0,   # 能量球最大飞行距离（像素）
        attack_angle=0.0,     # targeted 类型不用角度
        attack_cd=0.6,        # 普攻间隔 0.6 秒
        attack_type=AttackType.TARGETED,
    ),
    skills=(
        SkillDef(
            id="soul_weaver_f",
            name="灵能灌注",
            key="f",
            target_type=SkillTargetType.NONE,
            cooldown=8.0,
            description="强化5s内所有普攻：射程提升20%并获得追踪效果，命中后额外造成（140%法攻）法术伤害。",
        ),
        SkillDef(
            id="soul_weaver_e",
            name="缚魂印",
            key="e",
            target_type=SkillTargetType.NONE,
            cooldown=8.0,
            description="强化5s内下一次普攻：命中后造成1.5秒定身。",
        ),
        SkillDef(
            id="soul_weaver_r",
            name="裂魂弹幕",
            key="r",
            target_type=SkillTargetType.NONE,
            cooldown=8.0,
            description="强化5s内下一次普攻：普攻后额外发射4个小能量球，造成主能量球25%的伤害和定身时长。",
        ),
    ),
)

HERO_REGISTRY: dict[str, HeroDef] = {
    RED_LADY.id: RED_LADY,
    SOUL_WEAVER.id: SOUL_WEAVER,
}

DEFAULT_HERO_ID = RED_LADY.id


def get_hero(hero_id: str) -> Optional[HeroDef]:
    return HERO_REGISTRY.get(hero_id)


def list_heroes() -> list[dict]:
    return [h.to_dict() for h in HERO_REGISTRY.values()]
