"""
Smoke tests for critical user paths.
Tests that all major pages satisfy core UI contracts.
"""
import pytest
from playwright.sync_api import Page

from tests.playwright.config.test_config import config
from tests.playwright.pages import AdminPage, DashboardPage, LoginPage
from tests.playwright.tests.smoke.test_critical_paths import (
    _assert_asset_analysis_contract,
    _assert_audit_contract,
    _assert_backtest_contract,
    _assert_dashboard_contract,
    _assert_equity_contract,
    _assert_filter_contract,
    _assert_fund_contract,
    _assert_macro_contract,
    _assert_policy_contract,
    _assert_regime_contract,
    _assert_rotation_contract,
    _assert_signal_contract,
    _assert_simulated_trading_contract,
)
from tests.playwright.utils.screenshot_utils import ScreenshotUtils


class TestCriticalPaths:
    """Test critical paths through the application."""

    def test_login_page_loads(self, login_page: LoginPage) -> None:
        """Test that login page loads successfully."""
        login_page.goto()
        login_page.assert_on_login_page()
        login_page.assert_not_django_admin_login()

    def test_dashboard_requires_auth(self, dashboard_page: DashboardPage) -> None:
        """Test that dashboard requires authentication."""
        dashboard_page.goto()
        # Should redirect to login or show unauthorized
        # Check that path is not /dashboard/ (ignoring query parameters)
        from urllib.parse import urlparse
        parsed = urlparse(dashboard_page.page.url)
        assert parsed.path != "/dashboard/", "Should not be on dashboard without auth"

    def test_login_to_dashboard_path(self, login_page: LoginPage) -> None:
        """Test complete login flow to dashboard."""
        login_page.goto()
        login_page.assert_not_django_admin_login()
        login_page.login_as_admin()
        login_page.assert_login_success()

    def test_authenticated_dashboard_loads(self, authenticated_page: Page) -> None:
        """Test that dashboard loads when authenticated."""
        authenticated_page.goto(f"{config.base_url}{config.dashboard_url}")
        _assert_dashboard_contract(authenticated_page)

    def test_macro_data_page_loads(self, authenticated_page: Page) -> None:
        """Test that macro data page loads."""
        authenticated_page.goto(f"{config.base_url}{config.macro_data_url}")
        _assert_macro_contract(authenticated_page)

    def test_regime_dashboard_loads(self, authenticated_page: Page) -> None:
        """Test that regime dashboard loads."""
        authenticated_page.goto(f"{config.base_url}{config.regime_dashboard_url}")
        _assert_regime_contract(authenticated_page)

    def test_signal_manage_loads(self, authenticated_page: Page) -> None:
        """Test that signal management page loads."""
        authenticated_page.goto(f"{config.base_url}{config.signal_manage_url}")
        _assert_signal_contract(authenticated_page)

    def test_policy_manage_loads(self, authenticated_page: Page) -> None:
        """Test that policy management page loads."""
        authenticated_page.goto(f"{config.base_url}{config.policy_manage_url}")
        _assert_policy_contract(authenticated_page)

    def test_equity_screen_loads(self, authenticated_page: Page) -> None:
        """Test that equity screening page loads."""
        authenticated_page.goto(f"{config.base_url}{config.equity_screen_url}")
        _assert_equity_contract(authenticated_page)

    def test_fund_dashboard_loads(self, authenticated_page: Page) -> None:
        """Test that fund dashboard page loads."""
        authenticated_page.goto(f"{config.base_url}{config.fund_dashboard_url}")
        _assert_fund_contract(authenticated_page)

    def test_asset_analysis_screen_loads(self, authenticated_page: Page) -> None:
        """Test that asset analysis page loads."""
        authenticated_page.goto(f"{config.base_url}{config.asset_analysis_screen_url}")
        _assert_asset_analysis_contract(authenticated_page)

    def test_backtest_create_loads(self, authenticated_page: Page) -> None:
        """Test that backtest creation page loads."""
        authenticated_page.goto(f"{config.base_url}{config.backtest_create_url}")
        _assert_backtest_contract(authenticated_page)

    def test_simulated_trading_dashboard_loads(self, authenticated_page: Page) -> None:
        """Test that simulated trading dashboard loads."""
        authenticated_page.goto(f"{config.base_url}{config.simulated_trading_dashboard_url}")
        _assert_simulated_trading_contract(authenticated_page)

    def test_audit_reports_loads(self, authenticated_page: Page) -> None:
        """Test that audit reports page loads."""
        authenticated_page.goto(f"{config.base_url}{config.audit_reports_url}")
        _assert_audit_contract(authenticated_page)

    def test_filter_manage_loads(self, authenticated_page: Page) -> None:
        """Test that filter management page loads."""
        authenticated_page.goto(f"{config.base_url}{config.filter_manage_url}")
        _assert_filter_contract(authenticated_page)

    def test_sector_analysis_loads(self, authenticated_page: Page) -> None:
        """Test that sector analysis page loads."""
        authenticated_page.goto(f"{config.base_url}{config.sector_analysis_url}")
        _assert_rotation_contract(authenticated_page)


class TestAdminExposureSmoke:
    """Smoke tests for Django Admin exposure."""

    def test_admin_index_accessible(self, page: Page) -> None:
        """Test that admin index is accessible."""
        page.goto(f"{config.base_url}{config.admin_index}")
        # Admin should be accessible but we need to verify
        assert "/admin/" in page.url or "login" in page.url

    def test_admin_exposes_modules(self, authenticated_page: Page) -> None:
        """Check what modules are exposed in admin.
        Note: authenticated_page uses custom login (/account/login/).
        Django admin may use the same authentication (shared session).
        """
        authenticated_page.goto(f"{config.base_url}{config.admin_index}")
        admin = AdminPage(authenticated_page)

        # Check if we're on an admin page
        assert admin.is_django_admin_page(), "Should be on Django admin page"

        modules = admin.get_admin_modules()

        # The test outcome depends on authentication state:
        # - If modules are found: User is authenticated with Django admin
        # - If no modules: Either on login page or different page structure
        if len(modules) == 0:
            # Check if we're actually on the admin login page
            # or if we're authenticated but the page structure is different
            if "/admin/login/" not in authenticated_page.url:
                # We're authenticated but no modules found with current selector
                # This is OK - it just means the admin page structure differs
                # from the expected .app selector
                pass
        else:
            # Modules found - user has admin access
            assert len(modules) > 0

    def test_user_pages_not_admin(self, authenticated_page: Page) -> None:
        """Verify user-facing pages are not Admin pages."""
        user_urls = [
            config.dashboard_url,
            config.macro_data_url,
            config.regime_dashboard_url,
            config.signal_manage_url,
        ]

        for url in user_urls:
            authenticated_page.goto(f"{config.base_url}{url}")
            admin = AdminPage(authenticated_page)
            is_admin = admin.is_django_admin_page()
            assert not is_admin, f"User page {url} appears to be Django Admin page"


class TestScreenshotBaseline:
    """Generate baseline screenshots for all pages."""

    @pytest.mark.screenshot
    def test_screenshot_login_page(self, login_page: LoginPage, screenshot_utils: ScreenshotUtils) -> None:
        """Capture baseline screenshot of login page."""
        login_page.goto()
        screenshot_utils.capture_baseline(login_page.page, "login_page", module="auth")

    @pytest.mark.screenshot
    def test_screenshot_dashboard(self, authenticated_dashboard: DashboardPage, screenshot_utils: ScreenshotUtils) -> None:
        """Capture baseline screenshot of dashboard."""
        authenticated_dashboard.goto()
        screenshot_utils.capture_baseline(authenticated_dashboard.page, "dashboard", module="dashboard")

    @pytest.mark.screenshot
    def test_screenshot_macro_data(self, authenticated_page: Page, screenshot_utils: ScreenshotUtils) -> None:
        """Capture baseline screenshot of macro data page."""
        authenticated_page.goto(f"{config.base_url}{config.macro_data_url}")
        screenshot_utils.capture_baseline(authenticated_page, "macro_data", module="macro")

    @pytest.mark.screenshot
    def test_screenshot_regime_dashboard(self, authenticated_page: Page, screenshot_utils: ScreenshotUtils) -> None:
        """Capture baseline screenshot of regime dashboard."""
        authenticated_page.goto(f"{config.base_url}{config.regime_dashboard_url}")
        screenshot_utils.capture_baseline(authenticated_page, "regime_dashboard", module="regime")

    @pytest.mark.screenshot
    def test_screenshot_signal_manage(self, authenticated_page: Page, screenshot_utils: ScreenshotUtils) -> None:
        """Capture baseline screenshot of signal management."""
        authenticated_page.goto(f"{config.base_url}{config.signal_manage_url}")
        screenshot_utils.capture_baseline(authenticated_page, "signal_manage", module="signal")

    @pytest.mark.screenshot
    def test_screenshot_equity_screen(self, authenticated_page: Page, screenshot_utils: ScreenshotUtils) -> None:
        """Capture baseline screenshot of equity screening."""
        authenticated_page.goto(f"{config.base_url}{config.equity_screen_url}")
        screenshot_utils.capture_baseline(authenticated_page, "equity_screen", module="equity")

    @pytest.mark.screenshot
    def test_screenshot_fund_dashboard(self, authenticated_page: Page, screenshot_utils: ScreenshotUtils) -> None:
        """Capture baseline screenshot of fund dashboard."""
        authenticated_page.goto(f"{config.base_url}{config.fund_dashboard_url}")
        screenshot_utils.capture_baseline(authenticated_page, "fund_dashboard", module="fund")

    @pytest.mark.screenshot
    def test_screenshot_backtest_create(self, authenticated_page: Page, screenshot_utils: ScreenshotUtils) -> None:
        """Capture baseline screenshot of backtest creation."""
        authenticated_page.goto(f"{config.base_url}{config.backtest_create_url}")
        screenshot_utils.capture_baseline(authenticated_page, "backtest_create", module="backtest")

    @pytest.mark.screenshot
    def test_screenshot_simulated_trading(self, authenticated_page: Page, screenshot_utils: ScreenshotUtils) -> None:
        """Capture baseline screenshot of simulated trading."""
        authenticated_page.goto(f"{config.base_url}{config.simulated_trading_dashboard_url}")
        screenshot_utils.capture_baseline(authenticated_page, "simulated_trading", module="simulated_trading")

