"""Tests for POST /videos/recompute-dedup endpoint (#1664 follow-up)."""

from unittest.mock import MagicMock, patch

import pytest
from fastapi.testclient import TestClient


@pytest.fixture
def mock_video():
    """Mock video with missing dedup data."""
    v = MagicMock()
    v.id = "video-001"
    v.user_id = "user-abc"
    v.duplicate_rate = None
    v.video_fingerprint = None
    v.project_id = "proj-001"
    v.generation_task_id = "task-001"
    v.name = "test.mp4"
    v.file_url = "https://example.com/test.mp4"
    v.file_size = 1024
    v.duration = 10.0
    v.width = 1920
    v.height = 1080
    v.fps = 25.0
    v.status = "completed"
    v.review_status = "pending_review"
    v.generation_params = {}
    v.thumbnail_url = None
    v.is_duplicate = False
    v.duplicate_of = None
    v.match_count = None
    v.visual_similarity = None
    v.generated_at = "2026-09-04T00:00:00"
    return v


@pytest.fixture
def mock_video_with_dedup(mock_video):
    """Mock video that already has dedup data."""
    mock_video.duplicate_rate = 15.5
    mock_video.video_fingerprint = {"md5": "abc123"}
    return mock_video


class TestRecomputeDedupEndpoint:
    """POST /videos/recompute-dedup"""

    def test_enqueue_videos_without_dedup(self, mock_video):
        """Videos missing duplicate_rate should be enqueued."""
        from app.api.routes.videos import RecomputeDedupRequest

        mock_repo = MagicMock()
        mock_repo.list_by_user.return_value = [mock_video]

        with (patch("app.api.routes.videos.celery_app") as mock_celery,):
            mock_celery.send_task.return_value = MagicMock(id="task-xyz")
            from app.api.routes.videos import recompute_dedup

            auth_user = MagicMock()
            auth_user.user.id = "user-abc"

            result = recompute_dedup(
                request=RecomputeDedupRequest(),
                repo=mock_repo,
                current_user=auth_user,
            )

        assert result.enqueued == 1
        assert result.total_scanned == 1
        assert result.skipped == 0
        mock_celery.send_task.assert_called_once_with("worker.check_duplicate", args=["video-001"])

    def test_skip_videos_with_complete_dedup(self, mock_video_with_dedup):
        """Videos with both duplicate_rate and video_fingerprint should be skipped."""
        from app.api.routes.videos import RecomputeDedupRequest, recompute_dedup

        mock_repo = MagicMock()
        mock_repo.list_by_user.return_value = [mock_video_with_dedup]

        with patch("app.api.routes.videos.celery_app") as mock_celery:
            auth_user = MagicMock()
            auth_user.user.id = "user-abc"

            result = recompute_dedup(
                request=RecomputeDedupRequest(),
                repo=mock_repo,
                current_user=auth_user,
            )

        assert result.enqueued == 0
        assert result.total_scanned == 1
        assert result.skipped == 1
        mock_celery.send_task.assert_not_called()

    def test_specific_video_ids(self, mock_video):
        """When video_ids are provided, only those videos are processed."""
        from app.api.routes.videos import RecomputeDedupRequest, recompute_dedup

        mock_repo = MagicMock()
        mock_repo.get_by_ids.return_value = [mock_video]

        with patch("app.api.routes.videos.celery_app") as mock_celery:
            mock_celery.send_task.return_value = MagicMock(id="task-xyz")
            auth_user = MagicMock()
            auth_user.user.id = "user-abc"

            result = recompute_dedup(
                request=RecomputeDedupRequest(video_ids=["video-001"]),
                repo=mock_repo,
                current_user=auth_user,
            )

        assert result.enqueued == 1
        mock_repo.get_by_ids.assert_called_once_with(["video-001"])

    def test_security_only_own_videos(self, mock_video):
        """Videos belonging to other users should be filtered out."""
        from app.api.routes.videos import RecomputeDedupRequest, recompute_dedup

        mock_video.user_id = "user-OTHER"
        mock_repo = MagicMock()
        mock_repo.get_by_ids.return_value = [mock_video]

        with patch("app.api.routes.videos.celery_app") as mock_celery:
            auth_user = MagicMock()
            auth_user.user.id = "user-abc"

            result = recompute_dedup(
                request=RecomputeDedupRequest(video_ids=["video-001"]),
                repo=mock_repo,
                current_user=auth_user,
            )

        assert result.enqueued == 0
        mock_celery.send_task.assert_not_called()

    def test_mixed_complete_and_incomplete(self, mock_video, mock_video_with_dedup):
        """Mix of videos with and without dedup data."""
        import copy

        from app.api.routes.videos import RecomputeDedupRequest, recompute_dedup

        # Create a second video object
        v2 = MagicMock()
        v2.id = "video-002"
        v2.user_id = "user-abc"
        v2.duplicate_rate = None
        v2.video_fingerprint = None

        mock_repo = MagicMock()
        mock_repo.list_by_user.return_value = [mock_video_with_dedup, v2]

        with patch("app.api.routes.videos.celery_app") as mock_celery:
            mock_celery.send_task.return_value = MagicMock(id="task-xyz")
            auth_user = MagicMock()
            auth_user.user.id = "user-abc"

            result = recompute_dedup(
                request=RecomputeDedupRequest(),
                repo=mock_repo,
                current_user=auth_user,
            )

        assert result.enqueued == 1
        assert result.total_scanned == 2
        assert result.skipped == 1
