"""Thư viện dùng chung định nghĩa cấu trúc dữ liệu vật phẩm (Item Data Models) cho AutoPOE2.

Cung cấp các lớp enum và dataclass đại diện cho vật phẩm, độ hiếm (Rarity)
và các thuộc tính bổ trợ (Affixes), đóng vai trò Hợp đồng dữ liệu duy nhất (Single Source of Truth)
kết nối các phân hệ Pickit Filter, Item Inspector và Tooltip Overlay.
Tuân thủ nghiêm ngặt chuẩn tài liệu Google Docstrings theo Rule 16.
"""

from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Dict, List, Optional


class ItemRarity(Enum):
    """Độ hiếm tiêu chuẩn của vật phẩm trong Path of Exile 2."""

    NORMAL = "NORMAL"
    MAGIC = "MAGIC"
    RARE = "RARE"
    UNIQUE = "UNIQUE"


class Poe2ItemCategory(str, Enum):
    """Phân loại danh mục vật phẩm đặc trưng trong Path of Exile 2 (Doc 63 SSoT)."""

    GOLD = "Gold"
    CURRENCY = "Currency"
    WAYSTONE = "Waystone"
    PRECURSOR_TABLET = "Precursor Tablet"
    UNCUT_SKILL_GEM = "Uncut Skill Gem"
    UNCUT_SUPPORT_GEM = "Uncut Support Gem"
    UNCUT_SPIRIT_GEM = "Uncut Spirit Gem"
    RUNE = "Rune"
    SOUL_CORE = "Soul Core"
    CHARM = "Charm"
    EQUIPMENT = "Equipment"
    UNKNOWN = "Unknown"


def classify_poe2_category(name: str, item_class: str = "") -> Poe2ItemCategory:
    """Phân loại danh mục vật phẩm POE2 dựa trên tên hoặc class chuỗi."""
    lower = name.lower()
    class_lower = item_class.lower()

    if "gold" in lower:
        return Poe2ItemCategory.GOLD
    if "waystone" in lower or "waystone" in class_lower:
        return Poe2ItemCategory.WAYSTONE
    if "tablet" in lower or "tablet" in class_lower:
        return Poe2ItemCategory.PRECURSOR_TABLET
    if "uncut skill" in lower:
        return Poe2ItemCategory.UNCUT_SKILL_GEM
    if "uncut support" in lower:
        return Poe2ItemCategory.UNCUT_SUPPORT_GEM
    if "uncut spirit" in lower:
        return Poe2ItemCategory.UNCUT_SPIRIT_GEM
    if "soul core" in lower:
        return Poe2ItemCategory.SOUL_CORE
    if "rune" in lower:
        return Poe2ItemCategory.RUNE
    if "charm" in lower:
        return Poe2ItemCategory.CHARM
    if any(k in lower for k in ("armour", "cuirass", "plate", "garb", "robe", "doublet", "vest", "boots", "gloves", "helmet", "shield", "staff", "bow", "sword", "axe", "mace", "quarterstaff", "crossbow", "fists", "ring", "amulet", "belt")):
        return Poe2ItemCategory.EQUIPMENT
    if any(k in lower for k in ("orb", "scroll", "shard", "bauble", "prism", "scrap", "whetstone", "mirror", "divine", "exalt", "annul", "omen", "distilled", "essence")):
        return Poe2ItemCategory.CURRENCY
    return Poe2ItemCategory.UNKNOWN


class AffixType(Enum):
    """Phân loại vị trí của dòng thuộc tính trên trang bị."""

    PREFIX = "PREFIX"
    SUFFIX = "SUFFIX"
    IMPLICIT = "IMPLICIT"
    UNKNOWN = "UNKNOWN"


@dataclass
class AffixData:
    """Dữ liệu chi tiết về một dòng thuộc tính bổ trợ (Mod / Affix) trên vật phẩm.

    Attributes:
        text: Chuỗi văn bản hiển thị nguyên gốc của thuộc tính (ví dụ: '+42 to maximum Life').
        affix_type: Loại thuộc tính (PREFIX, SUFFIX, IMPLICIT, UNKNOWN).
        tier: Bậc của thuộc tính nếu được game công bố qua phím Alt (T1, T2, ...), hoặc None.
        name: Tên danh xưng của mod (ví dụ: 'Athlete\'s', 'of the Rainbow').
        category: Nhóm phân loại nghiệp vụ (ví dụ: 'life', 'elemental_res', 'phys_dmg').
        values: Danh sách các giá trị số bóc tách được từ dòng chữ.
        is_crafted: True nếu là dòng được thêm vào từ bàn chế tạo (Crafting Bench).
        is_fractured: True nếu là dòng thuộc tính cố định không thể tẩy (Fractured Mod).
    """

    text: str
    affix_type: AffixType = AffixType.UNKNOWN
    tier: Optional[int] = None
    name: str = ""
    category: str = ""
    values: List[float] = field(default_factory=list)
    is_crafted: bool = False
    is_fractured: bool = False


@dataclass
class ItemData:
    """Mô hình dữ liệu hoàn chỉnh của một vật phẩm trong hệ thống AutoPOE2.

    Được sử dụng xuyên suốt bởi các phân hệ Sàng lọc nhặt đồ (Pickit), Đánh giá chuyên sâu (Inspector)
    và Hiển thị hỗ trợ trực quan (Tooltip Overlay HUD).

    Attributes:
        name: Tên riêng của vật phẩm (thường có trên đồ Rare / Unique).
        base_type: Phôi cơ sở của vật phẩm (ví dụ: 'Expert Vaal Cuirass', 'Spiked Fists').
        item_class: Phân loại danh mục game (ví dụ: 'Body Armours', 'Gloves', 'Waystones').
        rarity: Độ hiếm của vật phẩm (NORMAL, MAGIC, RARE, UNIQUE).
        item_level: Cấp độ vật phẩm (iLvl).
        quality: Chỉ số chất lượng (+0% đến +20%).
        identified: True nếu vật phẩm đã được giám định, False nếu còn Unidentified.
        sockets: Số lượng lỗ ngọc trên trang bị.
        open_prefixes: Số lượng vị trí Prefix còn trống có thể chế thêm.
        open_suffixes: Số lượng vị trí Suffix còn trống có thể chế thêm.
        max_prefixes: Giới hạn Prefix tối đa cho loại phôi này (mặc định 3 cho đồ Rare).
        max_suffixes: Giới hạn Suffix tối đa cho loại phôi này (mặc định 3 cho đồ Rare).
        implicits: Danh sách các dòng thuộc tính ẩn mặc định (Implicit Mods).
        explicits: Danh sách các dòng thuộc tính mở rộng (Explicit Mods).
        properties: Bản đồ lưu trữ các chỉ số thuộc tính cơ sở (Armour, Evasion, Physical Damage, v.v.).
        raw_text: Toàn bộ văn bản thô đọc từ clipboard khi nhấn Ctrl+C vào vật phẩm in-game.

    Example:
        >>> item = ItemData(base_type="Expert Vaal Cuirass", rarity=ItemRarity.RARE, item_level=82)
        >>> print(f"Đồ: {item.base_type}, Rare={item.is_rare}")
    """

    name: str = ""
    base_type: str = ""
    item_class: str = ""
    rarity: ItemRarity = ItemRarity.NORMAL
    item_level: int = 0
    quality: int = 0
    identified: bool = True
    sockets: int = 0
    open_prefixes: int = 0
    open_suffixes: int = 0
    max_prefixes: int = 3
    max_suffixes: int = 3
    implicits: List[AffixData] = field(default_factory=list)
    explicits: List[AffixData] = field(default_factory=list)
    properties: Dict[str, Any] = field(default_factory=dict)
    raw_text: str = ""

    @property
    def is_normal(self) -> bool:
        """Kiểm tra vật phẩm có phải là đồ trắng (Normal) hay không."""
        return self.rarity == ItemRarity.NORMAL

    @property
    def is_magic(self) -> bool:
        """Kiểm tra vật phẩm có phải là đồ xanh (Magic) hay không."""
        return self.rarity == ItemRarity.MAGIC

    @property
    def is_rare(self) -> bool:
        """Kiểm tra vật phẩm có phải là đồ vàng (Rare) hay không."""
        return self.rarity == ItemRarity.RARE

    @property
    def is_unique(self) -> bool:
        """Kiểm tra vật phẩm có phải là đồ cam (Unique) hay không."""
        return self.rarity == ItemRarity.UNIQUE

    @property
    def total_affixes_count(self) -> int:
        """Tổng số dòng thuộc tính explicit hiện có trên trang bị."""
        return len(self.explicits)
