"""AutoPOE2 - Real-Time Net Worth Estimator (Doc 68 / Doc 69 / Doc 70).
======================================================================
Định giá tổng tài sản kho đồ (Stash) và ví (Wallet) của nhân vật thời gian thực:
- Quy đổi toàn bộ currency phụ, ngọc (Gems), nguyên liệu chế tác (Essences, Runes, Catalysts, Splinters)
  ra Chaos Orb và Divine Orb dựa trên tỷ giá POE2 Scout API.
- Cung cấp báo cáo bảng tổng hợp tài sản ròng sau mỗi map (Net Worth Breakdown).

Tuân thủ nghiêm ngặt:
- Rule 1: Cold Path Tier 2 (Python 3.11).
- Rule 4: Module hóa độc lập, trần file < 500 dòng.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime
from typing import Any, Dict, List, Optional, Tuple


@dataclass
class NetWorthCategory:
    """Phân nhóm giá trị tài sản theo danh mục vật phẩm."""
    category_name: str
    total_items: int
    total_chaos_value: float
    items: Dict[str, Dict[str, Any]] = field(default_factory=dict)


@dataclass
class NetWorthReport:
    """Báo cáo tổng hợp tài sản ròng của nhân vật."""
    timestamp: str
    total_net_worth_chaos: float
    total_net_worth_divine: float
    liquid_chaos: int
    liquid_divine: int
    liquid_mirror: int
    gold_balance: int
    categories: Dict[str, NetWorthCategory]
    divine_price_in_chaos: float = 145.0
    mirror_price_in_divine: float = 450.0

    def format_ascii_summary(self) -> str:
        """Định dạng chuỗi bảng tổng hợp ASCII an toàn cho console."""
        lines = [
            "--------------------------------------------------------",
            "             CHARACTER NET WORTH BREAKDOWN",
            "--------------------------------------------------------",
            f" Total Net Worth : {self.total_net_worth_chaos:,.1f} Chaos (~{self.total_net_worth_divine:.2f} Divine)",
            f" Liquid Assets   : {self.liquid_chaos} Chaos | {self.liquid_divine} Divine | {self.liquid_mirror} Mirror",
            f" Gold Reserve    : {self.gold_balance:,} Gold",
            "--------------------------------------------------------",
            " Category Valuation (in Chaos):",
        ]
        for cat_name, cat in sorted(self.categories.items(), key=lambda x: x[1].total_chaos_value, reverse=True):
            if cat.total_chaos_value > 0 or cat.total_items > 0:
                lines.append(f"  * {cat_name:<20}: {cat.total_chaos_value:>9.1f} C  ({cat.total_items} items)")
        lines.append("--------------------------------------------------------")
        return "\n".join(lines)

    def format_markdown_table(self) -> str:
        """Định dạng bảng Markdown chuẩn cho tài liệu kỹ thuật."""
        md = [
            "| Danh Mục Tài Sản | Số Lượng Item | Giá Trị Quy Đổi (Chaos) | Tỷ Trọng (%) |",
            "|---|:---:|:---:|:---:|",
        ]
        for cat_name, cat in sorted(self.categories.items(), key=lambda x: x[1].total_chaos_value, reverse=True):
            pct = (cat.total_chaos_value / max(1.0, self.total_net_worth_chaos)) * 100.0
            md.append(f"| **{cat_name}** | {cat.total_items} | {cat.total_chaos_value:,.1f} Chaos | {pct:.1f}% |")

        md.append(f"| **TỔNG CỘNG TÀI SẢN** | - | **{self.total_net_worth_chaos:,.1f} Chaos** (~**{self.total_net_worth_divine:.2f} Divine**) | **100.0%** |")
        return "\n".join(md)


class NetWorthEstimator:
    """Bộ ước lượng và tổng hợp tài sản ròng thời gian thực."""

    def __init__(self, default_prices_in_chaos: Optional[Dict[str, float]] = None):
        # Bảng giá chuẩn mặc định nếu chưa tải được từ POE2 Scout
        self.market_prices: Dict[str, float] = default_prices_in_chaos or {
            "Chaos Orb": 1.0,
            "Divine Orb": 145.0,
            "Mirror of Kalandra": 65250.0,
            "Exalted Orb": 12.5,
            "Regal Orb": 1.2,
            "Orb of Alchemy": 0.5,
            "Orb of Scouring": 0.8,
            "Vaul Orb": 1.5,
            "Orb of Annulment": 4.0,
            "Gemcutter's Prism": 3.0,
            "Greater Jeweller's Orb": 2.5,
            "Perfect Jeweller's Orb": 35.0,
            "Orb of Transmutation": 0.05,
            "Orb of Alteration": 0.15,
            "Orb of Augmentation": 0.05,
        }

    def classify_item_category(self, item_name: str) -> str:
        """Phân loại danh mục vật phẩm để thống kê tỷ trọng tài sản."""
        lower = item_name.lower()
        if any(w in lower for w in ("divine", "chaos", "mirror", "exalted")):
            return "High Currency"
        if any(w in lower for w in ("alchemy", "scouring", "regal", "vaal", "annul", "transmutation", "alteration")):
            return "Crafting Currency"
        if any(w in lower for w in ("essence", "rune", "catalyst", "splinter", "shard")):
            return "Materials & Runes"
        if any(w in lower for w in ("gem", "uncut")):
            return "Skill Gems"
        if any(w in lower for w in ("waystone", "tablet")):
            return "Endgame Maps"
        return "Miscellaneous"

    def calculate_net_worth(
        self,
        wallet: Dict[str, int],
        stash_items: Optional[List[Dict[str, Any]]] = None,
        current_gold: int = 0,
        dynamic_prices: Optional[Dict[str, float]] = None,
    ) -> NetWorthReport:
        """
        Tính toán tài sản ròng toàn diện từ số dư ví và kho đồ.
        """
        prices = dict(self.market_prices)
        if dynamic_prices:
            prices.update(dynamic_prices)

        categories: Dict[str, NetWorthCategory] = {
            "High Currency": NetWorthCategory("High Currency", 0, 0.0),
            "Crafting Currency": NetWorthCategory("Crafting Currency", 0, 0.0),
            "Materials & Runes": NetWorthCategory("Materials & Runes", 0, 0.0),
            "Skill Gems": NetWorthCategory("Skill Gems", 0, 0.0),
            "Endgame Maps": NetWorthCategory("Endgame Maps", 0, 0.0),
            "Miscellaneous": NetWorthCategory("Miscellaneous", 0, 0.0),
        }

        # 1. Quét tài sản trong ví (Wallet)
        for name, count in wallet.items():
            if count <= 0:
                continue
            cat_name = self.classify_item_category(name)
            unit_price = prices.get(name, 0.0)
            total_val = round(count * unit_price, 2)

            cat = categories[cat_name]
            cat.total_items += count
            cat.total_chaos_value += total_val
            cat.items[name] = {
                "count": count,
                "unit_chaos": unit_price,
                "total_chaos": total_val,
                "location": "Wallet",
            }

        # 2. Quét tài sản trong Hòm đồ (Stash) nếu có dữ liệu
        if stash_items:
            for item in stash_items:
                name = item.get("name", "Unknown")
                count = int(item.get("count", 1))
                if count <= 0:
                    continue

                cat_name = self.classify_item_category(name)
                unit_price = prices.get(name, float(item.get("chaos_value", 0.0)))
                total_val = round(count * unit_price, 2)

                cat = categories[cat_name]
                cat.total_items += count
                cat.total_chaos_value += total_val
                if name in cat.items:
                    cat.items[name]["count"] += count
                    cat.items[name]["total_chaos"] += total_val
                else:
                    cat.items[name] = {
                        "count": count,
                        "unit_chaos": unit_price,
                        "total_chaos": total_val,
                        "location": "Stash",
                    }

        # Làm tròn giá trị từng category
        for cat in categories.values():
            cat.total_chaos_value = round(cat.total_chaos_value, 2)

        total_chaos = sum(c.total_chaos_value for c in categories.values())
        divine_rate = prices.get("Divine Orb", 145.0)
        total_divine = round(total_chaos / divine_rate, 2) if divine_rate > 0 else 0.0

        mirror_rate_divine = 450.0
        if "Mirror of Kalandra" in prices and divine_rate > 0:
            mirror_rate_divine = round(prices["Mirror of Kalandra"] / divine_rate, 1)

        return NetWorthReport(
            timestamp=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            total_net_worth_chaos=round(total_chaos, 2),
            total_net_worth_divine=total_divine,
            liquid_chaos=int(wallet.get("Chaos Orb", 0)),
            liquid_divine=int(wallet.get("Divine Orb", 0)),
            liquid_mirror=int(wallet.get("Mirror of Kalandra", 0)),
            gold_balance=current_gold,
            categories=categories,
            divine_price_in_chaos=divine_rate,
            mirror_price_in_divine=mirror_rate_divine,
        )
