"""
Unit tests for YouTube Downloader in VideoDetection.
Kiểm thử chuẩn hóa URL/ID, phân tích section (mặc định 1h đầu), và tích hợp yt-dlp.
"""
from __future__ import annotations

from pathlib import Path
import pytest

from src.core.paths import DATA_DIR, TARGET_DIR
from src.ingestion.youtube_downloader import (
    DEFAULT_SECTION_1H,
    extract_youtube_id,
    normalize_youtube_url,
    parse_section_range,
    resolve_dest_dir,
    build_ytdlp_options,
)


class TestYouTubeDownloaderHelpers:
    """Kiểm tra các hàm tiện ích phân tích URL, ID và Section."""

    @pytest.mark.parametrize(
        "raw_input, expected_id",
        [
            ("dQw4w9WgXcQ", "dQw4w9WgXcQ"),
            ("https://www.youtube.com/watch?v=dQw4w9WgXcQ", "dQw4w9WgXcQ"),
            ("http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=share", "dQw4w9WgXcQ"),
            ("https://youtu.be/dQw4w9WgXcQ", "dQw4w9WgXcQ"),
            ("https://youtu.be/dQw4w9WgXcQ?si=abcdef123", "dQw4w9WgXcQ"),
            ("https://www.youtube.com/embed/dQw4w9WgXcQ", "dQw4w9WgXcQ"),
            ("https://www.youtube.com/shorts/dQw4w9WgXcQ", "dQw4w9WgXcQ"),
            ("https://www.youtube.com/live/dQw4w9WgXcQ", "dQw4w9WgXcQ"),
            ("www.youtube.com/watch?v=dQw4w9WgXcQ", "dQw4w9WgXcQ"),
            ("youtu.be/dQw4w9WgXcQ", "dQw4w9WgXcQ"),
        ],
    )
    def test_extract_youtube_id_valid(self, raw_input: str, expected_id: str):
        assert extract_youtube_id(raw_input) == expected_id

    @pytest.mark.parametrize(
        "invalid_input",
        [
            "",
            "not_an_id",
            "https://google.com",
            "https://vimeo.com/123456",
            "12345",
        ],
    )
    def test_extract_youtube_id_invalid(self, invalid_input: str):
        with pytest.raises(ValueError):
            extract_youtube_id(invalid_input)

    def test_normalize_youtube_url(self):
        url = normalize_youtube_url("dQw4w9WgXcQ")
        assert url == "https://www.youtube.com/watch?v=dQw4w9WgXcQ"

        url2 = normalize_youtube_url("https://youtu.be/dQw4w9WgXcQ?si=123")
        assert url2 == "https://www.youtube.com/watch?v=dQw4w9WgXcQ"

    def test_parse_section_range_default(self):
        # Rỗng hoặc default hoặc 1h -> mặc định 1h đầu
        assert parse_section_range("") == DEFAULT_SECTION_1H
        assert parse_section_range("default") == DEFAULT_SECTION_1H
        assert parse_section_range("1h") == DEFAULT_SECTION_1H
        assert parse_section_range("1h_dau") == DEFAULT_SECTION_1H

    def test_parse_section_range_all_full(self):
        # Tải toàn bộ video
        assert parse_section_range(None) is None
        assert parse_section_range("all") is None
        assert parse_section_range("full") is None
        assert parse_section_range("toan_bo") is None

    def test_parse_section_range_custom(self):
        assert parse_section_range("01:30-05:00") == "*01:30-05:00"
        assert parse_section_range("00:01:30 - 00:05:00") == "*00:01:30-00:05:00"
        assert parse_section_range("*00:10:00-00:20:00") == "*00:10:00-00:20:00"
        assert parse_section_range("05:00-inf") == "*05:00-inf"

    def test_resolve_dest_dir(self, tmp_path: Path):
        assert resolve_dest_dir("target") == TARGET_DIR
        assert resolve_dest_dir("Target") == TARGET_DIR
        assert resolve_dest_dir("data") == DATA_DIR
        assert resolve_dest_dir("Data") == DATA_DIR
        assert resolve_dest_dir(None) == TARGET_DIR
        assert resolve_dest_dir(tmp_path) == tmp_path


class TestBuildYtdlpOptions:
    """Kiểm tra cấu hình yt-dlp."""

    def test_build_ytdlp_options_default(self):
        opts = build_ytdlp_options(
            dest_dir=TARGET_DIR,
            section="*00:00:00-01:00:00",
        )
        assert "outtmpl" in opts
        assert str(TARGET_DIR) in str(opts["outtmpl"]["default"])
        assert opts.get("download_ranges") is not None
        assert opts.get("force_keyframes_at_cuts") is True

    def test_build_ytdlp_options_full_video(self):
        opts = build_ytdlp_options(
            dest_dir=DATA_DIR,
            section=None,
        )
        assert "download_ranges" not in opts or opts.get("download_ranges") is None
        assert str(DATA_DIR) in str(opts["outtmpl"]["default"])


class TestDownloadExecution:
    """Kiểm tra luồng tải và xử lý kết quả."""

    def test_download_invalid_url_fails_gracefully(self):
        from src.ingestion.youtube_downloader import download_youtube_video

        res = download_youtube_video("invalid_url_format", dest="target")
        assert res.success is False
        assert res.error_message is not None
        assert "Không thể nhận diện" in res.error_message

    def test_pipeline_download_integration(self, monkeypatch, tmp_path: Path):
        from src.ingestion.youtube_downloader import YouTubeDownloadResult
        from src.pipeline import VideoDetectionPipeline

        dummy_file = tmp_path / "sample_video.mp4"
        dummy_file.write_bytes(b"dummy_video_data")

        # Mock download_youtube_video
        def mock_dl(*args, **kwargs):
            return YouTubeDownloadResult(
                success=True,
                file_path=dummy_file,
                video_id="test1234567",
                title="Mock Test Video",
                duration_sec=120.0,
                section="*00:00:00-01:00:00",
                dest_dir=tmp_path,
            )

        monkeypatch.setattr("src.pipeline.dl_yt_video", mock_dl)

        pipeline = VideoDetectionPipeline()
        res = pipeline.download_youtube_video(
            url_or_id="https://www.youtube.com/watch?v=test1234567",
            dest=tmp_path,
            auto_sync=False,
        )

        assert res.success is True
        assert res.title == "Mock Test Video"
        assert res.file_path == dummy_file

