# [DEF:test_report_service:Module]
# @TIER: STANDARD
# @PURPOSE: Unit tests for ReportsService list/detail operations
# @LAYER: Domain
# @RELATION: TESTS -> backend.src.services.reports.report_service.ReportsService

import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))

import pytest
from unittest.mock import MagicMock, patch
from datetime import datetime, timezone, timedelta


def _make_task(task_id="task-1", plugin_id="superset-backup", status_value="SUCCESS",
               started_at=None, finished_at=None, result=None, params=None, logs=None):
    """Create a mock Task object matching the Task model interface."""
    from src.core.task_manager.models import Task, TaskStatus
    task = Task(plugin_id=plugin_id, params=params or {})
    task.id = task_id
    task.status = TaskStatus(status_value)
    task.started_at = started_at or datetime(2024, 1, 15, 10, 0, 0)
    task.finished_at = finished_at or datetime(2024, 1, 15, 10, 5, 0)
    task.result = result
    if logs is not None:
        task.logs = logs
    return task


class TestReportsServiceList:
    """Tests for ReportsService.list_reports."""

    def _make_service(self, tasks):
        from src.services.reports.report_service import ReportsService
        mock_tm = MagicMock()
        mock_tm.get_all_tasks.return_value = tasks
        return ReportsService(task_manager=mock_tm)

    def test_empty_tasks_returns_empty_collection(self):
        from src.models.report import ReportQuery
        svc = self._make_service([])
        result = svc.list_reports(ReportQuery())
        assert result.total == 0
        assert result.items == []
        assert result.has_next is False

    def test_single_task_normalized(self):
        from src.models.report import ReportQuery
        task = _make_task(result={"summary": "Backup completed"})
        svc = self._make_service([task])
        result = svc.list_reports(ReportQuery())
        assert result.total == 1
        assert result.items[0].task_id == "task-1"
        assert result.items[0].summary == "Backup completed"

    def test_pagination_first_page(self):
        from src.models.report import ReportQuery
        tasks = [
            _make_task(task_id=f"task-{i}",
                       finished_at=datetime(2024, 1, 15, 10, i, 0))
            for i in range(5)
        ]
        svc = self._make_service(tasks)
        result = svc.list_reports(ReportQuery(page=1, page_size=2))
        assert len(result.items) == 2
        assert result.total == 5
        assert result.has_next is True

    def test_pagination_last_page(self):
        from src.models.report import ReportQuery
        tasks = [
            _make_task(task_id=f"task-{i}",
                       finished_at=datetime(2024, 1, 15, 10, i, 0))
            for i in range(5)
        ]
        svc = self._make_service(tasks)
        result = svc.list_reports(ReportQuery(page=3, page_size=2))
        assert len(result.items) == 1
        assert result.has_next is False

    def test_filter_by_status(self):
        from src.models.report import ReportQuery, ReportStatus
        tasks = [
            _make_task(task_id="ok", status_value="SUCCESS"),
            _make_task(task_id="fail", status_value="FAILED"),
        ]
        svc = self._make_service(tasks)
        result = svc.list_reports(ReportQuery(statuses=[ReportStatus.SUCCESS]))
        assert result.total == 1
        assert result.items[0].task_id == "ok"

    def test_filter_by_task_type(self):
        from src.models.report import ReportQuery, TaskType
        tasks = [
            _make_task(task_id="backup", plugin_id="superset-backup"),
            _make_task(task_id="migrate", plugin_id="superset-migration"),
        ]
        svc = self._make_service(tasks)
        result = svc.list_reports(ReportQuery(task_types=[TaskType.BACKUP]))
        assert result.total == 1
        assert result.items[0].task_id == "backup"

    def test_search_filter(self):
        from src.models.report import ReportQuery
        tasks = [
            _make_task(task_id="t1", plugin_id="superset-migration",
                       result={"summary": "Migration complete"}),
            _make_task(task_id="t2", plugin_id="documentation",
                       result={"summary": "Docs generated"}),
        ]
        svc = self._make_service(tasks)
        result = svc.list_reports(ReportQuery(search="migration"))
        assert result.total == 1
        assert result.items[0].task_id == "t1"

    def test_sort_by_status(self):
        from src.models.report import ReportQuery
        tasks = [
            _make_task(task_id="t1", status_value="SUCCESS"),
            _make_task(task_id="t2", status_value="FAILED"),
        ]
        svc = self._make_service(tasks)
        # Order: FAILED (desc) -> SUCCESS (asc) if it's alphanumeric
        # status values are 'SUCCESS', 'FAILED'. 'FAILED' < 'SUCCESS'
        result = svc.list_reports(ReportQuery(sort_by="status", sort_order="asc"))
        assert result.items[0].status.value == "failed"
        assert result.items[1].status.value == "success"

    def test_applied_filters_echoed(self):
        from src.models.report import ReportQuery
        query = ReportQuery(page=2, page_size=5)
        svc = self._make_service([])
        result = svc.list_reports(query)
        assert result.applied_filters.page == 2
        assert result.applied_filters.page_size == 5


class TestReportsServiceDetail:
    """Tests for ReportsService.get_report_detail."""

    def _make_service(self, tasks):
        from src.services.reports.report_service import ReportsService
        mock_tm = MagicMock()
        mock_tm.get_all_tasks.return_value = tasks
        return ReportsService(task_manager=mock_tm)

    def test_detail_found(self):
        task = _make_task(task_id="detail-task", result={"summary": "Done"})
        svc = self._make_service([task])
        detail = svc.get_report_detail("detail-task")
        assert detail is not None
        assert detail.report.task_id == "detail-task"

    def test_detail_not_found(self):
        svc = self._make_service([])
        detail = svc.get_report_detail("nonexistent")
        assert detail is None

    def test_detail_includes_timeline(self):
        task = _make_task(task_id="tl-task",
                         started_at=datetime(2024, 1, 15, 10, 0, 0),
                         finished_at=datetime(2024, 1, 15, 10, 5, 0))
        svc = self._make_service([task])
        detail = svc.get_report_detail("tl-task")
        events = [e["event"] for e in detail.timeline]
        assert "started" in events
        assert "updated" in events

    def test_detail_failed_task_has_next_actions(self):
        task = _make_task(task_id="fail-task", status_value="FAILED")
        svc = self._make_service([task])
        detail = svc.get_report_detail("fail-task")
        assert len(detail.next_actions) > 0

    def test_detail_success_task_no_error_next_actions(self):
        task = _make_task(task_id="ok-task", status_value="SUCCESS",
                         result={"summary": "All good"})
        svc = self._make_service([task])
        detail = svc.get_report_detail("ok-task")
        assert detail.next_actions == []

# [/DEF:test_report_service:Module]
