import json
import subprocess
from pathlib import Path

import pytest

from tests.dashboard_bundle import dashboard


POSITIONER = Path(__file__).resolve().parents[1] / "frontend" / "work-detail-position.js"


def run_positioner(script: str) -> dict:
    source = f"const createPositioner = require({json.dumps(str(POSITIONER))});\n" + script
    result = subprocess.run(["node", "-e", source], capture_output=True, text=True)
    assert result.returncode == 0, result.stderr
    return json.loads(result.stdout)


def test_different_work_item_resets_to_top_while_same_item_keeps_position():
    result = run_positioner("""
const panel = {scrollTop:640};
const positioner = createPositioner({panel});
const first = positioner.open('issue:stackchain/dashboard#41');
panel.scrollTop = 380;
const same = positioner.open('issue:stackchain/dashboard#41');
const changed = positioner.open('pull:stackchain/dashboard#42');
process.stdout.write(JSON.stringify({first, same, changed, top:panel.scrollTop}));
""")

    assert result == {"first": True, "same": False, "changed": True, "top": 0}


def test_each_panel_tracks_its_own_visible_identity():
    result = run_positioner("""
const issuePanel = {scrollTop:500};
const pullPanel = {scrollTop:700};
const issue = createPositioner({panel:issuePanel});
const pull = createPositioner({panel:pullPanel});
issue.open('issue:stackchain/dashboard#8');
pull.open('pull:stackchain/dashboard#9');
issuePanel.scrollTop = 220;
pullPanel.scrollTop = 330;
issue.open('issue:stackchain/dashboard#8');
pull.open('review:stackchain/dashboard#9');
process.stdout.write(JSON.stringify({issueTop:issuePanel.scrollTop, pullTop:pullPanel.scrollTop}));
""")

    assert result == {"issueTop": 220, "pullTop": 0}


@pytest.mark.anyio
async def test_dashboard_positions_issue_pull_and_review_openers():
    html = await dashboard()

    assert '<script src="static/work-detail-position.js"></script>' in html
    assert "issueDetailPosition.open(workDetailIdentity('issue', item))" in html
    assert "pullDetailPosition.open(workDetailIdentity('pull', item))" in html
    assert "reviewDetailPosition.open(workDetailIdentity('review', item))" in html
    assert "BASE + 'static/work-detail-position.js'" in (POSITIONER.parent / "service-worker.js").read_text()
