"""
AutoPOE2 - Static Game Data & Wiki Synchronizer
Fallback: tải JSON RePoE khi chưa extract được Content.ggpk.
Nguồn ưu tiên: python tools/extract_ggpk_to_db.py (poe2_ggpk.db).
"""

import json
import sqlite3
import sys
from pathlib import Path

import requests

if hasattr(sys.stdout, "reconfigure"):
    sys.stdout.reconfigure(encoding="utf-8")
if hasattr(sys.stderr, "reconfigure"):
    sys.stderr.reconfigure(encoding="utf-8")

# Cấu hình đường dẫn
BASE_DIR = Path(__file__).resolve().parent.parent
ASSETS_DIR = BASE_DIR / "assets" / "game_data"
DB_PATH = ASSETS_DIR / "poe2_wiki.db"

REPOE_BASE_URL = "https://repoe-fork.github.io/poe2"
TARGET_FILES = [
    "base_items.min.json",
    "world_areas.min.json",
    "skill_gems.min.json",
    "item_classes.min.json",
    "uniques.min.json",
    "default_monster_stats.min.json"
]

def download_file(filename: str, target_dir: Path) -> Path:
    url = f"{REPOE_BASE_URL}/{filename}"
    out_path = target_dir / filename
    print(f"[Sync] Đang tải {filename} từ {url}...")
    resp = requests.get(url, timeout=30)
    resp.raise_for_status()
    with open(out_path, "wb") as f:
        f.write(resp.content)
    print(f"  -> Lưu thành công {filename} ({len(resp.content) / 1024:.1f} KB)")
    return out_path

def build_sqlite_database():
    print(f"\n[SQLite] Khởi tạo cơ sở dữ liệu: {DB_PATH}...")
    if DB_PATH.exists():
        try:
            DB_PATH.unlink()
        except Exception:
            pass

    conn = sqlite3.connect(str(DB_PATH))
    cursor = conn.cursor()

    # 1. Bảng base_items
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS base_items (
            id TEXT PRIMARY KEY,
            name TEXT NOT NULL,
            name_lower TEXT NOT NULL,
            item_class TEXT,
            width INTEGER DEFAULT 1,
            height INTEGER DEFAULT 1,
            drop_level INTEGER DEFAULT 1,
            stack_size INTEGER DEFAULT 1,
            is_currency INTEGER DEFAULT 0
        )
    """)
    cursor.execute("CREATE INDEX IF NOT EXISTS idx_base_items_name_lower ON base_items (name_lower);")
    cursor.execute("CREATE INDEX IF NOT EXISTS idx_base_items_class ON base_items (item_class);")

    # 2. Bảng world_areas
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS world_areas (
            id TEXT PRIMARY KEY,
            name TEXT NOT NULL,
            name_lower TEXT NOT NULL,
            act INTEGER DEFAULT 1,
            area_level INTEGER DEFAULT 0,
            has_waypoint INTEGER DEFAULT 0,
            is_town INTEGER DEFAULT 0,
            connections TEXT
        )
    """)
    cursor.execute("CREATE INDEX IF NOT EXISTS idx_world_areas_name_lower ON world_areas (name_lower);")

    # 3. Bảng skill_gems
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS skill_gems (
            id TEXT PRIMARY KEY,
            base_item_id TEXT,
            str_req INTEGER DEFAULT 0,
            dex_req INTEGER DEFAULT 0,
            int_req INTEGER DEFAULT 0
        )
    """)

    # 4. Bảng uniques
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS uniques (
            id TEXT PRIMARY KEY,
            name TEXT NOT NULL,
            name_lower TEXT NOT NULL,
            base_item TEXT
        )
    """)
    cursor.execute("CREATE INDEX IF NOT EXISTS idx_uniques_name_lower ON uniques (name_lower);")

    # Nạp base_items
    base_items_file = ASSETS_DIR / "base_items.min.json"
    if base_items_file.exists():
        with open(base_items_file, "r", encoding="utf-8") as f:
            items_data = json.load(f)

        insert_items = []
        for item_id, info in items_data.items():
            name = info.get("name", "")
            if not name:
                continue
            item_class = info.get("item_class", "")
            width = info.get("inventory_width", 1)
            height = info.get("inventory_height", 1)
            drop_level = info.get("drop_level", 1)
            props = info.get("properties", {}) or {}
            stack_size = props.get("stack_size", 1)
            tags = info.get("tags", []) or []
            is_currency = 1 if ("currency" in tags or item_class == "StackableCurrency") else 0

            insert_items.append((
                item_id,
                name,
                name.lower(),
                item_class,
                width,
                height,
                drop_level,
                stack_size,
                is_currency
            ))

        cursor.executemany("""
            INSERT OR REPLACE INTO base_items (id, name, name_lower, item_class, width, height, drop_level, stack_size, is_currency)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
        """, insert_items)
        print(f"  -> Đã nạp {len(insert_items)} BaseItemTypes vào SQLite.")

    # Nạp world_areas
    areas_file = ASSETS_DIR / "world_areas.min.json"
    if areas_file.exists():
        with open(areas_file, "r", encoding="utf-8") as f:
            areas_data = json.load(f)

        insert_areas = []
        for area_id, info in areas_data.items():
            name = info.get("name", "")
            if not name:
                continue
            act = info.get("act", 1)
            area_level = info.get("area_level", 0)
            has_wp = 1 if info.get("has_waypoint", False) else 0
            is_town = 1 if info.get("is_town", False) else 0
            conn_list = json.dumps(info.get("connections", []))

            insert_areas.append((
                area_id,
                name,
                name.lower(),
                act,
                area_level,
                has_wp,
                is_town,
                conn_list
            ))

        cursor.executemany("""
            INSERT OR REPLACE INTO world_areas (id, name, name_lower, act, area_level, has_waypoint, is_town, connections)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)
        """, insert_areas)
        print(f"  -> Đã nạp {len(insert_areas)} WorldAreas vào SQLite.")

    # Nạp skill_gems
    gems_file = ASSETS_DIR / "skill_gems.min.json"
    if gems_file.exists():
        with open(gems_file, "r", encoding="utf-8") as f:
            gems_data = json.load(f)

        insert_gems = []
        for gem_id, info in gems_data.items():
            base_item = info.get("base_item_type", "")
            str_r = info.get("strength_percent", 0)
            dex_r = info.get("dexterity_percent", 0)
            int_r = info.get("intelligence_percent", 0)
            insert_gems.append((gem_id, base_item, str_r, dex_r, int_r))

        cursor.executemany("""
            INSERT OR REPLACE INTO skill_gems (id, base_item_id, str_req, dex_req, int_req)
            VALUES (?, ?, ?, ?, ?)
        """, insert_gems)
        print(f"  -> Đã nạp {len(insert_gems)} SkillGems vào SQLite.")

    # Nạp uniques
    uniques_file = ASSETS_DIR / "uniques.min.json"
    if uniques_file.exists():
        with open(uniques_file, "r", encoding="utf-8") as f:
            uniques_data = json.load(f)

        insert_uniques = []
        for uniq_id, info in uniques_data.items():
            name = info.get("name", "")
            if not name:
                continue
            base = info.get("base_item", "")
            insert_uniques.append((uniq_id, name, name.lower(), base))

        cursor.executemany("""
            INSERT OR REPLACE INTO uniques (id, name, name_lower, base_item)
            VALUES (?, ?, ?, ?)
        """, insert_uniques)
        print(f"  -> Đã nạp {len(insert_uniques)} Unique items vào SQLite.")

    conn.commit()
    conn.close()
    print(f"\n[Thành Công] Đã tạo cơ sở dữ liệu {DB_PATH} ({DB_PATH.stat().st_size / 1024:.1f} KB).")

def main():
    ASSETS_DIR.mkdir(parents=True, exist_ok=True)
    print("=================================================")
    print("   AutoPOE2 - Static Game Data Synchronizer      ")
    print("=================================================")

    for filename in TARGET_FILES:
        try:
            download_file(filename, ASSETS_DIR)
        except Exception as e:
            print(f"[Warning] Không tải được {filename}: {e}")

    build_sqlite_database()

if __name__ == "__main__":
    main()
