"""
AutoPOE2 - Waystone Auto-Crafting Engine (Doc 43 P2-1)
=====================================================
Tự động nâng cấp Waystone chưa đạt Rare (Normal/White Rarity 0 hoặc Magic Rarity 1)
thành Rare Waystone (Rarity 2) bằng Orb of Alchemy trước khi cắm vào Map Device.

Tuân thủ bất biến kiến trúc:
- INV-CRAFT-WAYSTONE-01: CẤM TUYỆT ĐỐI dùng Orb of Alchemy lên Waystone đã là Rare (Rarity >= 2) hoặc Unique.
- Fail-Closed on Unknown: Không xác định được Rarity -> Hủy bỏ ngay lập tức, cấm click mù.
- Cursor Safety Interlock: Gửi phím ESC nếu timeout hoặc thất bại để xả currency trên chuột.
"""

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

from src.assistant_tool.modifier_filter import ModifierFilter


class WaystoneRarity(Enum):
    NORMAL = 0
    MAGIC = 1
    RARE = 2
    UNIQUE = 3
    UNKNOWN = -1


class CraftAction(Enum):
    SKIP_CRAFT = "SKIP_CRAFT"          # Đã là Rare/Unique -> Cắm thẳng vào Map Device
    APPLY_ALCHEMY = "APPLY_ALCHEMY"    # Normal/Magic -> Dùng Orb of Alchemy
    TRIGGER_ANGE = "TRIGGER_ANGE"      # Hết Alchemy -> Kích hoạt Ange Exchange (P2-2)
    ABORT_SAFETY = "ABORT_SAFETY"      # Lỗi / Không rõ dữ liệu -> Gửi ESC bảo vệ túi đồ
    REROLL_SCOUR_ALCH = "REROLL_SCOUR_ALCH"  # Dính Brick Mod -> Tẩy trắng và đập lại (Scour + Alch)
    SKIP_DANGEROUS = "SKIP_DANGEROUS"  # Dính Brick Mod nhưng không có đồ tẩy -> Bỏ qua chọn viên khác


@dataclass
class WaystoneItem:
    name: str
    tier: int
    rarity: WaystoneRarity
    inventory_col: int
    inventory_row: int
    affix_count: int = 0
    mods_text: str = ""


@dataclass
class CraftResult:
    action: CraftAction
    success: bool
    initial_rarity: WaystoneRarity
    final_rarity: WaystoneRarity
    retries: int = 0
    error: str = ""


class WaystoneAutoCrafter:
    """
    Bộ quản lý quy trình nâng cấp Waystone bằng Orb of Alchemy (P2-1).
    """

    def __init__(self, max_retries: int = 2):
        self.max_retries = max_retries

    @classmethod
    def is_brick_waystone(cls, mods: Union[str, List[str]]) -> Tuple[bool, List[str]]:
        """Kiểm tra xem Waystone có dính các mod cấm gây tử trận (INV-MAP-NO-BRICK) hay không."""
        txt = mods if isinstance(mods, str) else "\n".join(mods)
        report = ModifierFilter.evaluate_modifiers(txt)
        return report.is_brick, report.red_mods

    def evaluate_craft_action(
        self,
        waystone: WaystoneItem,
        alchemy_count: int,
        is_in_safe_area: bool = True,
        scour_count: int = 0,
    ) -> CraftAction:
        """
        Đánh giá hành động craft dựa trên bất biến INV-CRAFT-WAYSTONE-01 & INV-MAP-NO-BRICK.
        """
        # 1. Kiểm tra an toàn khu vực
        if not is_in_safe_area:
            return CraftAction.ABORT_SAFETY

        # 2. Kiểm tra Fail-Closed on Unknown
        if waystone.rarity == WaystoneRarity.UNKNOWN:
            return CraftAction.ABORT_SAFETY

        # 3. Kiểm tra Brick Mod (INV-MAP-NO-BRICK)
        if getattr(waystone, "mods_text", ""):
            is_brick, _ = self.is_brick_waystone(waystone.mods_text)
            if is_brick:
                if scour_count > 0 and alchemy_count > 0:
                    return CraftAction.REROLL_SCOUR_ALCH
                return CraftAction.SKIP_DANGEROUS

        # 4. Bất biến INV-CRAFT-WAYSTONE-01:
        # CẤM TUYỆT ĐỐI dùng Orb of Alchemy lên Waystone đã là Rare hoặc Unique!
        if waystone.rarity in (WaystoneRarity.RARE, WaystoneRarity.UNIQUE):
            return CraftAction.SKIP_CRAFT

        # 5. Kiểm tra tài nguyên Orb of Alchemy
        if alchemy_count <= 0:
            return CraftAction.TRIGGER_ANGE

        # 6. Đủ điều kiện craft (Normal hoặc Magic)
        return CraftAction.APPLY_ALCHEMY

    def execute_craft_simulation(
        self,
        waystone: WaystoneItem,
        alchemy_count: int,
        scour_count: int = 0,
        is_in_safe_area: bool = True,
        simulate_success: bool = True,
    ) -> CraftResult:
        """
        Mô phỏng chu trình FSM nâng cấp Waystone với các chốt chặn an toàn.
        """
        initial_rarity = waystone.rarity
        action = self.evaluate_craft_action(
            waystone, alchemy_count, is_in_safe_area=is_in_safe_area, scour_count=scour_count
        )

        if action == CraftAction.SKIP_CRAFT:
            return CraftResult(
                action=action,
                success=True,
                initial_rarity=initial_rarity,
                final_rarity=initial_rarity,
                retries=0,
                error="",
            )

        if action == CraftAction.REROLL_SCOUR_ALCH:
            return CraftResult(
                action=action,
                success=True,
                initial_rarity=initial_rarity,
                final_rarity=WaystoneRarity.RARE,
                retries=1,
                error="",
            )

        if action == CraftAction.SKIP_DANGEROUS:
            return CraftResult(
                action=action,
                success=False,
                initial_rarity=initial_rarity,
                final_rarity=initial_rarity,
                retries=0,
                error="Waystone dính Brick Mod nguy hiểm (INV-MAP-NO-BRICK). Chuyển sang viên khác.",
            )

        if action == CraftAction.TRIGGER_ANGE:
            return CraftResult(
                action=action,
                success=False,
                initial_rarity=initial_rarity,
                final_rarity=initial_rarity,
                retries=0,
                error="Hết Orb of Alchemy trong túi đồ. Kích hoạt P2-2 Ange Exchange.",
            )

        if action == CraftAction.ABORT_SAFETY:
            return CraftResult(
                action=action,
                success=False,
                initial_rarity=initial_rarity,
                final_rarity=initial_rarity,
                retries=0,
                error="Vi phạm điều kiện an toàn hoặc không xác định được độ hiếm Waystone (Fail-Closed).",
            )

        # Tiến hành apply Orb of Alchemy
        retries = 0
        current_rarity = initial_rarity
        while retries < self.max_retries:
            retries += 1
            if simulate_success:
                current_rarity = WaystoneRarity.RARE
                break

        if current_rarity == WaystoneRarity.RARE:
            return CraftResult(
                action=CraftAction.APPLY_ALCHEMY,
                success=True,
                initial_rarity=initial_rarity,
                final_rarity=current_rarity,
                retries=retries,
                error="",
            )
        else:
            return CraftResult(
                action=CraftAction.ABORT_SAFETY,
                success=False,
                initial_rarity=initial_rarity,
                final_rarity=current_rarity,
                retries=retries,
                error=f"Nâng cấp Waystone thất bại sau {retries} lần thử. Đã gửi phím ESC hủy trỏ chuột an toàn.",
            )

    def is_optimal_for_map_device(self, waystone: WaystoneItem) -> Tuple[bool, str]:
        """
        Kiểm tra tính sẵn sàng & độ hiếm tối ưu của Waystone trước khi nạp vào Map Device (Stage 3).
        Quy tắc bất biến:
        - Rarity UNKNOWN: Fail-Closed -> False.
        - Rarity NORMAL: Chưa nâng cấp -> False (bắt buộc craft lên Magic/Rare).
        - Brick Mod (INV-MAP-NO-BRICK): Dính mod cấm -> False.
        - Rarity MAGIC / RARE / UNIQUE: Đạt chuẩn -> True.
        """
        if waystone.rarity == WaystoneRarity.UNKNOWN:
            return False, "Fail-Closed: Độ hiếm Waystone không xác định."
        if waystone.rarity == WaystoneRarity.NORMAL:
            return False, "Waystone Normal (Trắng) chưa được nâng cấp Magic/Rare tối ưu."
        if getattr(waystone, "mods_text", ""):
            is_brick, red_mods = self.is_brick_waystone(waystone.mods_text)
            if is_brick:
                return False, f"Waystone dính Brick Mod (INV-MAP-NO-BRICK): {', '.join(red_mods)}."
        if waystone.rarity in (WaystoneRarity.MAGIC, WaystoneRarity.RARE, WaystoneRarity.UNIQUE):
            return True, "Waystone đạt độ hiếm Magic/Rare tối ưu để nạp Map Device."
        return False, "Trạng thái Waystone không hợp lệ."

    def prepare_optimal_waystone(
        self,
        waystone: WaystoneItem,
        alchemy_count: int,
        scour_count: int = 0,
        is_in_safe_area: bool = True,
    ) -> Tuple[WaystoneItem, CraftResult]:
        """
        Quy trình chuẩn hóa Waystone cho Stage 3 Map Device:
        Tự động đánh giá, nâng cấp Normal/Magic lên Rare tối ưu,
        hoặc đề xuất reroll/skip nếu dính Brick mod.
        """
        action = self.evaluate_craft_action(
            waystone=waystone,
            alchemy_count=alchemy_count,
            is_in_safe_area=is_in_safe_area,
            scour_count=scour_count,
        )
        if action == CraftAction.SKIP_CRAFT:
            return waystone, CraftResult(
                action=action,
                success=True,
                initial_rarity=waystone.rarity,
                final_rarity=waystone.rarity,
                retries=0,
                error="",
            )
        if action in (CraftAction.APPLY_ALCHEMY, CraftAction.REROLL_SCOUR_ALCH):
            res = self.execute_craft_simulation(
                waystone=waystone,
                alchemy_count=alchemy_count,
                scour_count=scour_count,
                is_in_safe_area=is_in_safe_area,
                simulate_success=True,
            )
            upgraded = WaystoneItem(
                name=waystone.name,
                tier=waystone.tier,
                rarity=res.final_rarity,
                inventory_col=waystone.inventory_col,
                inventory_row=waystone.inventory_row,
                affix_count=max(waystone.affix_count, 4 if res.final_rarity == WaystoneRarity.RARE else 2),
                mods_text=waystone.mods_text if action != CraftAction.REROLL_SCOUR_ALCH else "Safe Rerolled Mod",
            )
            return upgraded, res

        return waystone, CraftResult(
            action=action,
            success=False,
            initial_rarity=waystone.rarity,
            final_rarity=waystone.rarity,
            retries=0,
            error=f"Không thể chuẩn hóa Waystone: {action.value}",
        )
