import json
import tempfile
import unittest
from pathlib import Path

from sprint_forecast.integrations.zenhub_sprint_issues import build_work_items_from_zenhub_sprint
from zenhub_client.models import SprintInfo, SprintIssue


class _FakeSprints:
    def __init__(self, sprint: SprintInfo, issues: list[SprintIssue]) -> None:
        self._sprint = sprint
        self._issues = issues

    def get_current_open_sprint(self, workspace_id: str) -> SprintInfo:  # noqa: ARG002
        return self._sprint

    def get_sprint_issues(self, sprint_id: str, *, workspace_id: str):  # noqa: ARG002
        return self._sprint, self._issues


class _FakeZenhubClient:
    def __init__(self, sprint: SprintInfo, issues: list[SprintIssue]) -> None:
        self.sprints = _FakeSprints(sprint, issues)


class TestZenhubSprintIssuesMapping(unittest.TestCase):
    def test_build_items_from_sprint_export(self) -> None:
        sprint = SprintInfo(id="s1", name="Sprint 1", state="OPEN", start_at=None, end_at=None)
        issues = [
            SprintIssue(
                id="i1",
                number=123,
                title="Do thing",
                state="OPEN",
                html_url="https://example.com/issues/123",
                estimate=None,
                repository_gh_id=None,
                pipeline_name="In Progress",
                labels=("sprint", "ai"),
                assignees=("alice",),
            )
        ]
        zh = _FakeZenhubClient(sprint, issues)

        export = {
            "updatedAt": "2026-01-01T00:00:00Z",
            "units": "hours",
            "issues": [
                {
                    "issueNumber": 123,
                    "pert": {"optimistic": 2, "mostLikely": 4, "pessimistic": 8},
                    "trackedActualHours": 3.5,
                    "aiAssisted": True,
                }
            ],
        }

        with tempfile.TemporaryDirectory() as d:
            export_path = Path(d) / "pert-hours.json"
            export_path.write_text(json.dumps(export), encoding="utf-8")

            cfg = {
                "workspace_id": "w1",
                "use_current_open_sprint": True,
                "pert": {"source": "pert_hours_export", "path": str(export_path), "require_triad": True, "require_actual": True},
                "labels": {"enabled": True, "required": ["sprint"], "ai_label": "ai"},
                "assignment": {"require_assignee": True, "assignee_mode": "first"},
                "status": {"pipeline_to_status": {"In Progress": "in_progress"}, "done_statuses": ["done"]},
            }

            result = build_work_items_from_zenhub_sprint(
                zh=zh,
                source_cfg=cfg,
                fallback_owner_id="alice",
                developer_ids=["alice"],
            )

            self.assertEqual(result.sprint.id, "s1")
            self.assertEqual(len(result.items), 1)
            item = result.items[0]
            self.assertEqual(item.item_id, "123")
            self.assertEqual(item.owner_id, "alice")
            self.assertEqual(item.optimistic, 2.0)
            self.assertEqual(item.most_likely, 4.0)
            self.assertEqual(item.pessimistic, 8.0)
            self.assertEqual(item.ai_intensity, 1.0)

            self.assertEqual(len(result.project_items), 1)
            self.assertEqual(result.project_items[0].status, "in_progress")

