"""AutoPOE2 - Currency Exchange Models & Portfolio Schema (Doc 43 / Doc 68 / Doc 69).
====================================================================================
Định nghĩa cấu trúc dữ liệu cho Sàn Giao Dịch Ngoại Hối (Faustus Currency Exchange - Phím '/'):
- Phân tầng tháp tiền tệ (Tier 4 -> Tier 3 -> Tier 2 Chaos -> Tier 1 Divine -> Tier 0 Mirror).
- Cấu trúc đơn hàng (ExchangeOrder), định mức dự trữ an toàn và phí giao dịch Vàng (Gold Tax).

Tuân thủ nghiêm ngặt:
- Rule 1: Cold Path Tier 2 (Python 3.11).
- Rule 4: Module hóa, trần file < 500 dòng.
- Rule 7: Phím '/' mở Currency Exchange, Spacebar đóng panels.
- Bất biến: INV-EXCHANGE-GOLD-TAX, INV-EXCHANGE-RESERVE-SAFE, INV-EXCHANGE-SLIPPAGE-GUARD.
"""

from __future__ import annotations

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


class CurrencyTier(str, Enum):
    """Phân tầng tháp tài sản tích lũy trong Path of Exile 2."""
    TIER_0_APEX = "TIER_0_APEX"           # Mirror of Kalandra, Hinekora's Lock (Đỉnh cao tài sản)
    TIER_1_DIVINE = "TIER_1_DIVINE"       # Divine Orb (Chuẩn tích trữ giá trị cao)
    TIER_2_CHAOS = "TIER_2_CHAOS"         # Chaos Orb (Đơn vị thanh khoản cơ sở thị trường)
    TIER_3_CRAFTING = "TIER_3_CRAFTING"   # Exalted, Regal, Alchemy, Scouring, Annulment, Vaal, Gemcutter
    TIER_4_BASE = "TIER_4_BASE"           # Transmutation, Augmentation, Alteration, Chance, Essences, Runes


class ExchangeActionType(str, Enum):
    """Loại hành động giao dịch ngoại hối."""
    SELL_TO_CHAOS = "SELL_TO_CHAOS"                     # Bán currency phụ/thặng dư lấy Chaos Orb
    CONVERT_CHAOS_TO_DIVINE = "CONVERT_CHAOS_TO_DIVINE" # Gom Chaos Orb chuyển đổi sang Divine Orb
    CONVERT_DIVINE_TO_MIRROR = "CONVERT_DIVINE_TO_MIRROR" # Gom Divine Orb chuyển đổi sang Mirror of Kalandra


class ExchangeOrderStatus(str, Enum):
    """Trạng thái thực thi lệnh giao dịch."""
    PENDING = "PENDING"
    SUBMITTED = "SUBMITTED"
    COMPLETED = "COMPLETED"
    CANCELLED = "CANCELLED"
    REJECTED_LOW_RESERVE = "REJECTED_LOW_RESERVE"
    REJECTED_LOW_GOLD = "REJECTED_LOW_GOLD"
    REJECTED_SLIPPAGE = "REJECTED_SLIPPAGE"
    REJECTED_COOLDOWN = "REJECTED_COOLDOWN"
    CIRCUIT_BREAKER_ACTIVE = "CIRCUIT_BREAKER_ACTIVE"
    UNSAFE_AREA = "UNSAFE_AREA"


@dataclass
class CurrencyItem:
    """Mô tả một loại tiền tệ trong kho tài sản."""
    name: str
    tier: CurrencyTier
    quantity_owned: int = 0
    min_reserve: int = 0                  # Số lượng tối thiểu bắt buộc giữ lại (bất biến sinh tồn)
    market_chaos_value: float = 1.0       # Tỷ giá thị trường quy đổi ra Chaos Orb từ POE2 Scout API
    gold_tax_per_unit: int = 50           # Phí giao dịch vàng dự tính cho mỗi đơn vị giao dịch

    @property
    def tradable_surplus(self) -> int:
        """Lượng tiền tệ thặng dư có thể đem giao dịch trên sàn."""
        return max(0, self.quantity_owned - self.min_reserve)

    @property
    def total_chaos_value(self) -> float:
        """Tổng giá trị tài sản quy đổi sang Chaos Orb."""
        return round(self.quantity_owned * self.market_chaos_value, 2)


@dataclass
class ExchangeOrder:
    """Chi tiết một lệnh giao dịch trên sàn Currency Exchange."""
    order_id: str
    action_type: ExchangeActionType
    sell_currency: str
    sell_amount: int
    buy_currency: str
    expected_buy_amount: int
    market_rate: float                    # Tỷ lệ quy đổi buy/sell
    estimated_gold_tax: int               # Tổng phí Vàng (Gold Tax) cần nộp
    status: ExchangeOrderStatus = ExchangeOrderStatus.PENDING
    reason: str = ""


@dataclass
class ExchangePortfolioConfig:
    """Cấu hình an toàn và các định mức dự trữ cho danh mục tiền tệ."""
    min_gold_reserve: int = 5000          # Ngưỡng sàn bảo vệ Vàng (INV-EXCHANGE-GOLD-TAX)
    min_chaos_reserve: int = 50           # Giữ lại 50 Chaos để mua đồ / reroll map
    min_divine_reserve: int = 2           # Giữ lại 2 Divine dự trữ thanh khoản
    max_slippage_pct: float = 10.0        # Trượt giá tối đa cho phép so với POE2 Scout (10%)
    cooldown_ms: int = 300000             # Giãn cách tối thiểu giữa 2 phiên sàn (5 phút = 300,000ms)
    circuit_breaker_timeout_ms: int = 600000 # Khóa sàn 10 phút nếu thất bại 2 lần liên tiếp
    max_consecutive_failures: int = 2
    # Bất biến định mức dự trữ currency sinh tồn & craft map (INV-EXCHANGE-RESERVE-SAFE)
    default_reserves: Dict[str, int] = field(default_factory=lambda: {
        "Orb of Alchemy": 20,
        "Orb of Scouring": 20,
        "Chaos Orb": 50,
        "Divine Orb": 2,
        "Mirror of Kalandra": 0,
        "Exalted Orb": 5,
        "Regal Orb": 10,
        "Vaul Orb": 10,
        "Gemcutter's Prism": 5,
        "Greater Jeweller's Orb": 10,
        "Waystone": 5,
    })
