"""
debug_gh_yellow.py - GH「もっとみる」停止条件デバッグスクリプト

.shopBox:not(.yellowColor) が出たら止める判定が福岡で効かない問題を調査する。
「もっとみる」を最大10回クリックしながら、各クリック後に以下をログ出力する:
  - .shopBox 総数
  - .shopBox.yellowColor 数（Sタイプ）
  - .shopBox:not(.yellowColor) 数（Sタイプ以外）
  - .searchResultShopList 数
また、最初の15個の .shopBox の class 属性を列挙して yellowColor の付き方を確認する。
DB保存なし・調査専用。

Usage:
    python tools/debug_gh_yellow.py <monitor_url>
    例: python tools/debug_gh_yellow.py https://www.girlsheaven-job.net/fukuoka/shop-list/
"""

import argparse
import logging
import sys
from pathlib import Path

from playwright.sync_api import sync_playwright
from playwright_stealth import Stealth

# ---------------------------------------------------------------------------
# 定数
# ---------------------------------------------------------------------------
SCREENSHOT_PATH = Path(__file__).parent / "debug_gh_yellow.png"
PAGE_TIMEOUT    = 30_000   # ms
MAX_MORE_CLICKS = 10       # デバッグ用最大クリック数
CLASS_DUMP_COUNT = 15      # class 属性を列挙する .shopBox の最大件数

MORE_BTN_SELECTORS = ["a.nextBtn"]

# ---------------------------------------------------------------------------
# ロガー
# ---------------------------------------------------------------------------
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
)
logger = logging.getLogger(__name__)


# ---------------------------------------------------------------------------
# カウントをまとめてログ出力
# ---------------------------------------------------------------------------
def log_counts(page, label: str) -> None:
    total       = page.locator(".shopBox").count()
    yellow      = page.locator(".shopBox.yellowColor").count()
    not_yellow  = page.locator(".shopBox:not(.yellowColor)").count()
    result_list = page.locator(".searchResultShopList").count()
    logger.info(
        "%s: shopBox総数=%d  yellowColor=%d  not-yellowColor=%d  searchResultShopList=%d",
        label, total, yellow, not_yellow, result_list,
    )


# ---------------------------------------------------------------------------
# 最初の N 個の .shopBox の class 属性を列挙
# ---------------------------------------------------------------------------
def dump_shopbox_classes(page, n: int = CLASS_DUMP_COUNT) -> None:
    boxes = page.locator(".shopBox")
    total = boxes.count()
    show  = min(total, n)
    logger.info("--- .shopBox class 属性ダンプ（先頭%d件 / 全%d件） ---", show, total)
    for i in range(show):
        cls = boxes.nth(i).get_attribute("class") or "(class なし)"
        logger.info("  [%02d] %s", i + 1, cls)
    logger.info("--- ダンプ終了 ---")


# ---------------------------------------------------------------------------
# メイン
# ---------------------------------------------------------------------------
def main() -> None:
    parser = argparse.ArgumentParser(description="GH yellowColor 停止条件デバッグ")
    parser.add_argument("monitor_url", help="GH 店舗一覧URL（例: https://www.girlsheaven-job.net/fukuoka/shop-list/）")
    args = parser.parse_args()

    monitor_url = args.monitor_url.rstrip("/") + "/"
    if "?op=newc" not in monitor_url:
        monitor_url += "?op=newc"
    logger.info("対象URL: %s", monitor_url)

    with sync_playwright() as pw:
        browser = pw.chromium.launch(headless=True)
        ctx = browser.new_context(
            viewport={"width": 1280, "height": 800},
            user_agent=(
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                "AppleWebKit/537.36 (KHTML, like Gecko) "
                "Chrome/124.0.0.0 Safari/537.36"
            ),
        )
        page = ctx.new_page()
        Stealth().apply_stealth_sync(page)
        page.set_default_timeout(PAGE_TIMEOUT)

        try:
            # ページ取得
            logger.info("ページ取得中...")
            page.goto(monitor_url, timeout=PAGE_TIMEOUT, wait_until="load")
            page.wait_for_timeout(2000)

            # 年齢確認
            age_btn = page.locator(".over18confirm-yes")
            if age_btn.count() > 0:
                logger.info("年齢確認ダイアログを通過")
                age_btn.click()
                page.wait_for_timeout(1500)

            # 初期状態カウント
            log_counts(page, "初期状態")

            # 「もっとみる」クリックループ
            for click_count in range(1, MAX_MORE_CLICKS + 1):
                # ボタン探索
                more_btn = None
                for sel in MORE_BTN_SELECTORS:
                    el = page.locator(sel)
                    if el.count() > 0:
                        more_btn = el.first
                        break

                if more_btn is None:
                    logger.info("「もっとみる」ボタンなし → ループ終了")
                    break

                # スクロールしてボタンを表示
                page_height = page.evaluate("document.body.scrollHeight")
                scroll_y    = page.evaluate("window.scrollY")
                while scroll_y < page_height:
                    scroll_y = min(scroll_y + 300, page_height)
                    page.evaluate(f"window.scrollTo(0, {scroll_y})")
                    page.wait_for_timeout(200)
                    if more_btn.is_visible():
                        break

                if not more_btn.is_visible():
                    logger.info("「もっとみる」ボタンが非表示 → ループ終了")
                    break

                logger.info("「もっとみる」クリック (%d回目)", click_count)
                more_btn.scroll_into_view_if_needed()
                page.wait_for_timeout(500)
                more_btn.click()
                page.wait_for_timeout(3500)

                # クリック後カウント
                log_counts(page, f"クリック{click_count}回目後")

                # 停止条件チェック（デバッグ: 止まるか確認）
                not_yellow_count = page.locator(".shopBox:not(.yellowColor)").count()
                if not_yellow_count > 0:
                    logger.info("★ 停止条件成立: not-yellowColor=%d → 実際のスクリプトならここで停止", not_yellow_count)
                    break
            else:
                logger.warning("最大クリック数（%d回）に達した", MAX_MORE_CLICKS)

            # 最終状態: class 属性ダンプ
            log_counts(page, "最終状態")
            dump_shopbox_classes(page, CLASS_DUMP_COUNT)

            # スクリーンショット
            try:
                page.screenshot(path=str(SCREENSHOT_PATH), full_page=True)
                logger.info("スクリーンショット保存: %s", SCREENSHOT_PATH)
            except Exception as e:
                logger.warning("スクリーンショット失敗: %s", e)

        except Exception as e:
            logger.error("エラー: %s", e)
            try:
                page.screenshot(path=str(SCREENSHOT_PATH), full_page=True)
            except Exception:
                pass
            sys.exit(1)
        finally:
            browser.close()


if __name__ == "__main__":
    main()
