"""
E2E Tests for ReceptionistAI Landing/Marketing Page.

Tests page performance, responsiveness, and user experience.
Based on DEMO_RECORDING_SUMMARY.md and marketing requirements.
"""
import pytest
import time
from playwright.sync_api import expect


class TestPageLoading:
    """Landing page load performance tests."""

    def test_page_loads_successfully(self, page, widget_url):
        """Verify landing page loads without errors."""
        response = page.goto(f"{widget_url}/demo.html")
        assert response.status == 200, "Page failed to load"

    def test_page_load_time_under_3s(self, page, widget_url):
        """
        Verify page loads in under 3 seconds.

        From DEMO_RECORDING_SUMMARY.md:
        "Page loads under 3 seconds"
        """
        start_time = time.time()
        page.goto(f"{widget_url}/demo.html")
        page.wait_for_load_state("load")
        load_time = time.time() - start_time

        assert load_time < 3.0, f"Page load took {load_time:.2f}s (target: <3s)"

    def test_page_interactive_quickly(self, page, widget_url):
        """Verify page becomes interactive quickly (TTI)."""
        start_time = time.time()
        page.goto(f"{widget_url}/demo.html")
        page.wait_for_load_state("networkidle")

        # Check interactive elements are ready
        trigger = page.locator('button.widget-trigger, button[aria-label*="call"]').first
        trigger.wait_for(state="visible", timeout=5000)

        interactive_time = time.time() - start_time
        assert interactive_time < 4.0, f"Time to interactive: {interactive_time:.2f}s (target: <4s)"

    def test_no_console_errors_on_load(self, page, widget_url):
        """
        Verify no JavaScript errors on page load.

        From DEMO_RECORDING_SUMMARY.md:
        "No console errors"
        """
        errors = []
        page.on("console", lambda msg: errors.append(msg.text) if msg.type == "error" else None)

        page.goto(f"{widget_url}/demo.html")
        page.wait_for_load_state("networkidle")

        # Filter out benign errors (favicon, analytics, etc.)
        critical_errors = [
            e for e in errors
            if "favicon" not in e.lower()
            and "analytics" not in e.lower()
            and "gtag" not in e.lower()
        ]

        assert len(critical_errors) == 0, f"Console errors found: {critical_errors}"


class TestPageContent:
    """Test page content and structure."""

    def test_all_sections_render(self, page, widget_url):
        """
        Verify all page sections render correctly.

        From DEMO_RECORDING_SUMMARY.md:
        "All sections render"
        """
        page.goto(f"{widget_url}/demo.html")

        # Common landing page sections
        # Note: Exact selectors depend on actual page structure

        # Hero section should exist
        hero = page.locator('section, .hero, [class*="hero"]').first
        expect(hero).to_be_visible()

        # Some content should be visible
        headings = page.locator('h1, h2, h3')
        assert headings.count() > 0, "No headings found on page"

    def test_cta_buttons_present(self, page, widget_url):
        """
        Verify Call-to-Action buttons are present.

        From DEMO_RECORDING_SUMMARY.md:
        "CTA buttons work"
        """
        page.goto(f"{widget_url}/demo.html")

        # Look for common CTA patterns
        cta_selectors = [
            'button:has-text("Try Demo")',
            'button:has-text("Get Started")',
            'a:has-text("Sign Up")',
            'button.cta',
            'a.cta-button',
            '.widget-trigger'  # Widget trigger is a CTA
        ]

        found_cta = False
        for selector in cta_selectors:
            if page.locator(selector).count() > 0:
                found_cta = True
                break

        assert found_cta, "No CTA buttons found on page"

    def test_cta_buttons_clickable(self, page, widget_url):
        """Verify CTA buttons are clickable and functional."""
        page.goto(f"{widget_url}/demo.html")

        # Widget trigger is primary CTA on demo page
        cta = page.locator('button.widget-trigger, button[aria-label*="call"]').first
        expect(cta).to_be_enabled()

        # Click should work
        cta.click()
        page.wait_for_timeout(1000)

        # Should trigger action (widget opens)
        chat_interface = page.locator('.chat-interface, .chat-window')
        expect(chat_interface).to_be_visible()


class TestResponsiveDesign:
    """
    Test responsive design across different viewports.

    From DEMO_RECORDING_SUMMARY.md:
    "Mobile responsive"
    """

    def test_mobile_layout(self, mobile_page, widget_url):
        """Verify mobile layout is functional."""
        mobile_page.goto(f"{widget_url}/demo.html")

        # Page should load on mobile
        expect(mobile_page.locator('body')).to_be_visible()

        # Widget trigger should be visible and accessible
        trigger = mobile_page.locator('button.widget-trigger, button[aria-label*="call"]').first
        expect(trigger).to_be_visible()

        # Should be sized appropriately (not cut off)
        box = trigger.bounding_box()
        assert box['width'] > 0, "Widget trigger has no width on mobile"
        assert box['height'] > 0, "Widget trigger has no height on mobile"

    def test_tablet_layout(self, tablet_page, widget_url):
        """Verify tablet layout is functional."""
        tablet_page.goto(f"{widget_url}/demo.html")

        expect(tablet_page.locator('body')).to_be_visible()

        trigger = tablet_page.locator('button.widget-trigger, button[aria-label*="call"]').first
        expect(trigger).to_be_visible()

    def test_desktop_layout(self, page, widget_url):
        """Verify desktop layout is optimal."""
        page.set_viewport_size({"width": 1920, "height": 1080})
        page.goto(f"{widget_url}/demo.html")

        expect(page.locator('body')).to_be_visible()

        trigger = page.locator('button.widget-trigger, button[aria-label*="call"]').first
        expect(trigger).to_be_visible()

    def test_no_horizontal_scroll_mobile(self, mobile_page, widget_url):
        """Verify no horizontal scrolling on mobile (responsive design)."""
        mobile_page.goto(f"{widget_url}/demo.html")

        # Check body doesn't overflow viewport
        body_width = mobile_page.locator('body').evaluate("el => el.scrollWidth")
        viewport_width = mobile_page.viewport_size['width']

        # Allow small tolerance (1-2px) for rounding
        assert body_width <= viewport_width + 2, f"Horizontal scroll detected: {body_width}px > {viewport_width}px"


class TestAccessibility:
    """Accessibility compliance tests."""

    def test_page_has_title(self, page, widget_url):
        """Verify page has a title for SEO and accessibility."""
        page.goto(f"{widget_url}/demo.html")

        title = page.title()
        assert len(title) > 0, "Page has no title"
        assert title != "Untitled", f"Page has placeholder title: {title}"

    def test_images_have_alt_text(self, page, widget_url):
        """Verify images have alt text for screen readers."""
        page.goto(f"{widget_url}/demo.html")

        images = page.locator('img')
        image_count = images.count()

        if image_count > 0:
            for i in range(image_count):
                img = images.nth(i)
                alt = img.get_attribute('alt')

                # Alt text should exist (can be empty for decorative images)
                assert alt is not None, f"Image {i} missing alt attribute"

    def test_headings_hierarchy(self, page, widget_url):
        """Verify proper heading hierarchy (h1 -> h2 -> h3)."""
        page.goto(f"{widget_url}/demo.html")

        h1_count = page.locator('h1').count()

        # Should have exactly one h1
        assert h1_count >= 1, "Page should have at least one h1 heading"

    def test_links_have_accessible_names(self, page, widget_url):
        """Verify links have accessible text."""
        page.goto(f"{widget_url}/demo.html")

        links = page.locator('a')
        link_count = links.count()

        if link_count > 0:
            for i in range(link_count):
                link = links.nth(i)
                text = link.inner_text()
                aria_label = link.get_attribute('aria-label')

                # Link should have text or aria-label
                assert text or aria_label, f"Link {i} has no accessible name"


class TestSEOBasics:
    """Basic SEO requirements."""

    def test_meta_description_present(self, page, widget_url):
        """Verify meta description exists for SEO."""
        page.goto(f"{widget_url}/demo.html")

        meta_desc = page.locator('meta[name="description"]')

        # Meta description should exist
        # (May not be present on demo page, but good practice)
        # This is informational, not critical for demo

    def test_viewport_meta_tag(self, page, widget_url):
        """Verify viewport meta tag for mobile."""
        page.goto(f"{widget_url}/demo.html")

        viewport_meta = page.locator('meta[name="viewport"]')
        count = viewport_meta.count()

        assert count > 0, "Missing viewport meta tag (required for responsive design)"

        content = viewport_meta.get_attribute('content')
        assert 'width=device-width' in content, "Viewport meta should include width=device-width"


class TestPerformanceMetrics:
    """Performance monitoring and metrics."""

    def test_resource_count_reasonable(self, page, widget_url):
        """Verify page doesn't load excessive resources."""
        requests = []
        page.on("request", lambda req: requests.append(req))

        page.goto(f"{widget_url}/demo.html")
        page.wait_for_load_state("networkidle")

        # Should have reasonable number of requests (<50 for simple page)
        assert len(requests) < 100, f"Too many network requests: {len(requests)}"

    def test_no_failed_resources(self, page, widget_url):
        """Verify all resources load successfully."""
        failed_resources = []

        page.on("response", lambda resp: failed_resources.append(resp.url) if resp.status >= 400 else None)

        page.goto(f"{widget_url}/demo.html")
        page.wait_for_load_state("networkidle")

        # Filter out known failures (favicon 404 is common)
        critical_failures = [
            url for url in failed_resources
            if "favicon" not in url.lower()
        ]

        assert len(critical_failures) == 0, f"Failed resources: {critical_failures}"

    def test_large_resources_warning(self, page, widget_url):
        """Warn if resources are too large (performance impact)."""
        large_resources = []

        page.on("response", lambda resp: large_resources.append({
            'url': resp.url,
            'size': len(resp.body()) if resp.ok and resp.body() else 0
        }) if resp.ok and len(resp.body() or b'') > 500_000 else None)

        page.goto(f"{widget_url}/demo.html")
        page.wait_for_load_state("networkidle")

        # Warn if any resource is >500KB (performance concern)
        if large_resources:
            print(f"Warning: Large resources detected: {large_resources}")


class TestHeroSection:
    """
    Test hero section with demo video/audio.

    Based on DEMO_RECORDING_SUMMARY.md hero page requirements.
    """

    def test_hero_section_visible(self, page, widget_url):
        """Verify hero section is prominent."""
        page.goto(f"{widget_url}/demo.html")

        # Hero section should be visible
        hero = page.locator('section.hero, .hero, [class*="hero"]').first

        # May not exist on demo page, but test if present
        if hero.count() > 0:
            expect(hero).to_be_visible()

    @pytest.mark.skip(reason="Demo audio/video may not be deployed yet")
    def test_audio_element_present(self, page, widget_url):
        """
        Verify demo audio is embedded in hero.

        From DEMO_RECORDING_SUMMARY.md:
        Hero page should have audio overlay with AIVA voice demo.
        """
        page.goto(f"{widget_url}/demo.html")

        audio = page.locator('audio')

        if audio.count() > 0:
            # Audio element exists
            expect(audio).to_be_attached()

            # Should have source(s)
            sources = page.locator('audio source')
            assert sources.count() > 0, "Audio element has no sources"
