# [DEF:backend.tests.test_reports_api:Module]
# @TIER: STANDARD
# @SEMANTICS: tests, reports, api, contract, pagination, filtering
# @PURPOSE: Contract tests for GET /api/reports defaults, pagination, and filtering behavior.
# @LAYER: Domain (Tests)
# @RELATION: TESTS -> backend.src.api.routes.reports
# @INVARIANT: API response contract contains {items,total,page,page_size,has_next,applied_filters}.

from datetime import datetime, timedelta, timezone
from types import SimpleNamespace

from fastapi.testclient import TestClient

from src.app import app
from src.core.task_manager.models import Task, TaskStatus
from src.dependencies import get_current_user, get_task_manager


class _FakeTaskManager:
    def __init__(self, tasks):
        self._tasks = tasks

    def get_all_tasks(self):
        return self._tasks


def _admin_user():
    admin_role = SimpleNamespace(name="Admin", permissions=[])
    return SimpleNamespace(username="test-admin", roles=[admin_role])


def _make_task(task_id: str, plugin_id: str, status: TaskStatus, started_at: datetime, finished_at: datetime = None, result=None):
    return Task(
        id=task_id,
        plugin_id=plugin_id,
        status=status,
        started_at=started_at,
        finished_at=finished_at,
        params={"environment_id": "env-1"},
        result=result or {"summary": f"{plugin_id} {status.value.lower()}"},
    )


def test_get_reports_default_pagination_contract():
    now = datetime.utcnow()
    tasks = [
        _make_task("t-1", "superset-backup", TaskStatus.SUCCESS, now - timedelta(minutes=10), now - timedelta(minutes=9)),
        _make_task("t-2", "superset-migration", TaskStatus.FAILED, now - timedelta(minutes=8), now - timedelta(minutes=7)),
        _make_task("t-3", "llm_dashboard_validation", TaskStatus.RUNNING, now - timedelta(minutes=6), None),
    ]

    app.dependency_overrides[get_current_user] = lambda: _admin_user()
    app.dependency_overrides[get_task_manager] = lambda: _FakeTaskManager(tasks)

    try:
        client = TestClient(app)
        response = client.get("/api/reports")
        assert response.status_code == 200

        data = response.json()
        assert set(["items", "total", "page", "page_size", "has_next", "applied_filters"]).issubset(data.keys())
        assert data["page"] == 1
        assert data["page_size"] == 20
        assert data["total"] == 3
        assert isinstance(data["items"], list)
        assert data["applied_filters"]["sort_by"] == "updated_at"
        assert data["applied_filters"]["sort_order"] == "desc"
    finally:
        app.dependency_overrides.clear()


def test_get_reports_filter_and_pagination():
    now = datetime.utcnow()
    tasks = [
        _make_task("t-1", "superset-backup", TaskStatus.SUCCESS, now - timedelta(minutes=30), now - timedelta(minutes=29)),
        _make_task("t-2", "superset-backup", TaskStatus.FAILED, now - timedelta(minutes=20), now - timedelta(minutes=19)),
        _make_task("t-3", "superset-migration", TaskStatus.FAILED, now - timedelta(minutes=10), now - timedelta(minutes=9)),
    ]

    app.dependency_overrides[get_current_user] = lambda: _admin_user()
    app.dependency_overrides[get_task_manager] = lambda: _FakeTaskManager(tasks)

    try:
        client = TestClient(app)
        response = client.get("/api/reports?task_types=backup&statuses=failed&page=1&page_size=1")
        assert response.status_code == 200

        data = response.json()
        assert data["total"] == 1
        assert data["page"] == 1
        assert data["page_size"] == 1
        assert data["has_next"] is False
        assert len(data["items"]) == 1
        assert data["items"][0]["task_type"] == "backup"
        assert data["items"][0]["status"] == "failed"
    finally:
        app.dependency_overrides.clear()


def test_get_reports_handles_mixed_naive_and_aware_datetimes():
    naive_now = datetime.utcnow()
    aware_now = datetime.now(timezone.utc)
    tasks = [
        _make_task("t-naive", "superset-backup", TaskStatus.SUCCESS, naive_now - timedelta(minutes=5), naive_now - timedelta(minutes=4)),
        _make_task("t-aware", "superset-migration", TaskStatus.FAILED, aware_now - timedelta(minutes=3), aware_now - timedelta(minutes=2)),
    ]

    app.dependency_overrides[get_current_user] = lambda: _admin_user()
    app.dependency_overrides[get_task_manager] = lambda: _FakeTaskManager(tasks)

    try:
        client = TestClient(app)
        response = client.get("/api/reports?sort_by=updated_at&sort_order=desc")
        assert response.status_code == 200
        data = response.json()
        assert data["total"] == 2
        assert len(data["items"]) == 2
    finally:
        app.dependency_overrides.clear()


def test_get_reports_invalid_filter_returns_400():
    now = datetime.utcnow()
    tasks = [_make_task("t-1", "superset-backup", TaskStatus.SUCCESS, now - timedelta(minutes=5), now - timedelta(minutes=4))]

    app.dependency_overrides[get_current_user] = lambda: _admin_user()
    app.dependency_overrides[get_task_manager] = lambda: _FakeTaskManager(tasks)

    try:
        client = TestClient(app)
        response = client.get("/api/reports?task_types=bad_type")
        assert response.status_code == 400
        body = response.json()
        assert "detail" in body
    finally:
        app.dependency_overrides.clear()


# [/DEF:backend.tests.test_reports_api:Module]