# -*- coding: utf-8 -*-
"""
support.py - 节点支座相关函数

用于设置节点的边界条件（约束）

SAP2000 API:
- PointObj.SetRestraint(Name, Value, ItemType)
- PointObj.GetRestraint(Name)
- PointObj.DeleteRestraint(Name, ItemType)
"""

from typing import Tuple, Optional, List
from .enums import PointSupportType, ItemType, SUPPORT_RESTRAINTS


def set_point_support(
    model,
    point_name: str,
    support_type: PointSupportType,
    item_type: ItemType = ItemType.OBJECT
) -> int:
    """
    设置节点支座类型
    
    这是设置支座的便捷方法，使用预定义的支座类型。
    
    Args:
        model: SapModel 对象
        point_name: 节点名称
        support_type: 支座类型
            - FIXED: 固定支座 (全约束)
            - HINGED: 铰接支座 (约束平动，释放转动)
            - ROLLER: 滚动支座 (仅约束 Z 方向)
            - FREE: 自由 (无约束)
        item_type: 项目类型
    
    Returns:
        0 表示成功，非 0 表示失败
    
    Example:
        # 设置节点 "1" 为固定支座
        set_point_support(model, "1", PointSupportType.FIXED)
        
        # 设置节点 "2" 为铰接支座
        set_point_support(model, "2", PointSupportType.HINGED)
    """
    restraints = list(SUPPORT_RESTRAINTS.get(support_type, (False,) * 6))
    result = model.PointObj.SetRestraint(str(point_name), restraints, item_type)
    # 解析返回值
    if isinstance(result, (list, tuple)) and len(result) >= 2:
        return result[-1]
    return result


def set_point_restraint(
    model,
    point_name: str,
    restraints: Tuple[bool, bool, bool, bool, bool, bool],
    item_type: ItemType = ItemType.OBJECT
) -> int:
    """
    设置节点自定义约束
    
    可以自由组合 6 个自由度的约束状态。
    
    Args:
        model: SapModel 对象
        point_name: 节点名称
        restraints: 约束状态 (U1, U2, U3, R1, R2, R3)
            - True: 约束该自由度
            - False: 释放该自由度
        item_type: 项目类型
    
    Returns:
        0 表示成功
    
    Example:
        # 约束 X, Y 平动，释放其他
        set_point_restraint(model, "1", (True, True, False, False, False, False))
        
        # 约束所有平动，释放所有转动
        set_point_restraint(model, "2", (True, True, True, False, False, False))
    """
    return model.PointObj.SetRestraint(str(point_name), list(restraints), item_type)


def get_point_restraint(
    model,
    point_name: str
) -> Optional[Tuple[bool, bool, bool, bool, bool, bool]]:
    """
    获取节点约束状态
    
    Args:
        model: SapModel 对象
        point_name: 节点名称
    
    Returns:
        约束状态元组 (U1, U2, U3, R1, R2, R3)，失败返回 None
    
    Example:
        restraints = get_point_restraint(model, "1")
        if restraints:
            print(f"U1约束: {restraints[0]}, U2约束: {restraints[1]}")
    """
    try:
        result = model.PointObj.GetRestraint(str(point_name))
        if isinstance(result, (list, tuple)) and len(result) >= 2:
            restraints = result[0]
            ret = result[1]
            if ret == 0 and restraints:
                return tuple(restraints)
    except Exception:
        pass
    return None


def get_point_support_type(
    model,
    point_name: str
) -> Optional[PointSupportType]:
    """
    获取节点支座类型
    
    根据约束状态推断支座类型。
    
    Args:
        model: SapModel 对象
        point_name: 节点名称
    
    Returns:
        支座类型，如果不匹配预定义类型则返回 None
    
    Example:
        support_type = get_point_support_type(model, "1")
        if support_type == PointSupportType.FIXED:
            print("这是固定支座")
    """
    restraints = get_point_restraint(model, point_name)
    if restraints:
        for support_type, expected in SUPPORT_RESTRAINTS.items():
            if restraints == expected:
                return support_type
    return None


def delete_point_restraint(
    model,
    point_name: str,
    item_type: ItemType = ItemType.OBJECT
) -> int:
    """
    删除节点约束（释放所有自由度）
    
    Args:
        model: SapModel 对象
        point_name: 节点名称
        item_type: 项目类型
    
    Returns:
        0 表示成功
    
    Example:
        delete_point_restraint(model, "1")
    """
    return model.PointObj.DeleteRestraint(str(point_name), item_type)


def get_points_with_support(model) -> List[str]:
    """
    获取所有有支座的节点名称列表
    
    Args:
        model: SapModel 对象
    
    Returns:
        有支座的节点名称列表
    
    Example:
        supported_points = get_points_with_support(model)
        print(f"共有 {len(supported_points)} 个支座节点")
    """
    supported = []
    
    # 获取所有节点
    result = model.PointObj.GetNameList(0, [])
    if not isinstance(result, (list, tuple)) or len(result) < 3:
        return supported
    
    names = result[1]
    if not names:
        return supported
    
    # 检查每个节点
    for name in names:
        restraints = get_point_restraint(model, name)
        if restraints and any(restraints):
            supported.append(name)
    
    return supported
