"""单元格值处理器"""

import re
from typing import Any, Optional, Dict
from datetime import datetime, timedelta

from ...reference import PRIVATEDATA, GSDSTORE, get_element_value, INFO


class CellHandler:
    """单元格值处理器

    处理 Excel 单元格中的特殊语法，如变量引用、内置函数等。
    """

    # 变量引用模式: ${varName} 或 ${module.varName}
    VAR_PATTERN = re.compile(r'\$\{([^}]+)\}')

    # 内置函数模式: @func(args) 或 @func()
    FUNC_PATTERN = re.compile(r'@(\w+)\(([^)]*)\)')

    def __init__(self, custom_params: Dict[str, Any] = None):
        """初始化处理器

        Args:
            custom_params: 自定义参数字典
        """
        self._custom_params = custom_params or {}

        # 注册内置函数
        self._functions = {
            'today': self._func_today,
            'now': self._func_now,
            'date': self._func_date,
            'random': self._func_random,
            'random_str': self._func_random_str,
            'random_phone': self._func_random_phone,
            'random_email': self._func_random_email,
            'uuid': self._func_uuid,
            'timestamp': self._func_timestamp,
            'env': self._func_env,
        }

    def process(self, value: Any) -> Any:
        """处理单元格值

        Args:
            value: 原始值

        Returns:
            处理后的值
        """
        if value is None:
            return None

        value_str = str(value)

        # 处理变量引用
        value_str = self._process_variables(value_str)

        # 处理内置函数
        value_str = self._process_functions(value_str)

        return value_str

    def _process_variables(self, value: str) -> str:
        """处理变量引用

        支持格式:
        - ${varName} - 从元素值缓存获取
        - ${self.param} - 从自定义参数获取
        - ${env.name} - 从环境变量获取

        Args:
            value: 原始值

        Returns:
            处理后的值
        """
        def replace_var(match):
            var_path = match.group(1)

            # 检查是否有命名空间
            if '.' in var_path:
                namespace, var_name = var_path.split('.', 1)

                if namespace == 'self':
                    # 自定义参数
                    return str(self._custom_params.get(var_name, match.group(0)))
                elif namespace == 'env':
                    # 环境变量
                    import os
                    return os.environ.get(var_name, match.group(0))
                elif namespace == 'ele':
                    # 元素值缓存
                    return str(get_element_value(var_name, match.group(0)))

            # 默认从元素值缓存获取
            cached = get_element_value(var_path)
            if cached is not None:
                return str(cached)

            # 从自定义参数获取
            if var_path in self._custom_params:
                return str(self._custom_params[var_path])

            # 返回原始匹配
            return match.group(0)

        return self.VAR_PATTERN.sub(replace_var, value)

    def _process_functions(self, value: str) -> str:
        """处理内置函数

        支持格式:
        - @today() - 今天日期
        - @now() - 当前时间
        - @random(min, max) - 随机数
        - @uuid() - UUID

        Args:
            value: 原始值

        Returns:
            处理后的值
        """
        def replace_func(match):
            func_name = match.group(1)
            args_str = match.group(2).strip()

            # 解析参数
            args = []
            if args_str:
                args = [a.strip().strip('"\'') for a in args_str.split(',')]

            # 调用函数
            if func_name in self._functions:
                try:
                    return str(self._functions[func_name](*args))
                except Exception as e:
                    INFO(f"函数执行失败: @{func_name}({args_str}) - {e}", "WARNING")
                    return match.group(0)

            return match.group(0)

        return self.FUNC_PATTERN.sub(replace_func, value)

    # ==================== 内置函数 ====================

    def _func_today(self, fmt: str = '%Y-%m-%d', offset: str = '0') -> str:
        """获取今天日期

        Args:
            fmt: 日期格式
            offset: 天数偏移

        Returns:
            str: 格式化的日期
        """
        date = datetime.now() + timedelta(days=int(offset))
        return date.strftime(fmt)

    def _func_now(self, fmt: str = '%Y-%m-%d %H:%M:%S') -> str:
        """获取当前时间

        Args:
            fmt: 时间格式

        Returns:
            str: 格式化的时间
        """
        return datetime.now().strftime(fmt)

    def _func_date(self, fmt: str = '%Y-%m-%d', offset: str = '0', unit: str = 'days') -> str:
        """获取日期

        Args:
            fmt: 日期格式
            offset: 偏移量
            unit: 单位 (days, hours, minutes, seconds)

        Returns:
            str: 格式化的日期
        """
        offset_int = int(offset)
        kwargs = {unit: offset_int}
        date = datetime.now() + timedelta(**kwargs)
        return date.strftime(fmt)

    def _func_random(self, min_val: str = '0', max_val: str = '100') -> int:
        """生成随机整数

        Args:
            min_val: 最小值
            max_val: 最大值

        Returns:
            int: 随机整数
        """
        import random
        return random.randint(int(min_val), int(max_val))

    def _func_random_str(self, length: str = '8', chars: str = 'alphanumeric') -> str:
        """生成随机字符串

        Args:
            length: 长度
            chars: 字符类型 (alpha, numeric, alphanumeric)

        Returns:
            str: 随机字符串
        """
        import random
        import string

        char_map = {
            'alpha': string.ascii_letters,
            'numeric': string.digits,
            'alphanumeric': string.ascii_letters + string.digits,
            'lower': string.ascii_lowercase,
            'upper': string.ascii_uppercase,
        }

        charset = char_map.get(chars, string.ascii_letters + string.digits)
        return ''.join(random.choices(charset, k=int(length)))

    def _func_random_phone(self, prefix: str = '1') -> str:
        """生成随机手机号

        Args:
            prefix: 号码前缀

        Returns:
            str: 随机手机号
        """
        import random
        prefixes = ['13', '14', '15', '16', '17', '18', '19']
        phone_prefix = random.choice(prefixes) if prefix == '1' else prefix
        return phone_prefix + ''.join([str(random.randint(0, 9)) for _ in range(9)])

    def _func_random_email(self, domain: str = 'test.com') -> str:
        """生成随机邮箱

        Args:
            domain: 邮箱域名

        Returns:
            str: 随机邮箱
        """
        username = self._func_random_str('8', 'lower')
        return f"{username}@{domain}"

    def _func_uuid(self) -> str:
        """生成 UUID

        Returns:
            str: UUID 字符串
        """
        import uuid
        return str(uuid.uuid4())

    def _func_timestamp(self, unit: str = 'ms') -> int:
        """获取时间戳

        Args:
            unit: 单位 (s, ms)

        Returns:
            int: 时间戳
        """
        import time
        ts = time.time()
        if unit == 'ms':
            return int(ts * 1000)
        return int(ts)

    def _func_env(self, name: str, default: str = '') -> str:
        """获取环境变量

        Args:
            name: 环境变量名
            default: 默认值

        Returns:
            str: 环境变量值
        """
        import os
        return os.environ.get(name, default)

    def register_function(self, name: str, func) -> None:
        """注册自定义函数

        Args:
            name: 函数名
            func: 函数对象
        """
        self._functions[name] = func

    def set_custom_params(self, params: Dict[str, Any]) -> None:
        """设置自定义参数

        Args:
            params: 参数字典
        """
        self._custom_params.update(params)
