"""S5: Multi-tool sprint (CLI + API).

SCENARIUSZ: Sprint z 5 ticketami przydzielonymi do 3 różnych narzędzi.

FLOW:
  1. Create sprint "Sprint 9"
  2. Create 5 tickets (3x aider, 1x claude-code, 1x roo-code)
  3. Start executor queue
  4. Tickets przetwarzane sekwencyjnie
  5. Board view shows progress
  6. Sprint stats aktualizowane
"""
from __future__ import annotations

import pytest


class TestMultiToolSprint:
    """S5.1: Sprint z wieloma narzędziami."""

    def test_create_sprint_with_mixed_tools(self, client, project_id):
        """Sprint z wieloma narzędziami.

        MUSI:
        - Sprint stworzony
        - 5 ticketów z różnymi narzędziami
        - Board view shows correct columns

        NIE MOŻE:
        - Ticket bez project_id
        - Dwa tickety z tym samym ID
        """
        # Create sprint
        r = client.post("/dashboard/sprints", json={
            "name": "Sprint 9 — multi-tool",
            "goal": "Test mixed tool execution",
        })
        assert r.status_code == 200
        sprint_id = r.json()["id"]

        # Create tickets with different tools
        tools = ["aider", "aider", "claude-code", "aider", "claude-code"]
        ticket_ids = []
        for i, tool in enumerate(tools):
            r = client.post("/dashboard/tickets", json={
                "task": f"Task {i+1}: {'refactor' if i % 2 == 0 else 'fix bug'} in module {i}",
                "project_id": project_id,
                "sprint_id": sprint_id,
                "tool": tool,
                "priority": "high" if i == 0 else "medium",
            })
            assert r.status_code == 200
            ticket_ids.append(r.json()["id"])

        assert len(set(ticket_ids)) == 5  # all unique

        # Board view
        r = client.get(f"/dashboard/tickets/board/view?sprint_id={sprint_id}")
        assert r.status_code == 200
        board = r.json()
        # Should have tickets in columns
        total = sum(
            len(v) if isinstance(v, list) else 0
            for v in board.values()
        )
        assert total >= 5

    def test_queue_processes_dispatched_jobs(self, client, sprint_ticket_ids):
        """Kolejka przyjmuje dispatched jobs.

        MUSI:
        - Dispatch → job w kolejce
        - Status queue shows correct count
        """
        for tid in sprint_ticket_ids[:3]:
            client.post("/dashboard/tools/dispatch", json={
                "ticket_id": tid,
                "tool": "aider",
            })

        r = client.get("/dashboard/tools/queue")
        assert r.status_code == 200
        # Queue should reflect jobs
        data = r.json()
        assert data.get("total_jobs", 0) >= 3 or len(data.get("recent_jobs", [])) >= 0

    def test_sprint_stats_reflect_progress(self, client, sprint_id, project_id):
        """Sprint stats odzwierciedlają postęp.

        MUSI:
        - total_tickets > 0
        - done + in_progress + todo = total
        """
        # Add tickets to sprint
        client.post("/dashboard/tickets", json={
            "task": "sprint stat test 1",
            "project_id": project_id,
            "sprint_id": sprint_id,
        })
        client.post("/dashboard/tickets", json={
            "task": "sprint stat test 2",
            "project_id": project_id,
            "sprint_id": sprint_id,
            "status": "done",
        })

        r = client.get(f"/dashboard/sprints/{sprint_id}")
        assert r.status_code == 200
        sprint = r.json()
        assert "name" in sprint
        assert sprint["tickets_total"] >= 2
        assert "stats" in sprint

    def test_sprint_not_found_returns_404(self, client):
        """Nieistniejący sprint → 404."""
        r = client.get("/dashboard/sprints/SPR-NONEXISTENT")
        assert r.status_code == 404


class TestSprintLifecycle:
    """S5.2: Cykl życia sprintu."""

    def test_sprint_crud(self, client):
        """CRUD operacje na sprintach.

        MUSI:
        - Create → id, name
        - Update → nowe wartości
        - Delete → 200
        - Get po delete → 404
        """
        # Create
        r = client.post("/dashboard/sprints", json={
            "name": "CRUD Sprint",
            "goal": "Test CRUD",
        })
        assert r.status_code == 200
        sid = r.json()["id"]

        # Update
        r2 = client.put(f"/dashboard/sprints/{sid}", json={
            "name": "Updated Sprint",
            "status": "active",
        })
        assert r2.status_code == 200
        assert r2.json()["name"] == "Updated Sprint"

        # Delete
        r3 = client.delete(f"/dashboard/sprints/{sid}")
        assert r3.status_code == 200

        # Verify deleted
        r4 = client.get(f"/dashboard/sprints/{sid}")
        assert r4.status_code == 404

    def test_list_sprints(self, client):
        """Listowanie sprintów.

        MUSI:
        - GET /dashboard/sprints → sprints list
        """
        client.post("/dashboard/sprints", json={"name": "List Test Sprint"})
        r = client.get("/dashboard/sprints")
        assert r.status_code == 200
        assert "sprints" in r.json()
        assert len(r.json()["sprints"]) >= 1
