"""种子搜索工具辅助函数"""

import re
from typing import List, Optional

from app.core.context import Context
from app.utils.crypto import HashUtils
from app.utils.string import StringUtils

SEARCH_RESULT_CACHE_FILE = "__search_result__"
TORRENT_RESULT_LIMIT = 50


def build_torrent_ref(context: Optional[Context]) -> str:
    """生成用于下载校验的短引用"""
    if not context or not context.torrent_info:
        return ""
    return HashUtils.sha1(context.torrent_info.enclosure or "")[:7]


def sort_season_options(options: List[str]) -> List[str]:
    """按前端逻辑排序季集选项"""
    if len(options) <= 1:
        return options

    parsed_options = []
    for index, option in enumerate(options):
        match = re.match(r"^S(\d+)(?:-S(\d+))?\s*(?:E(\d+)(?:-E(\d+))?)?$", option or "")
        if not match:
            parsed_options.append({
                "original": option,
                "season_num": 0,
                "episode_num": 0,
                "max_episode_num": 0,
                "is_whole_season": False,
                "index": index,
            })
            continue

        episode_num = int(match.group(3)) if match.group(3) else 0
        max_episode_num = int(match.group(4)) if match.group(4) else episode_num
        parsed_options.append({
            "original": option,
            "season_num": int(match.group(1)),
            "episode_num": episode_num,
            "max_episode_num": max_episode_num,
            "is_whole_season": not match.group(3),
            "index": index,
        })

    whole_seasons = [item for item in parsed_options if item["is_whole_season"]]
    episodes = [item for item in parsed_options if not item["is_whole_season"]]

    whole_seasons.sort(key=lambda item: (-item["season_num"], item["index"]))
    episodes.sort(
        key=lambda item: (
            -item["season_num"],
            -(item["max_episode_num"] or item["episode_num"]),
            -item["episode_num"],
            item["index"],
        )
    )
    return [item["original"] for item in whole_seasons + episodes]


def append_option(options: List[str], value: Optional[str]) -> None:
    """按前端逻辑收集去重后的筛选项"""
    if value and value not in options:
        options.append(value)


def build_filter_options(items: List[Context]) -> dict:
    """从搜索结果中构建筛选项汇总"""
    filter_options = {
        "site": [],
        "season": [],
        "freeState": [],
        "edition": [],
        "resolution": [],
        "videoCode": [],
        "releaseGroup": [],
    }

    for item in items:
        torrent_info = item.torrent_info
        meta_info = item.meta_info
        append_option(filter_options["site"], getattr(torrent_info, "site_name", None))
        append_option(filter_options["season"], getattr(meta_info, "season_episode", None))
        append_option(filter_options["freeState"], getattr(torrent_info, "volume_factor", None))
        append_option(filter_options["edition"], getattr(meta_info, "edition", None))
        append_option(filter_options["resolution"], getattr(meta_info, "resource_pix", None))
        append_option(filter_options["videoCode"], getattr(meta_info, "video_encode", None))
        append_option(filter_options["releaseGroup"], getattr(meta_info, "resource_team", None))

    filter_options["season"] = sort_season_options(filter_options["season"])
    return filter_options


def match_filter(filter_values: Optional[List[str]], value: Optional[str]) -> bool:
    """匹配前端同款多选筛选规则"""
    return not filter_values or bool(value and value in filter_values)


def filter_contexts(items: List[Context],
                    site: Optional[List[str]] = None,
                    season: Optional[List[str]] = None,
                    free_state: Optional[List[str]] = None,
                    video_code: Optional[List[str]] = None,
                    edition: Optional[List[str]] = None,
                    resolution: Optional[List[str]] = None,
                    release_group: Optional[List[str]] = None) -> List[Context]:
    """按前端同款维度筛选结果"""
    filtered_items = []
    for item in items:
        torrent_info = item.torrent_info
        meta_info = item.meta_info
        if (
            match_filter(site, getattr(torrent_info, "site_name", None))
            and match_filter(free_state, getattr(torrent_info, "volume_factor", None))
            and match_filter(season, getattr(meta_info, "season_episode", None))
            and match_filter(release_group, getattr(meta_info, "resource_team", None))
            and match_filter(video_code, getattr(meta_info, "video_encode", None))
            and match_filter(resolution, getattr(meta_info, "resource_pix", None))
            and match_filter(edition, getattr(meta_info, "edition", None))
        ):
            filtered_items.append(item)
    return filtered_items


def simplify_search_result(context: Context, index: int) -> dict:
    """精简单条搜索结果"""
    simplified = {}
    torrent_info = context.torrent_info
    meta_info = context.meta_info
    media_info = context.media_info

    if torrent_info:
        simplified["torrent_info"] = {
            "title": torrent_info.title,
            "size": StringUtils.format_size(torrent_info.size),
            "seeders": torrent_info.seeders,
            "peers": torrent_info.peers,
            "site_name": torrent_info.site_name,
            "torrent_url": f"{build_torrent_ref(context)}:{index}",
            "page_url": torrent_info.page_url,
            "volume_factor": torrent_info.volume_factor,
            "freedate_diff": torrent_info.freedate_diff,
            "pubdate": torrent_info.pubdate,
        }

    if media_info:
        simplified["media_info"] = {
            "title": media_info.title,
            "en_title": media_info.en_title,
            "year": media_info.year,
            "type": media_info.type.value if media_info.type else None,
            "season": media_info.season,
            "tmdb_id": media_info.tmdb_id,
        }

    if meta_info:
        simplified["meta_info"] = {
            "name": meta_info.name,
            "cn_name": meta_info.cn_name,
            "en_name": meta_info.en_name,
            "year": meta_info.year,
            "type": meta_info.type.value if meta_info.type else None,
            "begin_season": meta_info.begin_season,
            "season_episode": meta_info.season_episode,
            "resource_team": meta_info.resource_team,
            "video_encode": meta_info.video_encode,
            "edition": meta_info.edition,
            "resource_pix": meta_info.resource_pix,
        }

    return simplified
