
from pathlib import Path
from datetime import datetime
import subprocess

from ...core.bl_utils import get_bl_cmd
from ...core.lib_utils import get_asset_data
from ...core.catalog import read_catalog
from ... import constants

import bpy
from bpy.types import Operator
from bpy.props import StringProperty, EnumProperty


class ASSETLIB_OT_update_materials(Operator):
    bl_idname = 'assetlibrary.update_materials'
    bl_label = 'Update node'
    bl_options = {"REGISTER", "UNDO"}

    selection : EnumProperty(items=[(s, s.title(), '') for s in ('ALL', 'OBJECT', 'CURRENT')], default="CURRENT")

    @classmethod
    def poll(cls, context):
        return context.object and context.object.active_material

    def invoke(self, context, event):
        return context.window_manager.invoke_props_dialog(self)

    def execute(self, context):
        asset_libraries = context.preferences.filepaths.asset_libraries

        ob = bpy.context.object
        ntree = context.space_data.edit_tree
        ntree_name = ntree.name
        new_ntree = None

        if self.selection == 'OBJECT':
            materials = [s.material for s in ob.material_slots if s.material]
        elif self.selection == 'CURRENT':
            materials = [ob.active_material]
        else:
            materials = list(bpy.data.materials)
        
        mat_names = set(m.name for m in materials)

        for asset_library in asset_libraries:
            library_path = Path(asset_library.path)
            blend_files = [fp for fp in library_path.glob("**/*.blend") if fp.is_file()]

            images = list(bpy.data.images)
            materials = list(bpy.data.materials)# Storing original materials to compare with imported ones

            link = (asset_library.import_method == 'LINK')
            for blend_file in blend_files:
                print(blend_file)
                with bpy.data.libraries.load(str(blend_file), assets_only=True, link=link) as (data_from, data_to):

                    import_materials = [n for n in data_from.materials if n in mat_names]
                    print("import_materials", import_materials)
                    data_to.materials = import_materials

                    mat_names -= set(import_materials) # Store already updated nodes

                new_materials = set(m for m in bpy.data.materials if m not in materials)
                new_images = set(i for i in bpy.data.images if i not in images)
                # 

                for new_mat in new_materials:
                    new_mat_name = new_mat.library_weak_reference.id_name[2:]
                    local_mat = next((m for m in bpy.data.materials if m.name == new_mat_name and m != new_mat), None)

                    if not local_mat:
                        print(f'No local material {new_mat_name}')
                        continue
                    
                    print(f'Merge material {local_mat.name} into {new_mat.name}')

                    local_mat.user_remap(new_mat)
                    bpy.data.materials.remove(local_mat)

                    if not new_mat.library:
                        new_mat.name = new_mat_name
                    new_mat.asset_clear()


        return {'FINISHED'}


    def draw(self, context):
        layout = self.layout
        layout.prop(self, "selection", expand=True)


bl_classes = (
    ASSETLIB_OT_update_materials,
)


def register():
    for bl_class in bl_classes:
        bpy.utils.register_class(bl_class)


def unregister():
    for bl_class in reversed(bl_classes):
        bpy.utils.unregister_class(bl_class)
