"""
Game Design Matrix Types & DTOs for FreeExile.
Defines structured immutable dataclasses for cross-cutting entities:
Story Acts, Zones, NPCs, Quests, Monsters, Weapons, Skills, and Progression Benchmarks.
Adheres to strict Clean Architecture and Zero-Drift Engineering Directives.
"""

from __future__ import annotations
from dataclasses import dataclass, field
from enum import Enum
from typing import Dict, List, Optional, Any, Set, Tuple


class CrossRelationType(str, Enum):
    """Categorization of cross-cutting systemic relationships."""
    ACT_CONTAINS_ZONE = "ACT_CONTAINS_ZONE"
    ZONE_HOUSES_NPC = "ZONE_HOUSES_NPC"
    NPC_OFFERS_QUEST = "NPC_OFFERS_QUEST"
    QUEST_TARGETS_MONSTER = "QUEST_TARGETS_MONSTER"
    QUEST_UNLOCKS_ZONE = "QUEST_UNLOCKS_ZONE"
    QUEST_REWARDS_ITEM = "QUEST_REWARDS_ITEM"
    BOSS_CLIMAX_FOR_ACT = "BOSS_CLIMAX_FOR_ACT"
    SKILL_REQUIRES_WEAPON = "SKILL_REQUIRES_WEAPON"
    AFFIX_ALLOWED_IN_SLOT = "AFFIX_ALLOWED_IN_SLOT"


@dataclass(slots=True, frozen=True)
class StoryActRow:
    """Story act record in central design database."""
    act_id: str
    act_order: int
    title: str
    subtitle: str
    level_min: int
    level_max: int
    primary_zone_id: str
    climax_boss_id: str
    climax_boss_name: str
    description: str


@dataclass(slots=True, frozen=True)
class ZoneRow:
    """Zone record in central design database."""
    zone_id: str
    act_id: str
    name: str
    zone_type: str
    environment: str
    min_level: int
    max_level: int
    bounds_width: float
    bounds_height: float
    default_spawn_x: float
    default_spawn_y: float


@dataclass(slots=True, frozen=True)
class NpcRow:
    """NPC record in central design database."""
    npc_id: str
    name: str
    title: str
    role: str
    zone_id: str
    x: float
    y: float
    dialogue_tree_id: str


@dataclass(slots=True, frozen=True)
class MonsterArchetypeRow:
    """Monster genus and archetype record."""
    archetype_id: str
    genus: str
    sub_species_code: str
    name: str
    base_hp: float
    base_dmg: float
    base_scale: float
    native_element: str
    min_level: int


@dataclass(slots=True, frozen=True)
class QuestRow:
    """Quest record with strict prerequisites and rewards."""
    quest_id: str
    act_id: str
    title: str
    quest_type: str
    required_level: int
    zone_id: Optional[str]
    prerequisite_quest_id: Optional[str]
    target_monster_id: Optional[str]
    target_count: int
    reward_exp: int
    reward_meridian_points: int
    reward_title: Optional[str]
    reward_items_json: str


@dataclass(slots=True, frozen=True)
class WeaponBaseRow:
    """Base weapon catalog record."""
    weapon_id: str
    name_vi: str
    name_en: str
    weapon_class: str
    weapon_category: str
    grip_style: str
    sect: str
    clan: str
    element: str
    required_level: int
    base_dmg_min: float
    base_dmg_max: float
    attack_speed: float
    crit_chance: float


@dataclass(slots=True, frozen=True)
class SkillRow:
    """Canonical active martial skill record."""
    skill_id: int
    skill_name: str
    element: str
    sect: str
    weapon_requirement: str
    base_damage: float
    energy_cost: int
    cooldown_ms: int
    combo_role: str
    tags_json: str


@dataclass(slots=True, frozen=True)
class AffixTierRow:
    """15-tier affix record with drop weight and ilvl gating."""
    mod_id: str
    name: str
    affix_type: str
    tier: int
    required_ilvl: int
    min_value: float
    max_value: float
    weight: int
    allowed_slots_json: str


@dataclass(slots=True, frozen=True)
class ProgressionBenchmarkRow:
    """Mathematical progression milestone per level."""
    level: int
    target_exp: int
    exp_to_next_level: int
    cumulative_exp: int
    player_base_hp: float
    player_benchmark_dps: float
    monster_base_hp: float
    monster_base_dps: float
    max_affix_tier_allowed: int
    death_penalty_ratio: float = 0.0
    level_gap_safe_range: int = 5
    level_gap_penalty_exp: float = 0.60
    monster_benchmark_exp: int = 25


@dataclass(slots=True, frozen=True)
class CrossRelationRow:
    """Direct cross-cutting link between two entities."""
    relation_id: str
    source_type: str
    source_id: str
    relation_type: CrossRelationType
    target_type: str
    target_id: str
    metadata_json: str = "{}"


@dataclass(slots=True, frozen=True)
class DesignIntegrityReport:
    """Automated validation report verifying zero cross-cutting drift."""
    is_valid: bool
    total_acts: int
    total_zones: int
    total_npcs: int
    total_quests: int
    total_monsters: int
    total_skills: int
    total_weapons: int
    total_affixes: int
    total_relations: int
    violations: Tuple[str, ...] = ()
    warnings: Tuple[str, ...] = ()
