import httpx
from bs4 import BeautifulSoup
import json
import asyncio

import re


def parse_ws_html(html: str) -> list[dict]:
    """最強強化版 Weiß Schwarz 解析器：含圖示欄位（色、魂、觸發）"""
    soup = BeautifulSoup(html, "html.parser")
    table = soup.find("table", class_="search-result-table")
    if not table:
        print("⚠️ 沒找到卡片表格結構")
        return []

    rows = table.find_all("tr")
    results = []

    for row in rows:
        cols = row.find_all("td")
        if not cols:
            continue

        img_tag = row.find("img")
        img_url = None
        if img_tag and img_tag.get("src"):
            src = img_tag["src"]
            img_url = src if src.startswith("http") else f"https://ws-tcg.com{src}"

        text = row.get_text(" ", strip=True)

        # 🧩 卡名與卡號
        name_match = re.match(r"^(.*?)\s*\(\s*([A-Z0-9/]+-[A-Z0-9]+)\s*\)", text)
        if name_match:
            card_name = name_match.group(1).strip()
            card_number = name_match.group(2).strip()
        else:
            card_name = text.split(" ")[0].strip()
            card_number = None

        # 從 row 的 HTML 直接分析單位 <span class="unit">
        units = row.select("span.unit")

        color = None
        power = None
        soul = None
        cost = None
        rarity = None
        trigger = []
        type_ = None
        level = None

        for unit in units:
            label = unit.get_text(strip=True)
            imgs = unit.find_all("img")

            # 提取 .gif 名稱
            gif_names = []
            for img in imgs:
                src = img.get("src", "")
                m = re.search(r"/([a-zA-Z0-9_]+)\.gif", src)
                if m:
                    gif_names.append(m.group(1))

            if "色" in label:
                color = gif_names[0] if gif_names else label.replace("色：", "").strip() or None
            elif "レベル" in label:
                level = re.search(r"(\d+)", label)
                level = int(level.group(1)) if level else None
            elif "パワー" in label:
                power = re.search(r"(\d+)", label)
                power = int(power.group(1)) if power else None
            elif "ソウル" in label:
                if gif_names:
                    soul = len(gif_names)  # 用圖數當魂數
                else:
                    soul = re.search(r"(\d+)", label)
                    soul = int(soul.group(1)) if soul else None
            elif "コスト" in label:
                cost = re.search(r"(\d+)", label)
                cost = int(cost.group(1)) if cost else None
            elif "レアリティ" in label:
                rarity = label.replace("レアリティ：", "").strip() or None
            elif "トリガー" in label:
                trigger = gif_names or [label.replace("トリガー：", "").strip()]
            elif "種類" in label:
                type_ = label.replace("種類：", "").strip() or None

        # 從整段文字抽特徵、風味、效果
        info_text = row.get_text(" ", strip=True)
        traits_match = re.search(r"特徴：([^フレーバー]*)", info_text)
        traits = [t.strip() for t in traits_match.group(1).split("・")] if traits_match else []

        flavor_match = re.search(r"フレーバー：([^【]*)", info_text)
        flavor = flavor_match.group(1).strip() if flavor_match else None

        effect_match = re.search(r"(【[^】]+】.*)", info_text)
        effect = effect_match.group(1).strip() if effect_match else None

        results.append({
            "card_name": card_name,
            "card_number": card_number,
            "type": type_,
            "level": level,
            "color": color,
            "power": power,
            "soul": soul,
            "cost": cost,
            "rarity": rarity,
            "trigger": trigger,
            "traits": traits,
            "flavor": flavor,
            "effect": effect,
            "image": img_url,
        })

    return results

import asyncio
import httpx
from bs4 import BeautifulSoup
import re

async def fetch_ws_cards(keyword: str = "", title_number: str = "", counter_mode: bool = False):
    """抓取 WS 官方卡片資料，支援多頁併發爬取（順序保持）"""
    payload = {
        "_method": "POST",
        "expansion_select": "",
        "title_number_select": "",
        "cmd": "search",
        "keyword": keyword,
        "keyword_or": "",
        "keyword_not": "",
        "keyword_cardname[0]": "",
        "keyword_cardname[1]": "",
        "keyword_feature[0]": "",
        "keyword_feature[1]": "",
        "keyword_text[0]": "",
        "keyword_text[1]": "",
        "keyword_cardnumber[0]": "",
        "keyword_cardnumber[1]": "",
        "side": "",
        "title_number": title_number,
        "expansion_category": "",
        "expansion": "",
        "card_kind": "",
        "level_s": "",
        "level_e": "",
        "power_s": "",
        "power_e": "",
        "color": "",
        "soul_s": "",
        "soul_e": "",
        "cost_s": "",
        "cost_e": "",
        "trigger": "",
        "option_counter": "1" if counter_mode else "0",
        "option_clock": "0",
        "show_page_count": "25",
        "show_small": "0",
        "parallel": "0",
        "expansion_filter": "",
        "button": "カードを検索する",
    }

    base_url = "https://ws-tcg.com/cardlist/search"
    all_cards = []

    async with httpx.AsyncClient() as client:
        # 🧭 抓首頁
        response = await client.post(
            base_url,
            data=payload,
            headers={"Content-Type": "application/x-www-form-urlencoded"},
            timeout=30,
        )
        html = response.text
        print(f"✅ HTML 取得成功（{len(html)} bytes）")

        soup = BeautifulSoup(html, "html.parser")
        first_cards = parse_ws_html(html)
        all_cards.extend(first_cards)

        pager = soup.find("p", class_="pager")
        if not pager:
            print("📄 僅一頁結果。")
            return all_cards

        pages = []
        for span in pager.find_all("span"):
            a = span.find("a")
            if a and "page=" in a.get("href", ""):
                try:
                    num = int(re.search(r"page=(\d+)", a["href"]).group(1))
                    pages.append(num)
                except:
                    pass
        max_page = max(pages) if pages else 1
        print(f"📑 共 {max_page} 頁，準備併發抓取…")

        # 🔥 建立所有任務
        async def fetch_page(page_num: int):
            url = f"{base_url}?page={page_num}"
            try:
                resp = await client.post(
                    url,
                    data=payload,
                    headers={"Content-Type": "application/x-www-form-urlencoded"},
                    timeout=30,
                )
                html_page = resp.text
                cards = parse_ws_html(html_page)
                print(f"✅ 第 {page_num}/{max_page} 頁 → {len(cards)} 張")
                return (page_num, cards)
            except Exception as e:
                print(f"⚠️ 第 {page_num} 頁錯誤：{e}")
                return (page_num, [])

        # 🧩 同時抓所有頁（最多同時10個）
        semaphore = asyncio.Semaphore(10)

        async def sem_fetch(page):
            async with semaphore:
                return await fetch_page(page)

        tasks = [sem_fetch(page) for page in range(2, max_page + 1)]
        results = await asyncio.gather(*tasks)

        # 🧠 排序合併結果
        results.sort(key=lambda x: x[0])
        for _, cards in results:
            all_cards.extend(cards)

    print(f"🎉 全部抓取完成，共 {len(all_cards)} 張卡")
    return all_cards

async def main():
    print("=== 🔍 一般搜尋模式 ===")
    normal_cards = await fetch_ws_cards(keyword="あくあ", title_number="HOL", counter_mode=False)
    print(f"🃏 抓到 {len(normal_cards)} 張卡")
    if normal_cards:
        print("➡️ 第一張卡：", json.dumps(normal_cards[0], ensure_ascii=False, indent=2))

    print("\n=== 🛡 助太刀搜尋模式（Counter） ===")
    counter_cards = await fetch_ws_cards(keyword="あくあ", title_number="HOL", counter_mode=True)
    print(f"🧱 抓到 {len(counter_cards)} 張助太刀卡")
    if counter_cards:
        print("➡️ 第一張助太刀卡：", json.dumps(counter_cards[0], ensure_ascii=False, indent=2))


if __name__ == "__main__":
    asyncio.run(main())
