from unittest.mock import patch

import pytest
from scripts.llm_triage import (
    get_context,
    get_prompt,
    parse_llm_response,
    run_triage,
)


# ── Mocks ──────────────────────────────────────────────────────────────────
@pytest.fixture
def mock_files(tmp_path):
    """Creates mock files for the triage script."""
    (tmp_path / ".loop/retro").mkdir(parents=True)
    (tmp_path / "scripts").mkdir(parents=True)

    (tmp_path / ".loop/queue.json").write_text("[]")
    (tmp_path / ".loop/retro/summary.json").write_text("{}")
    (tmp_path / ".loop/retro/deep-triage.jsonl").write_text("")
    (tmp_path / "scripts/deep_triage_prompt.md").write_text("This is the prompt.")

    return tmp_path


def test_get_prompt(mock_files):
    """Tests that the prompt is read correctly."""
    with patch("scripts.llm_triage.PROMPT_PATH", mock_files / "scripts/deep_triage_prompt.md"):
        prompt = get_prompt()
        assert prompt == "This is the prompt."


def test_get_context(mock_files):
    """Tests that the context is constructed correctly."""
    with (
        patch("scripts.llm_triage.QUEUE_PATH", mock_files / ".loop/queue.json"),
        patch("scripts.llm_triage.SUMMARY_PATH", mock_files / ".loop/retro/summary.json"),
        patch("scripts.llm_triage.RETRO_PATH", mock_files / ".loop/retro/deep-triage.jsonl"),
    ):
        context = get_context()
        assert "CURRENT QUEUE (.loop/queue.json):\\n[]" in context
        assert "CYCLE SUMMARY (.loop/retro/summary.json):\\n{}" in context
        assert "LAST DEEP TRIAGE RETRO:\\n" in context


def test_parse_llm_response():
    """Tests that the LLM's response is parsed correctly."""
    response = '{"queue": [1, 2, 3], "retro": {"a": 1}}'
    queue, retro = parse_llm_response(response)
    assert queue == [1, 2, 3]
    assert retro == {"a": 1}


@patch("scripts.llm_triage.get_llm_client")
@patch("scripts.llm_triage.GiteaClient")
def test_run_triage(mock_gitea_client, mock_llm_client, mock_files):
    """Tests the main triage logic."""
    mock_llm_client.return_value.chat.return_value = {
        "message": {
            "content": '{"queue": [{"issue": 1}], "retro": {"issues_closed": [2], "issues_created": [{"title": "New Issue", "body": "This is a new issue."}]}}'
        }
    }

    with (
        patch("scripts.llm_triage.PROMPT_PATH", mock_files / "scripts/deep_triage_prompt.md"),
        patch("scripts.llm_triage.QUEUE_PATH", mock_files / ".loop/queue.json"),
        patch("scripts.llm_triage.SUMMARY_PATH", mock_files / ".loop/retro/summary.json"),
        patch("scripts.llm_triage.RETRO_PATH", mock_files / ".loop/retro/deep-triage.jsonl"),
    ):
        run_triage()

        # Check that the queue and retro files were written
        assert (mock_files / ".loop/queue.json").read_text() == '[{"issue": 1}]'
        assert (
            (mock_files / ".loop/retro/deep-triage.jsonl").read_text()
            == '{"issues_closed": [2], "issues_created": [{"title": "New Issue", "body": "This is a new issue."}]}\n'
        )

        # Check that the Gitea client was called correctly
        mock_gitea_client.return_value.close_issue.assert_called_once_with(2)
        mock_gitea_client.return_value.create_issue.assert_called_once_with(
            "New Issue", "This is a new issue."
        )
