import os
import re
from pathlib import Path
from typing import Any, Dict, Union

import yaml
from models import TaskDefinition


def _expand_env_vars(value: Any) -> Any:
    """递归展开字符串中的 ${VAR} 和 $VAR 环境变量。"""
    if isinstance(value, str):
        pattern = re.compile(r"\$\{(\w+)\}|\$(\w+)")

        def replacer(match: re.Match) -> str:
            var_name = match.group(1) or match.group(2)
            return os.environ.get(var_name, match.group(0))

        return pattern.sub(replacer, value)
    if isinstance(value, dict):
        return {k: _expand_env_vars(v) for k, v in value.items()}
    if isinstance(value, list):
        return [_expand_env_vars(v) for v in value]
    return value


def _parse_definition(raw: Dict[str, Any]) -> TaskDefinition:
    """根据版本号解析任务定义，支持多版本规范。"""
    version = str(raw.get("version", "1"))
    if version == "1":
        # 提取多语言字段到 name_i18n / description_i18n
        raw = dict(raw)
        name_i18n = {}
        description_i18n = {}
        for lang in ["en", "ru"]:
            if f"name_{lang}" in raw:
                name_i18n[lang] = raw.pop(f"name_{lang}")
            if f"description_{lang}" in raw:
                description_i18n[lang] = raw.pop(f"description_{lang}")
        raw["name_i18n"] = name_i18n
        raw["description_i18n"] = description_i18n
        return TaskDefinition.model_validate(raw)
    raise ValueError(
        f"Unsupported task definition version '{version}' in task '{raw.get('id', '?')}'"
    )


def load_task_definitions(tasks_dir: Union[str, Path]) -> Dict[str, TaskDefinition]:
    """从 tasks_dir 加载所有 YAML 任务定义。"""
    tasks_dir = Path(tasks_dir)
    definitions: Dict[str, TaskDefinition] = {}
    if not tasks_dir.exists():
        return definitions

    for path in sorted(tasks_dir.glob("*.yaml")):
        raw = yaml.safe_load(path.read_text(encoding="utf-8"))
        if not raw:
            continue
        raw = _expand_env_vars(raw)
        try:
            task_def = _parse_definition(raw)
        except ValueError as e:
            # 跳过无法解析的定义，打印警告
            print(f"[WARN] 跳过任务定义 {path.name}: {e}")
            continue
        definitions[task_def.id] = task_def

    return definitions
