#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/DockPanel/DockPanelInfo.h"
#include "DeerStudio/EditorEngine/DockPanel/DockPanelContext.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "Deer/Log.h"

#include "Deer/Path.h"
#include "Deer/DataStore.h"

#include "angelscript.h"
#include "scriptbuilder.h"

#include <iostream>
#include <filesystem>
#include <vector>
#include <string>

namespace fs = std::filesystem;

namespace Deer {
    namespace EditorEngine {
        CScriptBuilder dockPanelScriptBuilder;
    }
    
    void EditorEngine::loadDockPanels() {
        Path path = DataStore::rootPath / DEER_EDITOR_PANEL_PATH;

        if (!fs::exists(path) || !fs::is_directory(path)) {
            DEER_EDITOR_ENGINE_ERROR("Could not find folder " DEER_EDITOR_PANEL_PATH);
            return;
        }
        
        DEER_CORE_TRACE("Extracting UI Engine Scripts ");
        for (const auto& _dir : fs::directory_iterator(path)) {
            Path panelInfo_path = _dir.path() / "dockPanelModule.json";

            // A panel info is neded to load a panel
            if (!fs::exists(panelInfo_path) || !fs::is_regular_file(panelInfo_path)) {
                DEER_EDITOR_ENGINE_WARN("Editor engine did not find dockPanelModule.json in folder {0}", panelInfo_path.c_str());
                continue;
            }

            DockPanelInfo* dockPanelInfo = loadDockPanelInfo(panelInfo_path);
            if (dockPanelInfo->name == "null") {
                DEER_EDITOR_ENGINE_ERROR("Failed to load dock panel module from {0},\n incorrect panelInfo.json file", path.string().c_str());
                delete dockPanelInfo;
                continue;
            }

            int r; r = dockPanelScriptBuilder.StartNewModule(scriptEngine, dockPanelInfo->name.c_str());
            if (r < 0) {
                DEER_EDITOR_ENGINE_ERROR("Failed to create module for dock panel module {0}", path.string().c_str());
                delete dockPanelInfo;
                continue;
            }
            
            for (const auto& entry : fs::recursive_directory_iterator(_dir)) {
                if (entry.is_regular_file() && entry.path().extension() == ".as") {
                    r = dockPanelScriptBuilder.AddSectionFromFile(entry.path().string().c_str());
                    if (r < 0) {
                        DEER_EDITOR_ENGINE_ERROR("Failed loading script for module {0}\nscript: {1}", path.string().c_str(), entry.path().string().c_str());
                    }
                }
            }

            r = dockPanelScriptBuilder.BuildModule();
            if (r < 0) {
                DEER_EDITOR_ENGINE_ERROR("Failed compiling module {0}", path.string().c_str());
                delete dockPanelInfo;
                continue;
            }

            dockPanelModules.push_back(DockPanelContext(scriptEngine->GetModule(dockPanelInfo->name.c_str()), dockPanelInfo));
        }
    }
}