"""
Step 12 — Timers & Combo Execution Tests

- test_tabata_form_inputs_shown: TABATA combo form shows work/rest time inputs
- test_tabata_form_inputs_not_shown_for_other_types: Work/rest inputs hidden for non-TABATA types
- test_tabata_timer_config_saved: TABATA work/rest times saved to timer_config
- test_amrap_label_in_session_form: AMRAP combo item shows "Duration (min)" label
- test_amrap_label_in_session_detail: AMRAP combo item shows minutes in detail view
- test_emom_timer_visible: EMOM combo steps show a timer display
- test_emom_timer_pause_resume: Pause button toggles pause state on EMOM timer
- test_emom_done_early_advances: Tapping Done during EMOM advances to next step immediately
- test_emom_auto_advance: EMOM timer auto-advances to next step after 60 seconds
- test_amrap_timer_visible: AMRAP combo steps show a timer display
- test_amrap_manual_done_cycles: Done button manually advances through AMRAP exercises
- test_amrap_timeup_screen: Time-up overlay appears when AMRAP timer expires
- test_amrap_continue_advances: Continue after time-up advances past AMRAP combo
- test_tabata_work_phase_shows_timer: TABATA shows timer on work phase
- test_tabata_rest_screen_after_work: REST screen appears after work phase timer expires
- test_tabata_advances_after_rest: Next exercise appears after rest phase timer expires
- test_tabata_pause_during_work: Pause freezes TABATA work timer
- test_tabata_pause_during_rest: Pause freezes TABATA rest timer
- test_non_timed_combo_unchanged: NONE-type combos still show final-round screen as before
"""
import pytest
from playwright.sync_api import Page, expect


# ── helpers ───────────────────────────────────────────────────────────────────


def _wait_for_db(page: Page, app_url: str):
    page.goto(app_url)
    page.wait_for_function(
        "document.documentElement.getAttribute('data-db-ready') === 'true'",
        timeout=15000,
    )


def _wait_for_execute(page: Page):
    page.wait_for_selector('[data-testid="execute-session-title"]', timeout=10000)
    page.wait_for_timeout(400)


def _create_exercise(page: Page, title: str, default_reps=10, default_weight=0.0):
    return page.evaluate(f"""async () => {{
        const userId = await window.__repos.settings.get('user_uuid')
        return window.__repos.exercises.create({{
            title: {repr(title)}, description: '', asymmetric: false, alternate: false,
            image_urls: '[]', video_urls: '[]',
            default_reps: {default_reps}, default_weight: {default_weight},
            created_by: userId
        }})
    }}""")


def _create_timed_combo(page: Page, title: str, combo_type: str, exercise_ids: list,
                         timer_config: dict = None):
    if timer_config is None:
        timer_config = {}
    import json
    tc_json = json.dumps(timer_config)
    ex_json = str([{"exerciseId": eid, "defaultReps": 10, "defaultWeight": 0}
                   for eid in exercise_ids]).replace("'", '"')
    return page.evaluate(f"""async () => {{
        const userId = await window.__repos.settings.get('user_uuid')
        const comboId = await window.__repos.combos.create({{
            title: {repr(title)}, description: '', type: {repr(combo_type)},
            timer_config: {tc_json}, created_by: userId
        }})
        const exercises = {ex_json}
        await window.__repos.combos.setExercises(comboId, exercises)
        return comboId
    }}""")


def _create_session_with_items(page: Page, title: str, items: list):
    import json
    items_json = json.dumps(items)
    return page.evaluate(f"""async () => {{
        const userId = await window.__repos.settings.get('user_uuid')
        const sessId = await window.__repos.sessions.create({{
            title: {repr(title)}, description: '', created_by: userId
        }})
        const items = {items_json}
        await window.__repos.sessions.setItems(sessId, items.map((it, i) => ({{
            item_id: it.item_id, item_type: it.item_type,
            position: i, repetitions: it.repetitions, weight: it.weight || 0
        }})))
        return sessId
    }}""")


def _clean_all(page: Page):
    page.evaluate("""async () => {
        const sessions = await window.__repos.sessions.getAll()
        for (const s of sessions) await window.__repos.sessions.delete(s.id)
        const combos = await window.__repos.combos.getAll()
        for (const c of combos) await window.__repos.combos.delete(c.id)
        const exercises = await window.__repos.exercises.getAll()
        for (const e of exercises) await window.__repos.exercises.delete(e.id)
    }""")


def _navigate_to_execute(page: Page, app_url: str, sess_id: str):
    page.goto(f"{app_url}#/sessions/{sess_id}/execute")
    _wait_for_execute(page)


# ── Combo form ────────────────────────────────────────────────────────────────


def test_tabata_form_inputs_shown(page: Page, app_url: str, browser_name: str):
    """TABATA combo form shows work time and rest time inputs."""
    _wait_for_db(page, app_url)
    page.goto(f"{app_url}#/combos/new")
    page.wait_for_selector('[data-testid="combo-type"]', timeout=5000)

    # Before selecting TABATA, inputs should not be visible
    expect(page.locator('[data-testid="combo-tabata-work-time"]')).not_to_be_visible()
    expect(page.locator('[data-testid="combo-tabata-rest-time"]')).not_to_be_visible()

    # Select TABATA
    page.select_option('[data-testid="combo-type"]', "TABATA")
    expect(page.locator('[data-testid="combo-tabata-work-time"]')).to_be_visible()
    expect(page.locator('[data-testid="combo-tabata-rest-time"]')).to_be_visible()


def test_tabata_form_inputs_not_shown_for_other_types(page: Page, app_url: str, browser_name: str):
    """Work/rest inputs are hidden for EMOM and AMRAP types."""
    _wait_for_db(page, app_url)
    page.goto(f"{app_url}#/combos/new")
    page.wait_for_selector('[data-testid="combo-type"]', timeout=5000)

    for combo_type in ["EMOM", "AMRAP", "NONE"]:
        page.select_option('[data-testid="combo-type"]', combo_type)
        expect(page.locator('[data-testid="combo-tabata-work-time"]')).not_to_be_visible()
        expect(page.locator('[data-testid="combo-tabata-rest-time"]')).not_to_be_visible()


def test_tabata_timer_config_saved(page: Page, app_url: str, browser_name: str):
    """TABATA work/rest times are persisted in timer_config."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    page.goto(f"{app_url}#/combos/new")
    page.wait_for_selector('[data-testid="combo-type"]', timeout=5000)

    page.fill('[data-testid="combo-title"]', "My Tabata")
    page.select_option('[data-testid="combo-type"]', "TABATA")
    page.fill('[data-testid="combo-tabata-work-time"]', "15")
    page.fill('[data-testid="combo-tabata-rest-time"]', "5")
    page.click('[data-testid="combo-save"]')
    page.wait_for_selector('[data-testid="combo-detail-title"]', timeout=8000)

    combo_id = page.url.split("/")[-1]
    timer_config = page.evaluate(f"""async () => {{
        const c = await window.__repos.combos.getById({repr(combo_id)})
        return c.timer_config
    }}""")
    assert timer_config.get("workTime") == 15
    assert timer_config.get("restTime") == 5


# ── Session form / detail labels for AMRAP ────────────────────────────────────


def test_amrap_label_in_session_form(page: Page, app_url: str, browser_name: str):
    """AMRAP combo items show 'Duration (min)' instead of 'Reps' in session form."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex_id = _create_exercise(page, "Jump")
    amrap_id = _create_timed_combo(page, "AMRAP Combo", "AMRAP", [ex_id])
    none_id = _create_timed_combo(page, "None Combo", "NONE", [ex_id])

    page.goto(f"{app_url}#/sessions/new")
    page.wait_for_selector('[data-testid="session-title"]', timeout=5000)

    # Add AMRAP combo
    page.select_option('[data-testid="session-item-type-select"]', "combo")
    page.wait_for_timeout(300)
    page.select_option('[data-testid="session-item-select"]', amrap_id)
    page.click('[data-testid="session-item-add"]')
    page.wait_for_timeout(300)

    # The reps label for AMRAP item should say "Duration (min)"
    label = page.locator('[data-testid="session-item-0"] label').first.inner_text()
    assert "min" in label.lower() or "duration" in label.lower()

    # Add NONE combo
    page.select_option('[data-testid="session-item-type-select"]', "combo")
    page.wait_for_timeout(300)
    page.select_option('[data-testid="session-item-select"]', none_id)
    page.click('[data-testid="session-item-add"]')
    page.wait_for_timeout(300)

    # The reps label for NONE combo should say "Reps" (not duration)
    label2 = page.locator('[data-testid="session-item-1"] label').first.inner_text()
    assert "rep" in label2.lower() or label2.lower() == "reps"


def test_amrap_label_in_session_detail(page: Page, app_url: str, browser_name: str):
    """AMRAP combo items show minutes unit in session detail view."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex_id = _create_exercise(page, "Burpee")
    amrap_id = _create_timed_combo(page, "AMRAP Detail", "AMRAP", [ex_id])
    sess_id = _create_session_with_items(page, "AMRAP Session", [
        {"item_id": amrap_id, "item_type": "combo", "repetitions": 10, "weight": 0}
    ])

    page.goto(f"{app_url}#/sessions/{sess_id}")
    page.wait_for_selector('[data-testid="session-detail-title"]', timeout=5000)

    detail_text = page.locator('[data-testid="session-detail-item-details-0"]').inner_text()
    # Should show "10 minutes" (not "10 reps")
    assert "10" in detail_text
    assert "min" in detail_text.lower()


# ── EMOM timer ────────────────────────────────────────────────────────────────


def test_emom_timer_visible(page: Page, app_url: str, browser_name: str):
    """EMOM combo steps show a timer display."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex_id = _create_exercise(page, "EMOM Press")
    combo_id = _create_timed_combo(page, "EMOM Combo", "EMOM", [ex_id])
    sess_id = _create_session_with_items(page, "EMOM Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    timer = page.locator('[data-testid="execute-timer"]')
    expect(timer).to_be_visible()
    # Should show countdown format MM:SS
    timer_text = timer.inner_text()
    assert ":" in timer_text


def test_emom_timer_pause_resume(page: Page, app_url: str, browser_name: str):
    """Pause button toggles pause state — button label changes."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex_id = _create_exercise(page, "EMOM Press P")
    combo_id = _create_timed_combo(page, "EMOM Pause Combo", "EMOM", [ex_id])
    sess_id = _create_session_with_items(page, "EMOM Pause Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    timer = page.locator('[data-testid="execute-timer"]')
    expect(timer).to_be_visible()

    # Initially timer is running — button should say Pause
    pause_btn = timer.locator('button')
    initial_label = pause_btn.inner_text()
    assert "pause" in initial_label.lower() or "pause" in pause_btn.get_attribute("aria-label", "").lower()

    # Click pause
    pause_btn.click()
    page.wait_for_timeout(300)

    # Button should now say Resume
    resume_label = pause_btn.inner_text()
    assert "resume" in resume_label.lower() or "resume" in pause_btn.get_attribute("aria-label", "").lower()

    # Click again to resume
    pause_btn.click()
    page.wait_for_timeout(300)

    after_resume = pause_btn.inner_text()
    assert "pause" in after_resume.lower() or "pause" in pause_btn.get_attribute("aria-label", "").lower()


def test_emom_done_early_advances(page: Page, app_url: str, browser_name: str):
    """Tapping Done during EMOM advances to the next step immediately."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex1 = _create_exercise(page, "EMOM Ex1")
    ex2 = _create_exercise(page, "EMOM Ex2")
    combo_id = _create_timed_combo(page, "EMOM Two", "EMOM", [ex1, ex2])
    sess_id = _create_session_with_items(page, "EMOM Two Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    # We're on step 1 (EMOM Ex1)
    expect(page.locator('[data-testid="execute-exercise-title"]')).to_have_text("EMOM Ex1")

    # Tap Done early (should advance without waiting 60 seconds)
    page.click('[data-testid="execute-done-btn"]')
    page.wait_for_timeout(500)

    # Now we should be on step 2
    expect(page.locator('[data-testid="execute-exercise-title"]')).to_have_text("EMOM Ex2")


def test_emom_auto_advance(page: Page, app_url: str, browser_name: str):
    """EMOM timer auto-advances to next step after 60 seconds."""
    page.clock.install()
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex1 = _create_exercise(page, "EMOM Auto1")
    ex2 = _create_exercise(page, "EMOM Auto2")
    combo_id = _create_timed_combo(page, "EMOM Auto", "EMOM", [ex1, ex2])
    sess_id = _create_session_with_items(page, "EMOM Auto Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)
    expect(page.locator('[data-testid="execute-exercise-title"]')).to_have_text("EMOM Auto1")

    # Advance 61 seconds — timer should fire and auto-advance
    page.clock.run_for(61000)
    page.wait_for_timeout(500)

    expect(page.locator('[data-testid="execute-exercise-title"]')).to_have_text("EMOM Auto2")


# ── AMRAP timer ───────────────────────────────────────────────────────────────


def test_amrap_timer_visible(page: Page, app_url: str, browser_name: str):
    """AMRAP combo steps show a timer display."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex_id = _create_exercise(page, "AMRAP Ex")
    combo_id = _create_timed_combo(page, "AMRAP Combo Vis", "AMRAP", [ex_id])
    sess_id = _create_session_with_items(page, "AMRAP Vis Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 5, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    timer = page.locator('[data-testid="execute-timer"]')
    expect(timer).to_be_visible()
    # Timer should show 05:00 (5 minutes)
    timer_text = timer.inner_text()
    assert "05:00" in timer_text or "5:" in timer_text


def test_amrap_manual_done_cycles(page: Page, app_url: str, browser_name: str):
    """Done button manually cycles through AMRAP exercises (auto-adds next round)."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex1 = _create_exercise(page, "AMRAP Cycle1")
    ex2 = _create_exercise(page, "AMRAP Cycle2")
    combo_id = _create_timed_combo(page, "AMRAP Cycle", "AMRAP", [ex1, ex2])
    sess_id = _create_session_with_items(page, "AMRAP Cycle Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 3, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    # Step 1: AMRAP Cycle1
    expect(page.locator('[data-testid="execute-exercise-title"]')).to_have_text("AMRAP Cycle1")

    # Done → advances to AMRAP Cycle2
    page.click('[data-testid="execute-done-btn"]')
    page.wait_for_timeout(400)
    expect(page.locator('[data-testid="execute-exercise-title"]')).to_have_text("AMRAP Cycle2")

    # Done → auto-cycles back to AMRAP Cycle1 (round 2)
    page.click('[data-testid="execute-done-btn"]')
    page.wait_for_timeout(400)
    expect(page.locator('[data-testid="execute-exercise-title"]')).to_have_text("AMRAP Cycle1")


def test_amrap_timeup_screen(page: Page, app_url: str, browser_name: str):
    """Time-up overlay appears when AMRAP timer expires."""
    page.clock.install()
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex_id = _create_exercise(page, "AMRAP TimeUp Ex")
    combo_id = _create_timed_combo(page, "AMRAP TimeUp", "AMRAP", [ex_id])
    sess_id = _create_session_with_items(page, "AMRAP TimeUp Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    # Advance 61 seconds (1 minute AMRAP)
    page.clock.run_for(61000)
    page.wait_for_timeout(500)

    timeup = page.locator('[data-testid="execute-amrap-timeup"]')
    expect(timeup).to_be_visible()


def test_amrap_continue_advances(page: Page, app_url: str, browser_name: str):
    """Continue after AMRAP time-up advances to the next session item."""
    page.clock.install()
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex_amrap = _create_exercise(page, "AMRAP Cont Ex")
    ex_next = _create_exercise(page, "After AMRAP")
    combo_id = _create_timed_combo(page, "AMRAP Cont", "AMRAP", [ex_amrap])
    sess_id = _create_session_with_items(page, "AMRAP Cont Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0},
        {"item_id": ex_next, "item_type": "exercise", "repetitions": 5, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    # Expire the AMRAP timer
    page.clock.run_for(61000)
    page.wait_for_timeout(500)

    expect(page.locator('[data-testid="execute-amrap-timeup"]')).to_be_visible()

    # Click Continue
    page.click('[data-testid="execute-amrap-continue-btn"]')
    page.wait_for_timeout(400)

    # Should now be on the next exercise
    expect(page.locator('[data-testid="execute-exercise-title"]')).to_have_text("After AMRAP")


# ── TABATA timer ──────────────────────────────────────────────────────────────


def test_tabata_work_phase_shows_timer(page: Page, app_url: str, browser_name: str):
    """TABATA step shows timer during work phase."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex_id = _create_exercise(page, "TABATA Work Ex")
    combo_id = _create_timed_combo(page, "TABATA Work", "TABATA", [ex_id],
                                    timer_config={"workTime": 30, "restTime": 10})
    sess_id = _create_session_with_items(page, "TABATA Work Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    timer = page.locator('[data-testid="execute-timer"]')
    expect(timer).to_be_visible()
    timer_text = timer.inner_text()
    assert ":" in timer_text


def test_tabata_rest_screen_after_work(page: Page, app_url: str, browser_name: str):
    """REST screen appears after TABATA work phase timer expires (using short times)."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex_id = _create_exercise(page, "TABATA Rest Ex")
    combo_id = _create_timed_combo(page, "TABATA Rest", "TABATA", [ex_id],
                                    timer_config={"workTime": 2, "restTime": 10})
    sess_id = _create_session_with_items(page, "TABATA Rest Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    # Wait for work phase to expire (2 seconds + margin)
    page.wait_for_timeout(3500)

    rest_card = page.locator('[data-testid="execute-tabata-rest"]')
    expect(rest_card).to_be_visible()


def test_tabata_advances_after_rest(page: Page, app_url: str, browser_name: str):
    """Next exercise appears after TABATA rest phase timer expires."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex1 = _create_exercise(page, "TABATA Adv1")
    ex2 = _create_exercise(page, "TABATA Adv2")
    combo_id = _create_timed_combo(page, "TABATA Adv", "TABATA", [ex1, ex2],
                                    timer_config={"workTime": 2, "restTime": 1})
    sess_id = _create_session_with_items(page, "TABATA Adv Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    # Step 1 is TABATA Adv1
    expect(page.locator('[data-testid="execute-exercise-title"]')).to_have_text("TABATA Adv1")

    # Wait for work (2s) + rest (1s) + margin → Playwright polls until ex2 appears
    expect(page.locator('[data-testid="execute-exercise-title"]')).to_have_text(
        "TABATA Adv2", timeout=8000
    )


def test_tabata_done_starts_rest(page: Page, app_url: str, browser_name: str):
    """Tapping Done during TABATA work phase starts the rest phase immediately."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex1 = _create_exercise(page, "TABATA Done1")
    ex2 = _create_exercise(page, "TABATA Done2")
    combo_id = _create_timed_combo(page, "TABATA Done", "TABATA", [ex1, ex2],
                                    timer_config={"workTime": 60, "restTime": 60})
    sess_id = _create_session_with_items(page, "TABATA Done Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    expect(page.locator('[data-testid="execute-exercise-title"]')).to_have_text("TABATA Done1")

    # Tap Done early — should start rest phase
    page.click('[data-testid="execute-done-btn"]')
    page.wait_for_timeout(400)

    rest_card = page.locator('[data-testid="execute-tabata-rest"]')
    expect(rest_card).to_be_visible()


def test_tabata_pause_during_work(page: Page, app_url: str, browser_name: str):
    """Pause freezes TABATA work timer — REST screen does not appear while paused."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex_id = _create_exercise(page, "TABATA Pause Ex")
    combo_id = _create_timed_combo(page, "TABATA Pause", "TABATA", [ex_id],
                                    timer_config={"workTime": 2, "restTime": 1})
    sess_id = _create_session_with_items(page, "TABATA Pause Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    timer = page.locator('[data-testid="execute-timer"]')
    expect(timer).to_be_visible()

    # Pause immediately
    timer.locator('button').click()
    page.wait_for_timeout(3500)  # Wait longer than workTime (2s)

    # Timer is paused — REST screen should NOT appear
    expect(page.locator('[data-testid="execute-tabata-rest"]')).not_to_be_visible()
    expect(page.locator('[data-testid="execute-current-step"]')).to_be_visible()


def test_tabata_pause_during_rest(page: Page, app_url: str, browser_name: str):
    """Pause freezes TABATA rest timer — next exercise does not appear while paused."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex1 = _create_exercise(page, "TABATA PauseR1")
    ex2 = _create_exercise(page, "TABATA PauseR2")
    combo_id = _create_timed_combo(page, "TABATA PauseR", "TABATA", [ex1, ex2],
                                    timer_config={"workTime": 2, "restTime": 10})
    sess_id = _create_session_with_items(page, "TABATA PauseR Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    # Wait for work phase to complete (2s)
    page.wait_for_timeout(3000)

    rest_card = page.locator('[data-testid="execute-tabata-rest"]')
    expect(rest_card).to_be_visible()

    # Pause during rest
    rest_card.locator('button').click()
    page.wait_for_timeout(3000)  # Wait well beyond rest time (paused)

    # Should still be on rest screen (not advanced to ex2)
    expect(rest_card).to_be_visible()
    expect(page.locator('[data-testid="execute-exercise-title"]')).not_to_be_visible()


# ── Non-timed combo unchanged ─────────────────────────────────────────────────


def test_non_timed_combo_unchanged(page: Page, app_url: str, browser_name: str):
    """NONE-type combos still show the final-round screen — no timer displayed."""
    _wait_for_db(page, app_url)
    _clean_all(page)

    ex_id = _create_exercise(page, "None Combo Ex")
    combo_id = _create_timed_combo(page, "None Combo", "NONE", [ex_id])
    sess_id = _create_session_with_items(page, "None Session", [
        {"item_id": combo_id, "item_type": "combo", "repetitions": 1, "weight": 0}
    ])

    _navigate_to_execute(page, app_url, sess_id)

    # No timer should be shown
    expect(page.locator('[data-testid="execute-timer"]')).not_to_be_visible()

    # Tap Done
    page.click('[data-testid="execute-done-btn"]')
    page.wait_for_timeout(400)

    # Final-round screen should appear (unchanged from Step 8 behaviour)
    expect(page.locator('[data-testid="execute-final-round"]')).to_be_visible()
    expect(page.locator('[data-testid="execute-continue-btn"]')).to_be_visible()
    expect(page.locator('[data-testid="execute-one-more-btn"]')).to_be_visible()
