from types import SimpleNamespace

from app.chain.media import MediaChain
from app.domain.context import MediaInfo
from app.domain.metainfo import MetaInfo
from app.schemas.types import MediaSource, MediaType


class _FakeTmdbModule:
    """返回固定 TMDB 结果，避免测试访问外部元数据服务。"""

    def __init__(self, result: MediaInfo):
        """保存测试需要返回的 TMDB 媒体信息。"""
        self.result = result

    def recognize_media(self, **_kwargs):
        """同步返回固定 TMDB 媒体信息。"""
        return self.result


def _make_chain(tmdb_media: MediaInfo) -> MediaChain:
    """构造不加载真实模块的媒体处理链。"""
    chain = object.__new__(MediaChain)
    module = _FakeTmdbModule(tmdb_media)
    chain.modulemanager = SimpleNamespace(
        get_running_module=lambda module_id: (
            module if module_id == "TheMovieDbModule" else None
        )
    )
    return chain


def test_supplement_tmdb_keeps_primary_source_identity() -> None:
    """非 TMDB 主来源补充 TMDB 后，主身份和展示字段必须保持不变。"""
    primary = MediaInfo(
        media_source=MediaSource.AniList,
        media_id="subject-42",
        type=MediaType.TV,
        title="原识别标题",
        year="2024",
        category="",
    )
    tmdb_media = MediaInfo(
        tmdb_info={
            "id": 12345,
            "media_type": MediaType.TV,
            "name": "TMDB 标题",
            "genre_ids": [16, 18],
            "external_ids": {"imdb_id": "tt12345", "tvdb_id": 6789},
        }
    )
    tmdb_media.category = "日本动画"

    result = _make_chain(tmdb_media).supplement_tmdb_info(
        primary, MetaInfo("原识别标题 2024")
    )

    assert result is primary
    assert result.media_source == MediaSource.AniList
    assert result.media_id == "subject-42"
    assert result.title == "原识别标题"
    assert result.tmdb_id == 12345
    assert result.genre_ids == [16, 18]
    assert result.category == "日本动画"


def test_supplement_tmdb_does_not_override_custom_category() -> None:
    """下载历史或目录指定的自定义分类优先于 TMDB 自动分类。"""
    primary = MediaInfo(
        media_source=MediaSource.Douban,
        media_id="35593344",
        douban_id="35593344",
        type=MediaType.MOVIE,
        title="测试电影",
        category="纪录片",
    )
    tmdb_media = MediaInfo(
        tmdb_info={
            "id": 9876,
            "media_type": MediaType.MOVIE,
            "title": "Test Movie",
            "genre_ids": [28],
        }
    )
    tmdb_media.category = "动作片"

    result = _make_chain(tmdb_media).supplement_tmdb_info(primary)

    assert result.media_source == MediaSource.Douban
    assert result.media_id == "35593344"
    assert result.category == "纪录片"
    assert result.tmdb_id == 9876


def test_tmdb_supplement_uses_current_season_year_and_keeps_season_zero() -> None:
    """电视剧优先使用当前季年份，并且特别季季号不能退化为空。"""
    media = MediaInfo(
        media_source=MediaSource.Bangumi,
        media_id="42",
        type=MediaType.TV,
        title="测试动画",
        year="2020",
        season=0,
        season_years={0: "2024"},
    )

    tmdb_meta = MediaChain._build_tmdb_supplement_meta(
        media, MetaInfo("测试动画 S00 2020")
    )

    assert tmdb_meta.begin_season == 0
    assert tmdb_meta.year == "2024"
