from __future__ import annotations

import os
from dataclasses import dataclass

import pytest
from playwright.sync_api import Page

from e2e.utils.bug_reporter import BugReporter
from e2e.utils.dual_browser import assert_distinct_account_contexts, dual_browser_enabled, dual_browser_manager
from e2e.utils.env_config import load_e2e_env


load_e2e_env()


@dataclass(frozen=True)
class E2ESettings:
    e2e_env: str
    tenant_base_url: str
    tenant_home_url: str
    admin_url: str
    admin_username: str
    admin_password: str
    register_password: str
    phone_prefix: str
    max_register_attempts: int
    enterprise_name_prefix: str
    verification_code_mode: str
    verification_code_static: str
    manual_code_file: str
    manual_code_timeout_seconds: int
    manual_code_poll_interval_seconds: int
    image_captcha_mode: str
    feishu_app_id: str
    feishu_app_secret: str
    feishu_chat_id: str
    feishu_timeout_seconds: int
    feishu_poll_interval_seconds: int
    certified_tenant_phone: str
    certified_tenant_password: str
    certified_tenant_enterprise_name: str
    certified_tenant_merchant_id: str
    wanyouji_product_id: str
    wanzhanggui_product_id: str
    wanzhanggui_tenant_phone: str
    wanzhanggui_tenant_password: str
    viewport_width: int
    viewport_height: int


@dataclass
class DualAccountPages:
    seed_page: Page
    viewport: dict[str, int]

    def page_for(self, phone: str) -> Page:
        assert dual_browser_enabled(), "多账号用例必须开启 E2E_DUAL_BROWSER，默认值为开启。"
        return dual_browser_manager().page_for_account(
            phone,
            viewport=self.viewport,
            seed_page=self.seed_page,
        )

    def pair(self, left_phone: str, right_phone: str) -> tuple[Page, Page]:
        left_page = self.page_for(left_phone)
        right_page = self.page_for(right_phone)
        assert_distinct_account_contexts(left_page, left_phone, right_page, right_phone)
        return left_page, right_page


@pytest.fixture(scope="session")
def settings() -> E2ESettings:
    return E2ESettings(
        e2e_env=os.getenv("E2E_ENV", "test"),
        tenant_base_url=os.getenv("TENANT_BASE_URL", "https://test-lianlianyun.lianlianwz.com"),
        tenant_home_url=os.getenv("TENANT_HOME_URL", "https://test-lianlianyun.lianlianwz.com/home"),
        admin_url=os.getenv("ADMIN_URL", "https://test-saas-adminui.lianlianwz.com/pages/home/index"),
        admin_username=os.getenv("ADMIN_USERNAME", "wangss"),
        admin_password=os.getenv("ADMIN_PASSWORD", "123456"),
        register_password=os.getenv("E2E_REGISTER_PASSWORD", "test123456"),
        phone_prefix=os.getenv("E2E_PHONE_PREFIX", "19"),
        max_register_attempts=int(os.getenv("E2E_MAX_REGISTER_ATTEMPTS", "5")),
        enterprise_name_prefix=os.getenv("E2E_ENTERPRISE_NAME_PREFIX", "E2E测试企业"),
        verification_code_mode=os.getenv("E2E_VERIFICATION_CODE_MODE", "feishu"),
        verification_code_static=os.getenv("E2E_VERIFICATION_CODE_STATIC", ""),
        manual_code_file=os.getenv("E2E_MANUAL_CODE_FILE", "runtime/sms_code.txt"),
        manual_code_timeout_seconds=int(os.getenv("E2E_MANUAL_CODE_TIMEOUT_SECONDS", "180")),
        manual_code_poll_interval_seconds=int(os.getenv("E2E_MANUAL_CODE_POLL_INTERVAL_SECONDS", "2")),
        image_captcha_mode=os.getenv("E2E_IMAGE_CAPTCHA_MODE", "ddddocr"),
        feishu_app_id=os.getenv("FEISHU_APP_ID", ""),
        feishu_app_secret=os.getenv("FEISHU_APP_SECRET", ""),
        feishu_chat_id=os.getenv("FEISHU_CHAT_ID", ""),
        feishu_timeout_seconds=int(os.getenv("FEISHU_TIMEOUT_SECONDS", "60")),
        feishu_poll_interval_seconds=int(os.getenv("FEISHU_POLL_INTERVAL_SECONDS", "3")),
        certified_tenant_phone=os.getenv("E2E_CERTIFIED_TENANT_PHONE", "19361091624"),
        certified_tenant_password=os.getenv("E2E_CERTIFIED_TENANT_PASSWORD", "test123456"),
        certified_tenant_enterprise_name=os.getenv("E2E_CERTIFIED_TENANT_ENTERPRISE_NAME", "E2E已认证企业"),
        certified_tenant_merchant_id=os.getenv("E2E_CERTIFIED_TENANT_MERCHANT_ID", ""),
        wanyouji_product_id=os.getenv("E2E_WANYOUJI_PRODUCT_ID", "12"),
        wanzhanggui_product_id=os.getenv("E2E_WANZHANGGUI_PRODUCT_ID", "15"),
        wanzhanggui_tenant_phone=os.getenv("E2E_WANZHANGGUI_TENANT_PHONE", "19147509308"),
        wanzhanggui_tenant_password=os.getenv("E2E_WANZHANGGUI_TENANT_PASSWORD", "test123456"),
        viewport_width=int(os.getenv("E2E_VIEWPORT_WIDTH", "1920")),
        viewport_height=int(os.getenv("E2E_VIEWPORT_HEIGHT", "1080")),
    )


@pytest.fixture(scope="session")
def browser_type_launch_args(browser_type_launch_args, settings: E2ESettings):
    args = list(browser_type_launch_args.get("args", []))
    window_size_arg = f"--window-size={settings.viewport_width},{settings.viewport_height}"
    args = [arg for arg in args if not str(arg).startswith("--window-size=")]
    args.append(window_size_arg)
    return {
        **browser_type_launch_args,
        "headless": True if dual_browser_enabled() else browser_type_launch_args.get("headless", False),
        "args": args,
    }


@pytest.fixture(scope="session")
def browser_context_args(browser_context_args, settings: E2ESettings):
    return {
        **browser_context_args,
        "viewport": {
            "width": settings.viewport_width,
            "height": settings.viewport_height,
        },
        "screen": {
            "width": settings.viewport_width,
            "height": settings.viewport_height,
        },
    }


@pytest.fixture
def dual_account_pages(page: Page, settings: E2ESettings) -> DualAccountPages:
    return DualAccountPages(
        seed_page=page,
        viewport={
            "width": settings.viewport_width,
            "height": settings.viewport_height,
        },
    )


@pytest.fixture
def bug_reporter(page: Page, request) -> BugReporter:
    marker_to_case = {
        "e2e_saas_001": "E2E-SAAS-001",
        "e2e_saas_003": "E2E-SAAS-003",
        "e2e_saas_004": "E2E-SAAS-004",
        "e2e_auth_closed_loop": "E2E-AUTH-001",
        "e2e_auth_new_enterprise": "E2E-AUTH-NEW-ENTERPRISE",
        "e2e_push_001": "E2E-PUSH-001",
        "e2e_push_003": "E2E-PUSH-003",
        "e2e_order_001": "E2E-ORDER-001",
        "s_flow_001": "S-FLOW-001",
        "e2e_task_001": "E2E-TASK-001",
        "e2e_member_001": "E2E-MEMBER-001",
        "e2e_member_002": "E2E-MEMBER-002",
        "e2e_main_001": "E2E-MAIN-001",
        "e2e_main_002": "E2E-MAIN-002",
    }
    case_id = "E2E-SAAS"
    for marker_name, marker_case_id in marker_to_case.items():
        if request.node.get_closest_marker(marker_name):
            case_id = marker_case_id
            break
    return BugReporter(page, case_id=case_id)


@pytest.fixture(scope="session", autouse=True)
def close_dual_browser_manager():
    yield
    dual_browser_manager().close()
