# SPDX-License-Identifier: GPL-2.0-or-later


"""
Action Library - GUI definition.
"""

import bpy
from pathlib import Path

from bpy.types import (
    AssetHandle,
    Context,
    Header,
    Menu,
    Panel,
    UIList,
    WindowManager,
    WorkSpace,
)

from bpy_extras import asset_utils
from asset_library.common.bl_utils import (
    get_addon_prefs,
    get_object_libraries,
)

from asset_library.common.functions import (
    get_active_library
)



def pose_library_panel_poll():
    return bpy.context.object and bpy.context.object.mode == 'POSE'

class PoseLibraryPanel:
    @classmethod
    def pose_library_panel_poll(cls, context: Context) -> bool:
        return bool(
            context.object
            and context.object.mode == 'POSE'
        )

    @classmethod
    def poll(cls, context: Context) -> bool:
        return cls.pose_library_panel_poll(context);


class AssetLibraryMenu:
    @classmethod
    def poll(cls, context):
        from bpy_extras.asset_utils import SpaceAssetInfo
        return SpaceAssetInfo.is_asset_browser_poll(context)


class ASSETLIB_PT_libraries(Panel):
    bl_label = "Libraries"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Item'

    @classmethod
    def poll(cls, context: Context) -> bool:
        return context.object and get_object_libraries(context.object)

    def draw(self, context: Context) -> None:
        layout = self.layout

        for f in get_object_libraries(context.object):
            row = layout.row(align=True)
            row.label(text=f)
            row.operator("assetlib.open_blend", icon='FILE_BLEND', text='').filepath = f

'''
class ASSETLIB_PT_pose_library_usage(Panel):
    bl_space_type = 'FILE_BROWSER'
    bl_region_type = "TOOLS"
    bl_label = "Action Library"
    # asset_categories = {'ANIMATIONS'}

    @classmethod
    def poll(cls, context: Context) -> bool:
        sp = context.space_data

        if not context.object or not context.object.mode == 'POSE':
            return False

        if not (sp and sp.type == 'FILE_BROWSER' and sp.browse_mode == 'ASSETS'):
            return False

        return True

    def draw(self, context: Context) -> None:
        layout = self.layout
        wm = context.window_manager

        sp = context.space_data
        sp.params.asset_library_ref

        if sp.params.asset_library_ref == 'LOCAL':
            col = layout.column(align=True)
            row = col.row(align=True)
            row.operator("poselib.create_pose_asset", text="Create Pose", icon='POSE_HLT').activate_new_action = False
            row.operator("actionlib.replace_pose", text='Replace Pose', icon='FILE_REFRESH')
            col.operator("actionlib.create_anim_asset", text="Create Anim", icon='ANIM')
            
            col.separator()
            row = col.row(align=True)
            row.operator("actionlib.edit_action", text='Edit Action', icon='ACTION')
            row.operator("actionlib.clear_action", text='Finish Edit', icon='CHECKBOX_HLT')
            
            col.separator()
            col.operator("actionlib.generate_preview", icon='RESTRICT_RENDER_OFF', text="Generate Thumbnail")
            col.operator("actionlib.update_action_data", icon='FILE_TEXT', text="Update Action Data")
        else:
            col = layout.column(align=True)
            row = col.row(align=True)
            row.operator("actionlib.store_anim_pose", text='Store Anim/Pose', icon='ACTION')
'''


class ASSETLIB_PT_pose_library_editing(PoseLibraryPanel, asset_utils.AssetBrowserPanel, Panel):
    bl_space_type = 'FILE_BROWSER'
    bl_region_type = "TOOL_PROPS"
    bl_label = "Metadata"
    #bl_options = {'HIDE_HEADER'}
    # asset_categories = {'ANIMATIONS'}

    @classmethod
    def poll(cls, context: Context) -> bool:
        sp = context.space_data

        if not (sp and sp.type == 'FILE_BROWSER' and sp.browse_mode == 'ASSETS'):
            return False

        if not (context.active_file and context.active_file.asset_data):
            return False

        return True

    def draw(self, context: Context) -> None:
        layout = self.layout

        layout.use_property_split = True
        asset_data = context.active_file.asset_data
        metadata = ['camera', 'is_single_frame', 'rest_pose']
        
        if 'camera' in asset_data.keys():
            layout.prop(asset_data, f'["camera"]', text='Camera', icon='CAMERA_DATA') 
        if 'is_single_frame' in asset_data.keys():
            layout.prop(asset_data, f'["is_single_frame"]', text='Is Single Frame') 
        if 'rest_pose' in asset_data.keys():
            layout.prop(asset_data, f'["rest_pose"]', text='Rest Pose', icon='ACTION') 
        if 'filepath' in asset_data.keys():
            layout.prop(asset_data, f'["filepath"]', text='Filepath') 


class ASSETLIB_MT_context_menu(AssetLibraryMenu, Menu):
    bl_label = "Asset Library Menu"
    
    @classmethod
    def poll(cls, context):
        if not asset_utils.SpaceAssetInfo.is_asset_browser(context.space_data):
            cls.poll_message_set("Current editor is not an asset browser")
            return False
        
        prefs = get_addon_prefs()
        asset_lib_ref = context.space_data.params.asset_library_ref

        lib = get_active_library()
        if not lib:
            return False
        
        return True

    def draw(self, context):
        lib = get_active_library()
        lib.library_type.draw_context_menu(self.layout)


def is_option_region_visible(context, space):
    from bpy_extras.asset_utils import SpaceAssetInfo

    if SpaceAssetInfo.is_asset_browser(space):
        pass
    # For the File Browser, there must be an operator for there to be options
    # (irrelevant for the Asset Browser).
    elif not space.active_operator:
        return False

    for region in context.area.regions:
        if region.type == 'TOOL_PROPS' and region.width <= 1:
            return False

    return True


def draw_assetbrowser_header(self, context):
    lib = get_active_library()

    if not lib:
        bpy.types.FILEBROWSER_HT_header._draw_asset_browser_buttons(self, context)
        return

    space_data = context.space_data
    params = context.space_data.params

    row = self.layout.row(align=True)
    row.separator()

    row.operator("assetlib.bundle", icon='UV_SYNC_SELECT', text='').name = lib.name
    #op
    #op.clean = False
    #op.only_recent = True

    lib.library_type.draw_header(row)

    if context.selected_files and context.active_file:
        row.separator()
        row.label(text=context.active_file.name)

    row.separator_spacer()

    sub = row.row()
    sub.ui_units_x = 10
    sub.prop(params, "filter_search", text="", icon='VIEWZOOM')

    row.separator_spacer()

    row.prop_with_popover(
        params,
        "display_type",
        panel="ASSETBROWSER_PT_display",
        text="",
        icon_only=True,
    )

    row.operator(
        "screen.region_toggle",
        text="",
        icon='PREFERENCES',
        depress=is_option_region_visible(context, space_data)
    ).region_type = 'TOOL_PROPS'


### Messagebus subscription to monitor asset library changes.
_msgbus_owner = object()

def _on_asset_library_changed() -> None:
    """Update areas when a different asset library is selected."""
    refresh_area_types = {'DOPESHEET_EDITOR', 'VIEW_3D'}
    for win in bpy.context.window_manager.windows:
        for area in win.screen.areas:
            if area.type not in refresh_area_types:
                continue

            area.tag_redraw()

def register_message_bus() -> None:

    bpy.msgbus.subscribe_rna(
        key=(bpy.types.FileAssetSelectParams, "asset_library_ref"),
        owner=_msgbus_owner,
        args=(),
        notify=_on_asset_library_changed,
        options={'PERSISTENT'},
    )

def unregister_message_bus() -> None:
    bpy.msgbus.clear_by_owner(_msgbus_owner)

@bpy.app.handlers.persistent
def _on_blendfile_load_pre(none, other_none) -> None:
    # The parameters are required, but both are None.
    unregister_message_bus()

@bpy.app.handlers.persistent
def _on_blendfile_load_post(none, other_none) -> None:
    # The parameters are required, but both are None.
    register_message_bus()


classes = (
    ASSETLIB_PT_pose_library_editing,
    #ASSETLIB_PT_pose_library_usage,
    ASSETLIB_MT_context_menu,
    ASSETLIB_PT_libraries
)


def register() -> None:
    for cls in classes:
        bpy.utils.register_class(cls)

    bpy.types.FILEBROWSER_HT_header._draw_asset_browser_buttons = bpy.types.FILEBROWSER_HT_header.draw_asset_browser_buttons
    bpy.types.FILEBROWSER_HT_header.draw_asset_browser_buttons = draw_assetbrowser_header

    #WorkSpace.active_pose_asset_index = bpy.props.IntProperty(
    #    name="Active Pose Asset",
    #    # TODO explain which list the index belongs to, or how it can be used to get the pose.
    #    description="Per workspace index of the active pose asset"
    #)
    # Register for window-manager. This is a global property that shouldn't be
    # written to files.
    #WindowManager.pose_assets = bpy.props.CollectionProperty(type=AssetHandle)

    # bpy.types.UI_MT_list_item_context_menu.prepend(pose_library_list_item_context_menu)
    # bpy.types.ASSETLIB_MT_context_menu.prepend(pose_library_list_item_context_menu)
    # bpy.types.ACTIONLIB_MT_context_menu.prepend(pose_library_list_item_context_menu)
    #bpy.types.ASSETBROWSER_MT_editor_menus.append(draw_assetbrowser_header)

    register_message_bus()
    bpy.app.handlers.load_pre.append(_on_blendfile_load_pre)
    bpy.app.handlers.load_post.append(_on_blendfile_load_post)


def unregister() -> None:
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)

    bpy.types.FILEBROWSER_HT_header.draw_asset_browser_buttons = bpy.types.FILEBROWSER_HT_header._draw_asset_browser_buttons
    del bpy.types.FILEBROWSER_HT_header._draw_asset_browser_buttons

    unregister_message_bus()

    #del WorkSpace.active_pose_asset_index
    #del WindowManager.pose_assets

    # bpy.types.UI_MT_list_item_context_menu.remove(pose_library_list_item_context_menu)
    # bpy.types.ASSETLIB_MT_context_menu.remove(pose_library_list_item_context_menu)
    # bpy.types.ACTIONLIB_MT_context_menu.remove(pose_library_list_item_context_menu)
    #bpy.types.ASSETBROWSER_MT_editor_menus.remove(draw_assetbrowser_header)
