
import importlib
import bpy

from bpy.types import Operator
from bpy.props import (BoolProperty, EnumProperty, StringProperty, IntProperty)
from .core.bl_utils import get_addon_prefs, unique_name


class ASSETLIB_OT_reload_addon(Operator):
    bl_idname = "assetlibrary.reload_addon"
    bl_options = {"UNDO"}
    bl_label = 'Reload Asset Library Addon'
    bl_description = 'Reload The Asset Library Addon and the addapters'

    def execute(self, context):

        print('Execute reload', __package__)

        addon = importlib.import_module(__package__)

        addon.unregister()
        importlib.reload(addon)
        for mod in addon.modules:
            importlib.reload(mod)
        addon.register()

        return {'FINISHED'}


class ASSETLIB_OT_remove_library(Operator):
    bl_idname = "assetlibrary.remove_library"
    bl_options = {"REGISTER", "UNDO"}
    bl_label = 'Remove Library'
    bl_description = 'Remove Library'

    index : IntProperty(default=-1)

    def execute(self, context):
        prefs = get_addon_prefs()

        addon_lib = prefs.libraries[self.index]

        bl_libs = context.preferences.filepaths.asset_libraries
        if (bl_lib := bl_libs.get(addon_lib.name)) and bl_lib.path == addon_lib.path:
            index = list(bl_libs).index(bl_lib)
            bpy.ops.preferences.asset_library_remove(index=index)

        prefs.libraries.remove(self.index)
        return {'FINISHED'}


class ASSETLIB_OT_add_library(Operator):
    bl_idname = "assetlibrary.add_library"
    bl_options = {"REGISTER", "UNDO"}
    bl_label = 'Add Library'
    bl_description = 'Add Library'

    def execute(self, context):
        prefs = get_addon_prefs()

        lib = prefs.libraries.add()
        lib.expand = True
        lib.name = unique_name('Asset Library', [l.name for l in prefs.libraries])

        return {'FINISHED'}


class ASSETLIB_OT_synchronize(Operator):
    bl_idname = "assetlibrary.synchronize"
    bl_options = {"REGISTER", "UNDO"}
    bl_label = 'Synchronize'
    bl_description = 'Synchronize Action Lib to Local Directory'

    name : StringProperty()
    diff : StringProperty()
    blocking : BoolProperty(default=False)
    mode : EnumProperty(items=[(i.replace(' ', '_').upper(), i, '') for i in ('None', 'All', 'Auto Bundle')], default='NONE')
    directory : StringProperty(subtype='DIR_PATH')
    #conform : BoolProperty(default=False)
    #def refresh(self):
    #    for area in suitable_areas(bpy.context.screen):
    #        bpy.ops.asset.library_refresh({"area": area, 'region': area.regions[3]})
            #space_data.activate_asset_by_id(asset, deferred=deferred)

    def execute(self, context):
        prefs = get_addon_prefs()

        libs = []
        if self.name:
            libs += [prefs.libraries[self.name]]

        if self.mode == 'ALL':
            libs += prefs.libraries.values()
        elif self.mode == 'AUTO_BUNDLE':
            libs += [l for l in prefs.libraries if l.auto_bundle]
        
        if not libs:
            return {"CANCELLED"}
                
        lib_datas = [l.to_dict() for l in libs]

        print(f'Bundle Libraries: {[l.name for l in libs]}')

        script_code = dedent(f"""
            import bpy
            prefs = bpy.context.preferences.addons["asset_library"].preferences

            for lib_data in {lib_datas}:
                lib = prefs.env_libraries.add()
                lib.set_dict(lib_data)
                lib.plugin.bundle(cache_diff='{self.diff}')
            
            bpy.ops.wm.quit_blender()
            """)

        script_path = Path(bpy.app.tempdir) / 'bundle_library.py'
        script_path.write_text(script_code)

        print(script_code)

        #raise Exception()

        cmd = get_bl_cmd(script=str(script_path), background=True)

        #print(cmd) 
        if self.blocking:
            subprocess.call(cmd)
            bpy.app.timers.register(refresh_asset_browsers, first_interval=0.2)
        else:
            subprocess.Popen(cmd)
        
        return {'FINISHED'}


classes = (
    ASSETLIB_OT_reload_addon,
    ASSETLIB_OT_add_library,
    ASSETLIB_OT_remove_library,
    ASSETLIB_OT_synchronize
)


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


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