"""Feature 3: stage visibility on the Plane board.

  * PLANE_STATES carries the 6 new per-stage / verdict UUIDs.
  * STAGE_TO_STATE maps architecture/development/review/testing to their
    dedicated board statuses (not all -> In Progress anymore).
  * set_issue_stage_state(work_item_id, stage) PATCHes the correct state UUID
    for a visible stage, and is a no-op for stages without one (analysis/deploy).
  * Needs Input / In Review / Blocked remain higher priority: their explicit
    setters use their own state, never overwritten by the stage map.

httpx is mocked; no network.
"""

import os

os.environ.setdefault("ORCH_PLANE_API_TOKEN", "test-token")
os.environ.setdefault("ORCH_GITEA_TOKEN", "test-token")

from unittest.mock import patch, MagicMock  # noqa: E402

from src import plane_sync as PS  # noqa: E402


EXPECTED_UUIDS = {
    "architecture": "3020bbb7-6122-4663-930c-0315ba8dfa3d",
    "development": "9920609b-f140-4e46-ab95-89acda8412c8",
    "review": "ba0d802c-5218-41d4-ab43-978b0ea123ed",
    "testing": "7855d807-b1bf-42ef-8dae-6cde0df92d02",
    "approved": "a519a341-dada-4a91-8910-7604f82b79c5",
    "rejected": "ba958f3c-5db5-461d-8f82-89425e413b97",
}


def test_plane_states_has_new_uuids():
    for key, uuid in EXPECTED_UUIDS.items():
        assert PS.PLANE_STATES[key] == uuid


def test_stage_to_state_maps_visible_stages():
    assert PS.STAGE_TO_STATE["architecture"] == EXPECTED_UUIDS["architecture"]
    assert PS.STAGE_TO_STATE["development"] == EXPECTED_UUIDS["development"]
    assert PS.STAGE_TO_STATE["review"] == EXPECTED_UUIDS["review"]
    assert PS.STAGE_TO_STATE["testing"] == EXPECTED_UUIDS["testing"]
    # analysis / deploy stay on In Progress; done stays Done.
    assert PS.STAGE_TO_STATE["analysis"] == PS.PLANE_STATES["in_progress"]
    assert PS.STAGE_TO_STATE["deploy"] == PS.PLANE_STATES["in_progress"]
    assert PS.STAGE_TO_STATE["done"] == PS.PLANE_STATES["done"]


def _patch_resolution(monkey_targets):
    """Helper: patch find_issue_id + _resolve_project_id to skip the DB/network."""
    return monkey_targets


@patch("src.plane_sync.httpx.patch")
@patch("src.plane_sync.find_issue_id", return_value="issue-uuid")
@patch("src.plane_sync._resolve_project_id", return_value="proj-1")
def test_set_issue_stage_state_patches_correct_uuid(mock_proj, mock_find, mock_patch):
    resp = MagicMock(); resp.raise_for_status.return_value = None
    mock_patch.return_value = resp

    PS.set_issue_stage_state("ET-1", "development")
    # the PATCH carried the development state UUID
    _, kwargs = mock_patch.call_args
    assert kwargs["json"]["state"] == EXPECTED_UUIDS["development"]


@patch("src.plane_sync.httpx.patch")
@patch("src.plane_sync.find_issue_id", return_value="issue-uuid")
@patch("src.plane_sync._resolve_project_id", return_value="proj-1")
def test_set_issue_stage_state_noop_for_deploy(mock_proj, mock_find, mock_patch):
    # ORCH-066: analysis now HAS a dedicated status (Analysis) -> it PATCHes.
    # deploy still has no board status here (driven by Phase A/B/C) -> no-op.
    resp = MagicMock()
    resp.raise_for_status.return_value = None
    mock_patch.return_value = resp

    PS.set_issue_stage_state("ET-1", "analysis")
    # analysis aliases in_progress when the Analysis status is absent.
    assert mock_patch.call_args.kwargs["json"]["state"] == PS.PLANE_STATES["analysis"]

    mock_patch.reset_mock()
    PS.set_issue_stage_state("ET-1", "deploy")
    mock_patch.assert_not_called()


@patch("src.plane_sync.httpx.patch")
@patch("src.plane_sync.find_issue_id", return_value="issue-uuid")
@patch("src.plane_sync._resolve_project_id", return_value="proj-1")
def test_priority_states_use_their_own_uuid(mock_proj, mock_find, mock_patch):
    """Needs Input / In Review / Blocked are set explicitly and take priority."""
    resp = MagicMock(); resp.raise_for_status.return_value = None
    mock_patch.return_value = resp

    PS.set_issue_needs_input("ET-1")
    assert mock_patch.call_args.kwargs["json"]["state"] == PS.PLANE_STATES["needs_input"]

    PS.set_issue_in_review("ET-1")
    assert mock_patch.call_args.kwargs["json"]["state"] == PS.PLANE_STATES["in_review"]

    PS.set_issue_blocked("ET-1")
    assert mock_patch.call_args.kwargs["json"]["state"] == PS.PLANE_STATES["blocked"]
