from typing import Optional

from fastapi import Depends

from app.schemas.cache import TorrentCacheData as _SchemaTorrentCacheData
from app.schemas.cache import TorrentReidentifyData as _SchemaTorrentReidentifyData
from app.schemas.response import Response as _SchemaResponse
from app.api.response import ResponseAPIRouter
from app.chain.media import MediaChain
from app.chain.torrents import TorrentsChain
from app.application.configuration import get_api_runtime_config_snapshot
from app.api.dependencies.auth import (
    get_current_active_superuser,
    get_current_active_superuser_async,
)
from app.schemas.types import (
    MediaSource,
    MusicTargetEntityType,
)
from app.foundation.crypto import HashUtils
from app.schemas.media import resolve_media_identity
from app.application.torrent_cache import TorrentCacheRecognitionService

router = ResponseAPIRouter()


@router.get(
    "/cache",
    summary="获取种子缓存",
    response_model=_SchemaResponse[_SchemaTorrentCacheData],
)
async def torrents_cache(_: object = Depends(get_current_active_superuser_async)):
    """
    获取当前种子缓存数据
    """
    torrents_chain = TorrentsChain()

    # 获取spider和rss两种缓存
    if get_api_runtime_config_snapshot().subscribe_mode == "rss":
        cache_info = await torrents_chain.async_get_torrents("rss")
    else:
        cache_info = await torrents_chain.async_get_torrents("spider")

    # 统计信息
    torrent_count = sum(len(torrents) for torrents in cache_info.values())

    # 转换为前端需要的格式
    torrent_data = []
    for domain, contexts in cache_info.items():
        for context in contexts:
            torrent_hash = HashUtils.md5(
                f"{context.torrent_info.title}{context.torrent_info.description}"
            )
            media_source, media_id = resolve_media_identity(media=context.media_info)
            torrent_data.append(
                {
                    "hash": torrent_hash,
                    "domain": domain,
                    "title": context.torrent_info.title,
                    "description": context.torrent_info.description,
                    "size": context.torrent_info.size,
                    "pubdate": context.torrent_info.pubdate,
                    "site_name": context.torrent_info.site_name,
                    "media_name": context.media_info.title
                    if context.media_info
                    else "",
                    "media_year": context.media_info.year if context.media_info else "",
                    "media_type": context.media_info.type if context.media_info else "",
                    "media_source": media_source,
                    "media_id": media_id,
                    "music_type": getattr(context.media_info, "music_type", None),
                    "season_episode": context.meta_info.season_episode
                    if context.meta_info
                    else "",
                    "resource_term": context.meta_info.resource_term
                    if context.meta_info
                    else "",
                    "enclosure": context.torrent_info.enclosure,
                    "page_url": context.torrent_info.page_url,
                    "poster_path": context.media_info.get_poster_image()
                    if context.media_info
                    else "",
                    "backdrop_path": context.media_info.get_backdrop_image()
                    if context.media_info
                    else "",
                }
            )

    return _SchemaResponse(
        success=True,
        data={"count": torrent_count, "sites": len(cache_info), "data": torrent_data},
    )


@router.delete(
    "/cache/{domain}/{torrent_hash}",
    summary="删除指定种子缓存",
    response_model=_SchemaResponse[None],
)
async def delete_cache(
    domain: str,
    torrent_hash: str,
    _: object = Depends(get_current_active_superuser_async),
):
    """
    删除指定的种子缓存
    :param domain: 站点域名
    :param torrent_hash: 种子hash（使用title+description的md5）
    :param _: 当前用户，必须是超级用户
    """

    torrents_chain = TorrentsChain()

    try:
        # 获取当前缓存
        cache_data = await torrents_chain.async_get_torrents()

        if domain not in cache_data:
            return _SchemaResponse(success=False, message=f"站点 {domain} 缓存不存在")

        # 查找并删除指定种子
        original_count = len(cache_data[domain])
        cache_data[domain] = [
            context
            for context in cache_data[domain]
            if HashUtils.md5(
                f"{context.torrent_info.title}{context.torrent_info.description}"
            )
            != torrent_hash
        ]

        if len(cache_data[domain]) == original_count:
            return _SchemaResponse(success=False, message="未找到指定的种子")

        # 保存更新后的缓存：影视与音乐分别回写各自存储文件
        video_cache, music_cache = torrents_chain.split_cache_contexts(cache_data)
        video_file, music_file = torrents_chain.cache_files()
        await torrents_chain.async_save_cache(video_cache, video_file)
        await torrents_chain.async_save_cache(music_cache, music_file)

        return _SchemaResponse(success=True, message="种子删除成功")
    except Exception as e:
        return _SchemaResponse(success=False, message=f"删除失败：{str(e)}")


@router.delete("/cache", summary="清理种子缓存", response_model=_SchemaResponse[None])
async def clear_cache(_: object = Depends(get_current_active_superuser_async)):
    """
    清理所有种子缓存
    """
    torrents_chain = TorrentsChain()

    try:
        await torrents_chain.async_clear_torrents()
        return _SchemaResponse(success=True, message="种子缓存清理完成")
    except Exception as e:
        return _SchemaResponse(success=False, message=f"清理失败：{str(e)}")


@router.post("/cache/refresh", summary="刷新种子缓存", response_model=_SchemaResponse[None])
def refresh_cache(_: object = Depends(get_current_active_superuser)):
    """
    刷新种子缓存
    """
    from app.chain.torrents import TorrentsChain

    torrents_chain = TorrentsChain()

    try:
        result = torrents_chain.refresh()

        # 统计刷新结果
        total_count = sum(len(torrents) for torrents in result.values())
        sites_count = len(result)

        return _SchemaResponse(
            success=True,
            message=f"缓存刷新完成，共刷新 {sites_count} 个站点，{total_count} 个种子",
        )
    except Exception as e:
        return _SchemaResponse(success=False, message=f"刷新失败：{str(e)}")


@router.post(
    "/cache/reidentify/{domain}/{torrent_hash}",
    summary="重新识别种子",
    response_model=_SchemaResponse[_SchemaTorrentReidentifyData],
)
async def reidentify_cache(
    domain: str,
    torrent_hash: str,
    media_source: Optional[MediaSource] = None,
    media_id: Optional[str] = None,
    music_type: Optional[MusicTargetEntityType] = None,
    _: object = Depends(get_current_active_superuser_async),
):
    """
    重新识别指定的种子
    :param domain: 站点域名
    :param torrent_hash: 种子hash（使用title+description的md5）
    :param media_source: 媒体数据源
    :param media_id: 数据源原生 ID
    :param music_type: 音乐实体类型，仅支持单曲或专辑
    :param _: 当前用户，必须是超级用户
    """

    try:
        service = TorrentCacheRecognitionService(TorrentsChain(), MediaChain())
        success, message, data = await service.execute(
            domain=domain,
            torrent_hash=torrent_hash,
            media_source=media_source,
            media_id=media_id,
            music_type=music_type,
        )
        return _SchemaResponse(
            success=success,
            message=message,
            data=data,
        )
    except Exception as e:
        return _SchemaResponse(success=False, message=f"重新识别失败：{str(e)}")
