# -*- coding: utf-8 -*-
"""
CustomProperties 문자열 파싱 유틸리티

AnimMontage의 AnimNotifies에 있는 CustomProperties는 모두 문자열로 저장되어 있어서
타입 변환 및 파싱이 필요합니다.
"""

import re
from typing import Any, Optional


def parse_float(value: str) -> Optional[float]:
    """문자열을 float로 변환 (실패 시 None)"""
    try:
        return float(value.strip())
    except (ValueError, AttributeError):
        return None


def parse_tag_name(value: str) -> Optional[str]:
    """
    (TagName="Event.Attack.Normal") 형태에서 태그 이름 추출

    Example:
        '(TagName="Event.Attack.Normal")' -> 'Event.Attack.Normal'
    """
    if not value:
        return None

    match = re.search(r'TagName="([^"]+)"', value)
    if match:
        return match.group(1)
    return None


def parse_vector(value: str) -> Optional[dict]:
    """
    (X=0.0,Y=1.0,Z=0.0) 형태를 dict로 변환

    Example:
        '(X=0.0,Y=1.0,Z=0.0)' -> {'X': 0.0, 'Y': 1.0, 'Z': 0.0}
    """
    if not value:
        return None

    try:
        x_match = re.search(r'X=([-\d.]+)', value)
        y_match = re.search(r'Y=([-\d.]+)', value)
        z_match = re.search(r'Z=([-\d.]+)', value)

        if x_match and y_match and z_match:
            return {
                'X': float(x_match.group(1)),
                'Y': float(y_match.group(1)),
                'Z': float(z_match.group(1))
            }
    except (ValueError, AttributeError):
        pass

    return None


def parse_array(value: str) -> Optional[list]:
    """
    (0.1,0.2,0.3) 형태를 리스트로 변환

    Example:
        '(0.1,0.2,0.3)' -> [0.1, 0.2, 0.3]
    """
    if not value:
        return None

    try:
        # 괄호 제거
        cleaned = value.strip().strip('()')
        if not cleaned:
            return []

        # 쉼표로 분리
        parts = cleaned.split(',')
        return [float(p.strip()) for p in parts if p.strip()]
    except (ValueError, AttributeError):
        return None


def parse_custom_property(value: str, field_name: str) -> Any:
    """
    CustomProperties 필드의 값을 적절한 타입으로 변환

    Args:
        value: 원본 문자열 값
        field_name: 필드 이름 (타입 추론에 사용)

    Returns:
        파싱된 값 (float, str, dict, list 등)
    """
    if not isinstance(value, str):
        return value

    value = value.strip()

    # 빈 문자열
    if not value or value == '':
        return None

    # TagName 파싱
    if 'TagName=' in value:
        tag = parse_tag_name(value)
        if tag and tag != 'None':
            return tag
        return None

    # Vector 파싱
    if value.startswith('(') and ('X=' in value or 'Y=' in value or 'Z=' in value):
        vec = parse_vector(value)
        if vec:
            return vec

    # Array 파싱 (TimeArray, LocationArray 등)
    if 'Array' in field_name and value.startswith('('):
        arr = parse_array(value)
        if arr is not None:
            return arr

    # Boolean 파싱
    if value.lower() in ['true', 'false']:
        return value.lower() == 'true'

    # Float 파싱 시도
    float_val = parse_float(value)
    if float_val is not None:
        return float_val

    # 기본: 문자열 그대로 반환
    return value


def extract_notify_properties(notify: dict, target_fields: list) -> dict:
    """
    AnimNotify에서 CustomProperties의 특정 필드만 추출

    Args:
        notify: AnimNotify 딕셔너리
        target_fields: 추출할 필드 이름 리스트

    Returns:
        추출된 프로퍼티 딕셔너리
    """
    custom_props = notify.get('CustomProperties', {})
    result = {}

    for field in target_fields:
        if field in custom_props:
            value = custom_props[field]
            parsed = parse_custom_property(value, field)
            if parsed is not None:
                result[field] = parsed

    return result
