from __future__ import annotations

import re
from typing import Collection, Optional, Pattern

from turbo_agent_core.schema.basic import RESERVED_NAMES


DISPLAY_NAME_PATTERN = re.compile(r"^[\u4e00-\u9fa5a-zA-Z0-9._\-|\s]+$")
IDENTIFIER_NAME_PATTERN = re.compile(r"^[a-zA-Z0-9._\-]+$")
SPACE_NAME_PATTERN = re.compile(r"^[a-zA-Z0-9_]+$")
INVALID_EDGE_CHARS = {"-", ".", " "}


def is_reserved_name(value: str, reserved_exceptions: Optional[Collection[str]] = None) -> bool:
    normalized = value.strip().lower()
    exceptions = {item.lower() for item in (reserved_exceptions or [])}
    return normalized in RESERVED_NAMES and normalized not in exceptions


def validate_name_by_pattern(
    value: Optional[str],
    *,
    field_label: str,
    pattern: Pattern[str],
    rule_description: str,
    check_reserved: bool = False,
    reserved_exceptions: Optional[Collection[str]] = None,
) -> Optional[str]:
    if value is None:
        return value

    if value and (value[0] in INVALID_EDGE_CHARS or value[-1] in INVALID_EDGE_CHARS):
        raise ValueError(f"{field_label}不能以横线(-)、小数点(.)或空格开头或结尾")

    if value and not pattern.fullmatch(value):
        raise ValueError(f"{field_label}{rule_description}")

    if value and check_reserved and is_reserved_name(value, reserved_exceptions=reserved_exceptions):
        raise ValueError(f"{field_label}不能使用系统保留字")

    return value


def validate_display_name(
    value: Optional[str],
    *,
    field_label: str,
    check_reserved: bool = False,
    reserved_exceptions: Optional[Collection[str]] = None,
) -> Optional[str]:
    return validate_name_by_pattern(
        value,
        field_label=field_label,
        pattern=DISPLAY_NAME_PATTERN,
        rule_description="只能包含中文、英文、数字、空格、小数点(.)、连字符(-)、下划线(_)和竖线(|)",
        check_reserved=check_reserved,
        reserved_exceptions=reserved_exceptions,
    )


def validate_identifier_name(
    value: Optional[str],
    *,
    field_label: str,
    check_reserved: bool = True,
    reserved_exceptions: Optional[Collection[str]] = None,
) -> Optional[str]:
    return validate_name_by_pattern(
        value,
        field_label=field_label,
        pattern=IDENTIFIER_NAME_PATTERN,
        rule_description="只能包含英文、数字、小数点(.)、连字符(-)和下划线(_)",
        check_reserved=check_reserved,
        reserved_exceptions=reserved_exceptions,
    )


def validate_space_name(
    value: Optional[str],
    *,
    field_label: str = "空间名称",
    reserved_exceptions: Optional[Collection[str]] = None,
) -> Optional[str]:
    return validate_name_by_pattern(
        value,
        field_label=field_label,
        pattern=SPACE_NAME_PATTERN,
        rule_description="只能包含英文、数字和下划线(_)",
        check_reserved=True,
        reserved_exceptions=reserved_exceptions,
    )