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

import importlib
import os

import bpy
from bpy.types import Operator
from bpy.props import IntProperty

import vse_toolbox


from vse_toolbox.bl_utils import (get_addon_prefs, get_scene_settings)
from vse_toolbox.file_utils import (read_file, norm_str)



class VSETB_OT_reload_addon(Operator):
    bl_idname = "vse_toolbox.reload_addon"
    bl_options = {"UNDO"}
    bl_label = 'Reload VSE ToolBox Addon'
    bl_description = 'Reload The VSE ToolBox Addon'

    def execute(self, context):

        print('Execute reload')

        vse_toolbox.unregister()
        importlib.reload(vse_toolbox)
        vse_toolbox.register()

        return {'FINISHED'}


class VSETB_OT_load_settings(Operator):
    bl_idname = "vse_toolbox.load_settings"
    bl_options = {"UNDO"}
    bl_label = 'Load Settings'
    bl_description = 'Load VSE ToolBox settings from config file'

    def set_config(self, data, values):
        for k, v in values.items():
            if not hasattr(data, k):
                print(f'{repr(data)} has no attribute {k}')
                continue

            if isinstance(v, list):
                data[k] = v
                return

            try:
                setattr(data, k, v)
            except Exception:
                print(f'Could not set property {k} with value {v} to {repr(data)}')

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

        if not prefs.config_path:
            return {'CANCELLED'}

        addon_config = read_file(os.path.expandvars(prefs.config_path))

        if not addon_config:
            return {'CANCELLED'}
        
        # Environ set
        for k, v in addon_config.get('environ', {}).items():
            os.environ[k] = str(v)

        addon_config['trackers'] = addon_config.get('trackers')
        trackers_config = addon_config.pop('trackers')
        for tracker_config in trackers_config:
            tracker_name = norm_str(tracker_config.pop('name'))

            if not hasattr(prefs.trackers, tracker_name):
                continue

            tracker = getattr(prefs.trackers, tracker_name)
            for k, v in tracker_config.items():
                setattr(tracker, k, v)
        
        spreadsheet_export_config = addon_config.pop('spreadsheet_export', {})
        spreadsheet_import_config = addon_config.pop('spreadsheet_import', {})
        upload_to_tracker_config = addon_config.pop('upload_to_tracker', {})
        import_shots_config = addon_config.pop('import_shots', {})

        project_name = addon_config.get('project_name')
        if project_name not in settings.projects:
            project = settings.projects.add()
            project.name = project_name
            settings.project_name = project_name
        #if project_name and project_name in settings.projects:
        #    settings.project_name = project_name

        # Project Properties
        project = settings.active_project
        self.set_config(project, addon_config)
        
        export_cells = project.spreadsheet_export.cells
        for k, v in spreadsheet_export_config.items():
            if k == 'cells':
                #project.spreadsheet.clear()

                for i, cell_data in enumerate(v):
                    if not 'name' in cell_data:
                        print(f'cell_data {cell_data} need to have a attribute name')
                        continue

                    cell = export_cells.get(cell_data['name'])

                    if not cell:
                        print(f"cell {cell_data['name']} not in spreadsheet")
                        continue

                    export_cells.move(list(export_cells).index(cell), i)

                    for prop_name in ('export_name', 'enabled'):
                        if prop_name in cell_data:
                            setattr(cell, prop_name, cell_data[prop_name])

            else:
                try:
                    setattr(project.spreadsheet_export, k, v)
                except Exception:
                    print(f'Could not set option {k} with value {v} to spreadsheet')


        import_cells = project.spreadsheet_import.cells
        if spreadsheet_import_config:
            import_cells.clear()

        cell_types = project.get_cell_types()
        for k, v in spreadsheet_import_config.items():
            if k == 'cells':
                for i, cell_data in enumerate(v):
                    if not 'name' in cell_data:
                        print(f'cell_data {cell_data} need to have a attribute name')
                        continue

                    cell = import_cells.add()
                    cell.name = cell_data['name']

                    norm_import_name = norm_str(cell_data.get('import_name', cell_data['name']))
                    import_name = next((n for n, t in cell_types.items() if norm_str(n) == norm_import_name), None)
                    if import_name is None:
                        print(f'import_name {norm_import_name} not in {list(cell_types.values())}')
                    else:
                        cell.import_name = import_name
                        cell.type = cell_types[import_name]
                    
                    if 'enabled' in cell_data:
                        try:
                            cell.enabled = cell_data['enabled']
                        except TypeError as e:
                            print(e)

            else:
                try:
                    setattr(project.spreadsheet_import, k, v)
                except Exception:
                    print(f'Could not set option {k} with value {v} to spreadsheet')

        # Upload to Tracker
        self.set_config(project.upload_to_tracker, upload_to_tracker_config)

        # Import Shots
        self.set_config(project.import_shots, import_shots_config)

        self.report({"INFO"}, 'Settings loaded with success')
        return {'FINISHED'}


class VSETB_OT_add_template(Operator):
    bl_idname = "vse_toolbox.add_template"
    bl_label = "Add Template"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        scn = context.scene
        settings = get_scene_settings()
        project = settings.active_project

        project.templates.add()

        return {'FINISHED'}
    

class VSETB_OT_remove_template(Operator):
    bl_idname = "vse_toolbox.remove_template"
    bl_label = "Remove Template"
    bl_options = {"REGISTER", "UNDO"}

    index : IntProperty()

    def execute(self, context):
        scn = context.scene
        settings = get_scene_settings()
        project = settings.active_project

        project.templates.remove(self.index)

        return {'FINISHED'}





classes = (
    VSETB_OT_reload_addon,
    VSETB_OT_load_settings,
    VSETB_OT_add_template,
    VSETB_OT_remove_template
)

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

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