"""Step definitions for Workbench session lifecycle tests.

These tests verify that a session can be suspended and resumed.
Patterns adapted from test_ide_launch.py.
"""

from __future__ import annotations

import time
from pathlib import Path

import pytest
from playwright.sync_api import Page, expect
from pytest_bdd import given, scenario, then, when

from vip_tests.workbench.conftest import (
    TIMEOUT_CLEANUP,
    TIMEOUT_DIALOG,
    TIMEOUT_PAGE_LOAD,
    TIMEOUT_QUICK,
    TIMEOUT_SESSION_START,
    assert_homepage_loaded,
    workbench_login,
)
from vip_tests.workbench.pages import Homepage, NewSessionDialog

# Get filename for session naming
_FILENAME = Path(__file__).name


@scenario("test_sessions.feature", "Session can be suspended and resumed")
def test_session_suspend_resume():
    pass


# ---------------------------------------------------------------------------
# Shared state
# ---------------------------------------------------------------------------


@pytest.fixture
def session_context():
    """Holds session name across steps."""
    return {"name": None}


# ---------------------------------------------------------------------------
# Steps
# ---------------------------------------------------------------------------


@given("the user is logged in to Workbench")
def user_logged_in(
    page: Page,
    workbench_url: str,
    test_username: str,
    test_password: str,
    auth_provider: str,
    interactive_auth: bool,
):
    """Log in to Workbench and verify homepage loads."""
    workbench_login(
        page, workbench_url, test_username, test_password, auth_provider, interactive_auth
    )

    assert_homepage_loaded(page)


@when("the user starts a new RStudio Pro session")
def start_rstudio_pro_session(page: Page, session_context: dict):
    """Start a new RStudio Pro session without auto-joining."""
    session_name = f"VIP {_FILENAME} - {int(time.time())}"
    session_context["name"] = session_name

    page.locator(Homepage.NEW_SESSION_BUTTON).first.click(timeout=TIMEOUT_DIALOG)

    dialog = page.locator(NewSessionDialog.DIALOG)
    expect(dialog.locator(NewSessionDialog.TITLE)).to_have_text(
        "New Session", timeout=TIMEOUT_DIALOG
    )

    # Select RStudio Pro tab
    ide_display = NewSessionDialog.ide_display_name("RStudio")
    dialog.get_by_role("tab", name=ide_display).click(timeout=TIMEOUT_QUICK)

    page.fill(NewSessionDialog.SESSION_NAME, session_name)

    # Uncheck auto-join so we stay on homepage to observe state transitions
    checkbox = page.locator(NewSessionDialog.JOIN_CHECKBOX)
    if checkbox.is_checked():
        checkbox.click()
    expect(checkbox).not_to_be_checked(timeout=TIMEOUT_QUICK)

    page.locator(NewSessionDialog.LAUNCH_BUTTON).click(timeout=TIMEOUT_QUICK)


@when("the session reaches Active state")
def session_becomes_active(page: Page, session_context: dict):
    """Wait for the session to reach Active state on the homepage."""
    session_name = session_context["name"]

    session_row = page.locator(Homepage.session_row(session_name))
    expect(session_row).to_be_visible(timeout=TIMEOUT_PAGE_LOAD)

    session_active = page.locator(Homepage.session_row_status(session_name, "Active"))
    expect(session_active).to_be_visible(timeout=TIMEOUT_SESSION_START)


@when("the user suspends the session")
def user_suspends_session(page: Page, session_context: dict):
    """Select the session checkbox and click Suspend."""
    session_name = session_context["name"]

    checkbox = page.locator(Homepage.session_checkbox(session_name))
    expect(checkbox).to_be_visible(timeout=TIMEOUT_DIALOG)
    checkbox.click()

    suspend_btn = page.locator(Homepage.SUSPEND_BUTTON)
    expect(suspend_btn).to_be_visible(timeout=TIMEOUT_QUICK)
    suspend_btn.click()


@then("the session reaches Suspended state")
def session_becomes_suspended(page: Page, session_context: dict):
    """Verify the session transitions to Suspended state."""
    session_name = session_context["name"]

    session_suspended = page.locator(Homepage.session_row_status(session_name, "Suspended"))
    expect(session_suspended).to_be_visible(timeout=TIMEOUT_CLEANUP)


@when("the user resumes the session")
def user_resumes_session(page: Page, session_context: dict):
    """Click the suspended session link to resume it."""
    session_name = session_context["name"]

    session_row = page.locator(Homepage.session_row(session_name))
    expect(session_row).to_be_visible(timeout=TIMEOUT_DIALOG)

    # Clicking the session link on a suspended session resumes it
    session_link = session_row.locator(f"a[title='join {session_name}']")
    expect(session_link).to_be_visible(timeout=TIMEOUT_DIALOG)
    session_link.click()

    # Navigate back to homepage to observe the Active state
    page.go_back()
    expect(page.locator(Homepage.POSIT_LOGO)).to_be_visible(timeout=TIMEOUT_PAGE_LOAD)


@then("the session reaches Active state again")
def session_becomes_active_again(page: Page, session_context: dict):
    """Verify the session transitions back to Active state."""
    session_name = session_context["name"]

    session_active = page.locator(Homepage.session_row_status(session_name, "Active"))
    expect(session_active).to_be_visible(timeout=TIMEOUT_SESSION_START)


@then("the session is cleaned up")
def session_cleaned_up(page: Page, workbench_url: str, session_context: dict):
    """Navigate to homepage and quit the session."""
    session_name = session_context["name"]

    home_url = workbench_url.rstrip("/") + "/home"
    page.goto(home_url)
    expect(page.locator(Homepage.POSIT_LOGO)).to_be_visible(timeout=TIMEOUT_PAGE_LOAD)

    checkbox = page.locator(Homepage.session_checkbox(session_name))
    expect(checkbox).to_be_visible(timeout=TIMEOUT_DIALOG)
    checkbox.click()

    quit_btn = page.locator(Homepage.QUIT_BUTTON)
    expect(quit_btn).to_be_visible(timeout=TIMEOUT_QUICK)
    quit_btn.click()

    session_link = page.locator(Homepage.session_link(session_name))
    expect(session_link).not_to_be_visible(timeout=TIMEOUT_CLEANUP)
