import os
import re
from playwright.sync_api import Page, expect
from dulizhan.test_case.Resource.UI.base_page import BasePage


class DownloadAppPage(BasePage):
    """
    Download the App 页面对象

    已知侦察结果：
    - 首页 URL: https://joyhub-website-frontend-test.best-envision.com/
    - 页面标题: Joyhub | Explore Sexual Health, Wellness, and Connection
    - 导航链接: Download the App
    - Cookie 按钮文案: Accepet
    """

    DOWNLOAD_APP_LINK_TEXT = re.compile(r"^Download the App$", re.I)

    def accept_cookie_if_present(self):
        # 页面侦察结果中按钮文本为 Accepet，疑似拼写如此，按真实页面处理
        accept_button = self.page.get_by_role("button", name=re.compile(r"Accepet|Accept", re.I))
        self.click_if_visible(accept_button, timeout=3000)

    def open_download_app_page(self):
        self.accept_cookie_if_present()

        download_link = self.page.get_by_role("link", name=self.DOWNLOAD_APP_LINK_TEXT)
        expect(download_link).to_be_visible(timeout=10000)

        download_link.click()
        try:
            self.page.wait_for_load_state("networkidle", timeout=5000)
        except Exception:
            pass

    def get_google_play_locator(self):
        """
        优先使用稳定定位：
        1. href 包含 play.google.com
        2. 链接文本包含 Google Play
        3. 图片 alt 包含 Google，向上找父级 a 标签

        如果后续页面提供 data-testid，建议替换为：
        self.page.get_by_test_id("google-play-download")
        """
        candidates = [
            self.page.locator("a[href*='play.google.com']").first,
            self.page.get_by_role("link", name=re.compile(r"Google\s*Play", re.I)).first,
            self.page.locator("a").filter(has_text=re.compile(r"Google\s*Play", re.I)).first,
            self.page.locator("img[alt*='Google' i]").locator("xpath=ancestor::a[1]").first,
        ]

        for locator in candidates:
            try:
                if locator.count() > 0:
                    return locator
            except Exception:
                continue

        return None

    def discover_google_play_href(self):
        """
        DOM 兜底侦察：
        当 Google Play 是图片按钮、无文本链接时，用 JS 从渲染后的 DOM 中提取跳转地址。
        只用于兜底发现，不作为首选点击方式。
        """
        return self.page.evaluate(
            """
            () => {
                const keywords = ['google play', 'play.google.com'];
                const nodes = Array.from(document.querySelectorAll('a, button, [role="button"], img'));

                for (const node of nodes) {
                    const text = [
                        node.innerText,
                        node.textContent,
                        node.getAttribute('aria-label'),
                        node.getAttribute('title'),
                        node.getAttribute('alt'),
                        node.getAttribute('href'),
                        node.getAttribute('src')
                    ].filter(Boolean).join(' ').toLowerCase();

                    if (keywords.some(k => text.includes(k))) {
                        const link = node.closest('a');
                        if (link && link.href) {
                            return link.href;
                        }

                        if (node.href) {
                            return node.href;
                        }
                    }
                }

                return null;
            }
            """
        )

    def click_google_play_and_get_redirect_url(self) -> str:
        """
        点击 Google Play 下载入口，并返回跳转地址。

        成功判定：
        - 新开页面 URL
        - 当前页面跳转后的 URL
        - 或点击前已获取到 Google Play href
        """
        try:
            self.page.wait_for_load_state("networkidle", timeout=5000)
        except Exception:
            pass

        google_play_href = self.discover_google_play_href()
        google_play_locator = self.get_google_play_locator()

        if google_play_locator is None and not google_play_href:
            raise AssertionError(
                "未找到 Google Play 下载入口。"
                "请检查 Download the App 页面是否存在 Google Play 链接，"
                "或补充稳定 selector，例如 data-testid。"
            )

        context = self.page.context
        before_pages = list(context.pages)
        old_url = self.page.url

        if google_play_locator is not None:
            google_play_locator.scroll_into_view_if_needed()
            google_play_locator.click()
        else:
            # 没有稳定可点击 locator 时，使用已发现 href 直接跳转。
            # TODO: 页面增加稳定 selector 后，替换为 locator.click()
            self.page.goto(google_play_href, wait_until="domcontentloaded")

        self.page.wait_for_timeout(3000)

        after_pages = list(context.pages)
        new_pages = [p for p in after_pages if p not in before_pages]

        if new_pages:
            new_page = new_pages[-1]
            new_page.wait_for_load_state("domcontentloaded")
            try:
                new_page.wait_for_load_state("networkidle", timeout=10000)
            except Exception:
                pass
            return new_page.url

        if self.page.url != old_url:
            return self.page.url

        if google_play_href:
            return google_play_href

        raise AssertionError("点击 Google Play 后未获取到跳转地址")
