"""Port of github-adapter tests — GitHub Issues integration."""

from __future__ import annotations

import pytest

from specwright.parser.models import SectionStatus
from specwright.sync.adapters.github_issues import (
    GitHubAdapter,
    parse_github_ticket_id,
)
from specwright.sync.models import (
    CreateTicketInput,
    GitHubConfig,
    UpdateTicketInput,
)


@pytest.fixture
def config() -> GitHubConfig:
    return GitHubConfig(
        token="test-token",
        default_owner="Gerner-Ventures",
        default_repo="gv-exp-specwright",
    )


class TestParseGitHubTicketId:
    def test_bare_number(self, config: GitHubConfig):
        parsed = parse_github_ticket_id("7", config)
        assert parsed.owner == "Gerner-Ventures"
        assert parsed.repo == "gv-exp-specwright"
        assert parsed.issue_number == 7

    def test_repo_number(self, config: GitHubConfig):
        parsed = parse_github_ticket_id("other-repo#42", config)
        assert parsed.owner == "Gerner-Ventures"
        assert parsed.repo == "other-repo"
        assert parsed.issue_number == 42

    def test_full_format(self, config: GitHubConfig):
        parsed = parse_github_ticket_id("acme/widgets#99", config)
        assert parsed.owner == "acme"
        assert parsed.repo == "widgets"
        assert parsed.issue_number == 99

    def test_invalid_ticket_id_raises(self, config: GitHubConfig):
        with pytest.raises(ValueError, match="Invalid GitHub ticket ID"):
            parse_github_ticket_id("not-valid", config)


class TestGitHubAdapter:
    @pytest.mark.asyncio
    async def test_create_ticket(self, config: GitHubConfig, respx_mock):
        respx_mock.post(
            "https://api.github.com/repos/Gerner-Ventures/gv-exp-specwright/issues"
        ).respond(json={"number": 10, "html_url": "https://github.com/org/repo/issues/10"})

        adapter = GitHubAdapter(config)
        result = await adapter.create_ticket(
            CreateTicketInput(
                project_key="GV",
                summary="[1] Test Section",
                description="Content",
                status=SectionStatus(state="todo"),
            )
        )
        assert result.ticket_id == "10"
        assert "issues/10" in result.ticket_url

    @pytest.mark.asyncio
    async def test_create_ticket_closes_for_done_status(self, config: GitHubConfig, respx_mock):
        respx_mock.post(
            "https://api.github.com/repos/Gerner-Ventures/gv-exp-specwright/issues"
        ).respond(json={"number": 11, "html_url": "https://github.com/org/repo/issues/11"})
        respx_mock.patch(
            "https://api.github.com/repos/Gerner-Ventures/gv-exp-specwright/issues/11"
        ).respond(json={"number": 11, "state": "closed"})

        adapter = GitHubAdapter(config)
        result = await adapter.create_ticket(
            CreateTicketInput(
                project_key="GV",
                summary="Done section",
                description="Done",
                status=SectionStatus(state="done"),
            )
        )
        assert result.ticket_id == "11"

    @pytest.mark.asyncio
    async def test_get_ticket_status(self, config: GitHubConfig, respx_mock):
        respx_mock.get(
            "https://api.github.com/repos/Gerner-Ventures/gv-exp-specwright/issues/7"
        ).respond(
            json={
                "state": "open",
                "labels": [{"name": "specwright:in-progress"}, {"name": "bug"}],
            }
        )

        adapter = GitHubAdapter(config)
        result = await adapter.get_ticket_status("7")
        assert result.status.state == "in_progress"
        # raw_status is the specwright label (most meaningful status string)
        assert result.raw_status == "specwright:in-progress"

    @pytest.mark.asyncio
    async def test_get_ticket_status_fallback(self, config: GitHubConfig, respx_mock):
        respx_mock.get(
            "https://api.github.com/repos/Gerner-Ventures/gv-exp-specwright/issues/8"
        ).respond(json={"state": "closed", "labels": []})

        adapter = GitHubAdapter(config)
        result = await adapter.get_ticket_status("8")
        assert result.status.state == "done"

    @pytest.mark.asyncio
    async def test_update_ticket_with_status(self, config: GitHubConfig, respx_mock):
        respx_mock.get(
            "https://api.github.com/repos/Gerner-Ventures/gv-exp-specwright/issues/7"
        ).respond(
            json={
                "state": "open",
                "labels": [{"name": "specwright:todo"}, {"name": "feature"}],
            }
        )
        respx_mock.patch(
            "https://api.github.com/repos/Gerner-Ventures/gv-exp-specwright/issues/7"
        ).respond(json={"number": 7})

        adapter = GitHubAdapter(config)
        await adapter.update_ticket(
            UpdateTicketInput(
                ticket_id="7",
                status=SectionStatus(state="in_progress"),
            )
        )

    @pytest.mark.asyncio
    async def test_link_pr(self, config: GitHubConfig, respx_mock):
        respx_mock.post(
            "https://api.github.com/repos/Gerner-Ventures/gv-exp-specwright/issues/7/comments"
        ).respond(json={"id": 1})

        adapter = GitHubAdapter(config)
        await adapter.link_pr("7", "https://github.com/org/repo/pull/5", "Fix thing")
