import re
from typing import Optional, Tuple


_VERSION_LABELS = {"stable": -1, "rc": -2, "beta": -3, "alpha": -4}
_UNKNOWN_VERSION_LABEL = -5
_COMPARISON_TYPES = {"ge", "gt", "le", "lt", "eq", "==", ">=", ">", "<=", "<"}


def _normalize_version(version: str) -> list[int]:
    """将历史版本格式转换为保持原有排序语义的整数序列。"""
    parts = re.split(r"[.-]", version.strip().lstrip("vV"))
    return [
        int(part)
        if part.isdigit()
        else _VERSION_LABELS.get(part, _UNKNOWN_VERSION_LABEL)
        for part in parts
    ]


def compare_version(
    source: str,
    comparison: str,
    target: str,
    verbose: bool = False,
) -> Optional[bool] | Tuple[Optional[bool], str | Exception]:
    """按 MoviePilot 历史规则比较版本号，并可返回可读比较结果。"""
    try:
        if not source or not target:
            raise ValueError("要比较的版本号不全")
        if not comparison:
            raise ValueError("缺少比对模式，无法比对")
        if comparison not in _COMPARISON_TYPES:
            raise ValueError(f"设置的版本比对模式 {comparison} 不是有效的模式！")

        source_parts = _normalize_version(source)
        target_parts = _normalize_version(target)
        max_length = max(len(source_parts), len(target_parts))
        source_parts += [0] * (max_length - len(source_parts))
        target_parts += [0] * (max_length - len(target_parts))

        relation = "等于"
        for source_value, target_value in zip(source_parts, target_parts):
            if source_value > target_value:
                relation = "大于"
                break
            if source_value < target_value:
                relation = "小于"
                break

        matched = {
            "eq": relation == "等于",
            "==": relation == "等于",
            "ge": relation in {"大于", "等于"},
            ">=": relation in {"大于", "等于"},
            "gt": relation == "大于",
            ">": relation == "大于",
            "le": relation in {"小于", "等于"},
            "<=": relation in {"小于", "等于"},
            "lt": relation == "小于",
            "<": relation == "小于",
        }[comparison]
        display_relation = (
            "不等于" if comparison in {"eq", "=="} and not matched else relation
        )
        message = f"版本号 {source} {display_relation} 目标版本号 {target} ！"
        return (matched, message) if verbose else matched
    except Exception as err:
        return (None, err) if verbose else None
