import time
from tests.conftest import BASE_URL, assert_share_copies


def _set_cm_value(page, value):
    page.evaluate(f'''() => {{
        const cm = document.querySelector(".CodeMirror")?.CodeMirror;
        if (cm) {{
            cm.setValue({repr(value)});
            cm.save();
        }}
    }}''')


def _create_gist(page, title="Test Gist", description="Test description", language="python", source_code="print('hello')"):
    page.goto(f"{BASE_URL}/gists", wait_until="domcontentloaded")
    page.locator("#create-gist-btn").wait_for(state="visible", timeout=10000)
    page.locator("#create-gist-btn").click()
    page.wait_for_timeout(800)
    page.fill("#gist-title", title)
    page.fill("#gist-description", description)
    page.select_option("#gist-language", language)
    page.wait_for_timeout(300)
    _set_cm_value(page, source_code)
    page.wait_for_timeout(300)
    page.locator("button.btn-primary:has-text('Create Gist')").click()
    page.wait_for_timeout(2000)
    current = page.url
    if "/gists/" in current and current != f"{BASE_URL}/gists":
        return
    page.wait_for_url("**/gists/*", timeout=15000, wait_until="domcontentloaded")


def test_gist_listing_loads(page, app_server):
    page.goto(f"{BASE_URL}/gists", wait_until="domcontentloaded")
    assert page.is_visible("h1:has-text('Gists')")
    assert page.is_visible("text=Share and discover code snippets")


def test_gist_listing_empty(page, app_server):
    page.goto(f"{BASE_URL}/gists", wait_until="domcontentloaded")
    assert page.is_visible("text=No gists found")


def test_gist_listing_shows_sidebar(page, app_server):
    page.goto(f"{BASE_URL}/gists", wait_until="domcontentloaded")
    assert page.is_visible("text=Languages")
    assert page.is_visible("text=All")


def test_guest_cannot_create(page, app_server):
    page.goto(f"{BASE_URL}/gists", wait_until="domcontentloaded")
    assert not page.is_visible("#create-gist-btn")


def test_create_gist(alice, app_server):
    page, _ = alice
    title = f"Create Test {int(time.time())}"
    _create_gist(page, title=title, source_code="print('create test')")
    assert page.is_visible(f"text={title}")
    assert page.is_visible("text=Python")
    assert page.is_visible("text=print('create test')")


def test_gist_detail_shows_all_sections(alice, app_server):
    page, _ = alice
    title = f"Detail Test {int(time.time())}"
    _create_gist(page, title=title, description="See all sections", source_code="def hello(): pass")
    assert page.is_visible("text=See all sections")
    assert page.is_visible("text=def hello(): pass")
    assert page.is_visible("text=Copy")
    assert page.is_visible("text=Back to Gists")


def test_gist_detail_back_link(alice, app_server):
    page, _ = alice
    title = f"Back Link Test {int(time.time())}"
    _create_gist(page, title=title, source_code="x = 1")
    page.click("text=Back to Gists")
    page.wait_for_url(f"{BASE_URL}/gists", timeout=10000, wait_until="domcontentloaded")
    assert page.is_visible("h1:has-text('Gists')")


def test_edit_gist(alice, app_server):
    page, _ = alice
    title = f"Edit Test Original {int(time.time())}"
    _create_gist(page, title=title, source_code="x = 1")
    page.locator("button:has-text('Edit')").wait_for(state="visible", timeout=5000)
    page.click("button:has-text('Edit')")
    page.wait_for_timeout(800)
    new_title = f"Edit Test Updated {int(time.time())}"
    page.fill("#edit-gist-title", new_title)
    page.select_option("#edit-gist-language", "javascript")
    _set_cm_value(page, "const x = 1;")
    page.wait_for_timeout(300)
    page.locator("button.btn-primary:has-text('Save Changes')").click()
    page.wait_for_url("**/gists/*", timeout=15000, wait_until="domcontentloaded")
    assert page.is_visible(f"text={new_title}")
    assert page.is_visible("text=JavaScript")


def test_non_owner_cannot_edit_or_delete(bob, alice, app_server):
    bob_page, _ = bob
    alice_page, alice_user = alice
    title = f"Owner Check {int(time.time())}"
    _create_gist(alice_page, title=title, source_code="owner_only = True")
    slug = alice_page.url.split("/gists/")[-1]
    bob_page.goto(f"{BASE_URL}/gists/{slug}", wait_until="domcontentloaded")
    assert not bob_page.is_visible("button:has-text('Edit')")
    assert not bob_page.is_visible("button:has-text('Delete')")


def test_delete_gist(alice, app_server):
    page, _ = alice
    title = f"Delete Test {int(time.time())}"
    _create_gist(page, title=title, source_code="delete_me = True")
    page.locator("button:has-text('Delete')").wait_for(state="visible", timeout=5000)
    page.once("dialog", lambda dialog: dialog.accept())
    page.click("button:has-text('Delete')")
    page.wait_for_url(f"{BASE_URL}/gists", timeout=10000, wait_until="domcontentloaded")


def test_gist_voting(alice, app_server):
    page, _ = alice
    title = f"Vote Test {int(time.time())}"
    _create_gist(page, title=title, source_code="vote_me = True")
    star_btn = page.locator("form[action*='/votes/gist/'] button").first
    original_text = star_btn.text_content()
    original_stars = int(original_text.strip("\u2606 "))
    star_btn.click()
    page.wait_for_timeout(500)
    star_btn = page.locator("form[action*='/votes/gist/'] button").first
    new_text = star_btn.text_content()
    new_stars = int(new_text.strip("\u2606 "))
    assert new_stars == original_stars + 1


def test_gist_detail_has_sourcecode_schema(alice, app_server):
    page, _ = alice
    _create_gist(page, title=f"Schema Gist {int(time.time())}", source_code="x = 1")
    scripts = page.locator('script[type="application/ld+json"]')
    text = " ".join(scripts.nth(i).text_content() for i in range(scripts.count()))
    assert "SoftwareSourceCode" in text


def test_gist_detail_share_button(alice, app_server):
    page, _ = alice
    _create_gist(page, title=f"Share Gist {int(time.time())}", source_code="x = 1")
    assert_share_copies(page, "/gists/")


def test_profile_gists_tab(alice, app_server):
    page, alice_user = alice
    title = f"Profile Tab Test {int(time.time())}"
    _create_gist(page, title=title, source_code="profile_tab = True")
    page.goto(f"{BASE_URL}/profile/{alice_user['username']}?tab=gists", wait_until="domcontentloaded")
    assert page.is_visible(f"text={title}")


def test_language_filter(alice, app_server):
    page, _ = alice
    title = f"Lang Filter Test {int(time.time())}"
    _create_gist(page, title=title, language="go", source_code="package main")
    page.goto(f"{BASE_URL}/gists?language=go", wait_until="domcontentloaded")
    assert page.is_visible(f"text={title}")
    page.goto(f"{BASE_URL}/gists?language=python", wait_until="domcontentloaded")
    assert not page.is_visible(f"text={title}")


def test_gist_comments(alice, app_server):
    page, _ = alice
    title = f"Comment Test {int(time.time())}"
    _create_gist(page, title=title, source_code="has_comments = True")
    comment_text = f"Nice gist! {int(time.time())}"
    comment_input = page.locator("textarea[name='content']").first
    comment_input.wait_for(state="visible", timeout=5000)
    comment_input.fill(comment_text)
    page.locator("button.comment-form-submit").first.click()
    page.wait_for_url("**/gists/*", timeout=10000, wait_until="domcontentloaded")
    assert page.is_visible(f"text={comment_text}")


def test_gist_listing_shows_created_gist(alice, app_server):
    page, _ = alice
    title = f"Listing Shows {int(time.time())}"
    _create_gist(page, title=title, source_code="show_in_list = True")
    page.goto(f"{BASE_URL}/gists", wait_until="domcontentloaded")
    assert page.is_visible(f"text={title}")
