# SPDX-License-Identifier: MIT OR GPL-3.0-or-later
from collections.abc import Set as AbstractSet
from typing import TYPE_CHECKING, Optional

from bpy.types import Context, Panel

from .utils import (
    MaterialInfo,
    find_body_mesh,
    find_face_mesh,
    get_material_face_count,
    is_retained_material,
)

if TYPE_CHECKING:
    from bpy.types import Object


class VRM_PT_body_mesh_separator(Panel):
    """Body网格分离面板"""

    bl_idname = "VRM_PT_body_mesh_separator"
    bl_label = "Body Mesh Separator"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_category = "VRM"
    bl_options: AbstractSet[str] = set()

    @classmethod
    def poll(cls, context: Context) -> bool:
        """检查是否应该显示面板 - 仅在选中包含Body网格的Armature时显示"""
        armature = cls._get_armature(context)
        if armature is None:
            return False
        body_mesh = find_body_mesh(armature)
        return body_mesh is not None

    @classmethod
    def _get_armature(cls, context: Context) -> Optional["Object"]:
        """获取当前选中的Armature对象"""
        active_object = context.active_object
        if active_object is None:
            return None

        if active_object.type == "ARMATURE":
            return active_object

        # 如果选中的是网格，检查其父对象是否为Armature
        if active_object.parent is not None and active_object.parent.type == "ARMATURE":
            return active_object.parent

        return None

    def draw(self, context: Context) -> None:
        """绘制面板UI"""
        layout = self.layout
        armature = self._get_armature(context)

        if armature is None:
            layout.label(text="未找到Armature对象", icon="ERROR")
            return

        body_mesh = find_body_mesh(armature)
        if body_mesh is None:
            layout.label(text="未找到Body网格对象", icon="ERROR")
            return

        mesh_data = body_mesh.data
        if mesh_data is None:
            layout.label(text="Body网格数据无效", icon="ERROR")
            return

        # 显示材质统计信息（区分保留材质和可分离材质）
        box = layout.box()
        box.label(text="材质列表", icon="MATERIAL")

        # 收集材质信息，使用is_retained_material和is_separable_material分类
        materials_info: list[MaterialInfo] = []
        for i, material in enumerate(mesh_data.materials):
            if material is not None:
                face_count = get_material_face_count(mesh_data, i)
                is_retained = is_retained_material(material.name)
                materials_info.append(
                    MaterialInfo(
                        name=material.name,
                        index=i,
                        face_count=face_count,
                        is_skin=is_retained,  # 使用is_skin字段存储保留状态
                    )
                )

        # 显示材质列表，区分保留材质（SKIN/HAIR）和可分离材质（CLOTH和其他）
        has_separable = False
        for mat_info in materials_info:
            row = box.row()
            if mat_info.is_skin:  # is_skin字段现在表示是否为保留材质
                # 保留材质（SKIN/HAIR）标记为"[保留]"
                row.label(text=f"[保留] {mat_info.name}", icon="CHECKMARK")
            else:
                # 可分离材质（CLOTH和其他）标记为"[分离]"
                row.label(text=f"[分离] {mat_info.name}", icon="MESH_DATA")
                has_separable = True
            row.label(text=f"{mat_info.face_count} 面")

        # 显示分离操作按钮
        layout.separator()
        col = layout.column()
        col.enabled = has_separable
        col.operator(
            "vrm.separate_non_skin_faces",
            text="分离非皮肤面",
            icon="MESH_DATA",
        )

        if not has_separable:
            layout.label(text="没有可分离材质", icon="INFO")

        # 显示UV边融并按钮 (Requirements 1.2, 1.3)
        layout.separator()
        armature = self._get_armature(context)
        face_mesh = find_face_mesh(armature) if armature else None
        has_vrm_structure = body_mesh is not None and face_mesh is not None

        col = layout.column()
        col.enabled = has_vrm_structure
        col.operator(
            "vrm.merge_uv_edges",
            text="根据UV转四边面",
            icon="MOD_EDGESPLIT",
        )

        if not has_vrm_structure:
            layout.label(text="需要Body和Face网格", icon="INFO")
