"""
Symphra Excel库的工具函数
"""

import re
from pathlib import Path
from typing import Any

from ..utils.exceptions import ValidationError
from ..utils.validators import (
    validate_excel_file_path as _validate_excel_file_path,
)
from ..utils.validators import (
    validate_file_path as _validate_file_path_new,
)


def validate_cell_reference(cell_ref: str) -> tuple[str, int]:
    """
    验证并解析Excel单元格引用

    参数:
        cell_ref: 单元格引用 (例如: 'A1', 'AB10')

    返回:
        (列字母, 行号)元组

    异常:
        ValueError: 如果单元格引用无效
    """
    match = re.match(r"^([A-Za-z]+)(\d+)$", cell_ref.strip())
    if not match:
        raise ValueError(f"无效的单元格引用: {cell_ref}")

    column, row = match.groups()
    return column.upper(), int(row)


def column_letter_to_number(column_letter: str) -> int:
    """
    将Excel列字母转换为数字 (A=1, B=2, 等)

    参数:
        column_letter: 列字母 (例如: 'A', 'AB')

    返回:
        列号
    """
    column_letter = column_letter.upper()
    number = 0
    for char in column_letter:
        number = number * 26 + (ord(char) - ord("A") + 1)
    return number


def column_number_to_letter(column_number: int) -> str:
    """
    将列号转换为Excel列字母 (1=A, 2=B, 等)

    参数:
        column_number: 列号

    返回:
        列字母
    """
    if column_number <= 0:
        raise ValueError("列号必须为正数")

    result = ""
    while column_number > 0:
        column_number -= 1
        result = chr(ord("A") + column_number % 26) + result
        column_number //= 26

    return result


def get_cell_range_bounds(range_ref: str) -> tuple[tuple[int, int], tuple[int, int]]:
    """
    解析Excel范围引用并返回边界

    参数:
        range_ref: 范围引用 (例如: 'A1:B2')

    返回:
        ((起始行, 起始列), (结束行, 结束列))元组
    """
    if ":" not in range_ref:
        # 单元格范围
        col, row = validate_cell_reference(range_ref)
        col_num = column_letter_to_number(col)
        return (row, col_num), (row, col_num)

    start_cell, end_cell = range_ref.split(":", 1)
    start_col, start_row = validate_cell_reference(start_cell)
    end_col, end_row = validate_cell_reference(end_cell)

    start_col_num = column_letter_to_number(start_col)
    end_col_num = column_letter_to_number(end_col)

    return (start_row, start_col_num), (end_row, end_col_num)


def validate_file_path(file_path: str | Path) -> Path:
    """
    验证并返回文件路径的Path对象

    备注: 这是向后兼容的包装器,内部使用 validators.validate_file_path

    参数:
        file_path: 文件路径

    返回:
        Path对象

    异常:
        ValidationError: 如果文件路径无效
    """
    return _validate_file_path_new(file_path)


def get_file_extension(file_path: str | Path) -> str:
    """
    从文件路径获取文件扩展名

    参数:
        file_path: 文件路径

    返回:
        文件扩展名 (小写)
    """
    path = validate_file_path(file_path)
    return path.suffix.lower()


def is_excel_file(file_path: str | Path) -> bool:
    """
    检查文件是否为Excel文件

    备注: 这是向后兼容的包装器,内部使用 validators.validate_excel_file_path

    参数:
        file_path: 文件路径

    返回:
        如果文件是Excel文件则返回True
    """
    try:
        _validate_excel_file_path(file_path, must_exist=False)
        return True
    except ValidationError:
        return False


def safe_convert_to_number(value: Any) -> int | float | None:
    """
    安全地将值转换为数字

    参数:
        value: 要转换的值

    返回:
        转换后的数字，如果转换失败则返回None
    """
    if value is None:
        return None

    try:
        # 首先尝试整数
        return int(value)
    except (ValueError, TypeError):
        try:
            # 尝试浮点数
            return float(value)
        except (ValueError, TypeError):
            return None
