"""
Step 10 — PWA Finalization & Polish tests.

Tests manifest presence and validity, service worker registration,
icon availability, and install prompt absence in test environment.
"""

import json
import pytest


def test_manifest_link_present(page, app_url):
    """HTML page includes a <link rel=manifest> pointing to /manifest.json."""
    page.goto(app_url)
    handle = page.query_selector('link[rel="manifest"]')
    assert handle is not None, "<link rel='manifest'> not found in <head>"
    href = handle.get_attribute("href")
    assert href == "/manifest.json", f"Unexpected manifest href: {href}"


def test_manifest_json_valid(page, app_url):
    """manifest.json is reachable, valid JSON, and has required PWA fields."""
    response = page.request.get(f"{app_url}/manifest.json")
    assert response.status == 200, f"manifest.json returned {response.status}"
    manifest = json.loads(response.text())
    assert manifest.get("name"), "manifest missing 'name'"
    assert manifest.get("display") == "standalone", "manifest display should be 'standalone'"
    icons = manifest.get("icons", [])
    assert len(icons) >= 2, "manifest should declare at least 2 icons"
    sizes = {icon["sizes"] for icon in icons}
    assert "192x192" in sizes, "192x192 icon missing from manifest"
    assert "512x512" in sizes, "512x512 icon missing from manifest"


def test_icon_192_accessible(page, app_url):
    """icon-192.png is served with a 200 status."""
    response = page.request.get(f"{app_url}/icon-192.png")
    assert response.status == 200, f"icon-192.png returned {response.status}"


def test_icon_512_accessible(page, app_url):
    """icon-512.png is served with a 200 status."""
    response = page.request.get(f"{app_url}/icon-512.png")
    assert response.status == 200, f"icon-512.png returned {response.status}"


def test_service_worker_registered(page, app_url):
    """Service worker is registered in the browser after page load."""
    page.goto(app_url)
    page.wait_for_selector('[data-testid="db-loading"]', state="detached", timeout=15000)
    registration = page.evaluate(
        "() => navigator.serviceWorker.getRegistration().then(r => !!r)"
    )
    assert registration, "No service worker registration found"


def test_install_prompt_hidden_by_default(page, app_url):
    """Install prompt button is not shown in the test environment (beforeinstallprompt not fired)."""
    page.goto(app_url)
    page.wait_for_selector('[data-testid="db-loading"]', state="detached", timeout=15000)
    btn = page.query_selector('[data-testid="install-prompt-btn"]')
    assert btn is None, "Install prompt button should not appear without beforeinstallprompt"


def test_favicon_linked(page, app_url):
    """HTML page includes a <link rel=icon> for the favicon."""
    page.goto(app_url)
    handle = page.query_selector('link[rel="icon"]')
    assert handle is not None, "<link rel='icon'> not found in <head>"


def test_apple_touch_icon_linked(page, app_url):
    """HTML page includes a <link rel=apple-touch-icon>."""
    page.goto(app_url)
    handle = page.query_selector('link[rel="apple-touch-icon"]')
    assert handle is not None, "<link rel='apple-touch-icon'> not found in <head>"


def test_nav_has_aria_label(page, app_url):
    """Main navigation has an aria-label for screen readers."""
    page.goto(app_url)
    page.wait_for_selector('[data-testid="db-loading"]', state="detached", timeout=15000)
    nav = page.query_selector("nav.navbar")
    assert nav is not None, "<nav class='navbar'> not found"
    aria_label = nav.get_attribute("aria-label")
    assert aria_label, "nav.navbar is missing aria-label"


def test_form_required_fields_marked(page, app_url):
    """Exercise form title input is marked as required."""
    page.goto(f"{app_url}/#/exercises/new")
    page.wait_for_selector('[data-testid="exercise-title"]', timeout=10000)
    required = page.get_attribute('[data-testid="exercise-title"]', "required")
    assert required is not None, "Exercise title input should have required attribute"


def test_progress_bar_has_aria_role(page, app_url):
    """Execution progress bar has role=progressbar with ARIA value attributes."""
    from playwright.sync_api import expect

    # Create an exercise and session first — skip if none exist, just verify structure
    page.goto(f"{app_url}/#/exercises")
    page.wait_for_selector('[data-testid="db-loading"]', state="detached", timeout=15000)

    exercises = page.query_selector_all('[data-testid^="exercise-card"]')
    sessions = []
    if exercises:
        page.goto(f"{app_url}/#/sessions")
        sessions = page.query_selector_all('[data-testid^="session-card"]')

    if not sessions:
        pytest.skip("No sessions available to test execution view progress bar")

    session_link = page.query_selector('[data-testid^="session-card"] a')
    session_link.click()
    page.wait_for_selector('[data-testid="session-execute-btn"]', timeout=5000)
    page.click('[data-testid="session-execute-btn"]')
    page.wait_for_selector('[data-testid="execute-progress"]', timeout=5000)

    bar = page.query_selector('[role="progressbar"]')
    assert bar is not None, "Progress bar should have role='progressbar'"
    assert bar.get_attribute("aria-valuemin") == "0"
    assert bar.get_attribute("aria-valuemax") is not None
