#include "ui/Application.h"
#include "utils/Logger.h"
#include <pxr/base/plug/registry.h>
#include <exception>
#include <Windows.h>
#include <string>

static void SetUsdPluginPath() {
    char exePath[MAX_PATH];
    GetModuleFileNameA(nullptr, exePath, MAX_PATH);
    std::string exeDir(exePath);
    size_t lastSlash = exeDir.find_last_of("\\/");
    if (lastSlash != std::string::npos) {
        exeDir = exeDir.substr(0, lastSlash);
    }

    std::string pluginPath = exeDir + "\\usd";
    SetEnvironmentVariableA("PXR_PLUGINPATH_NAME", pluginPath.c_str());

    std::vector<std::string> pluginPaths;
    WIN32_FIND_DATAA findData;
    std::string searchPattern = pluginPath + "\\*";
    HANDLE hFind = FindFirstFileA(searchPattern.c_str(), &findData);
    if (hFind != INVALID_HANDLE_VALUE) {
        do {
            if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                std::string dirName(findData.cFileName);
                if (dirName != "." && dirName != "..") {
                    std::string plugInfoPath = pluginPath + "\\" + dirName + "\\resources\\plugInfo.json";
                    DWORD attrs = GetFileAttributesA(plugInfoPath.c_str());
                    if (attrs != INVALID_FILE_ATTRIBUTES && !(attrs & FILE_ATTRIBUTE_DIRECTORY)) {
                        pluginPaths.push_back(plugInfoPath);
                    }
                }
            }
        } while (FindNextFileA(hFind, &findData));
        FindClose(hFind);
    }

    if (!pluginPaths.empty()) {
        auto& registry = pxr::PlugRegistry::GetInstance();
        auto registered = registry.RegisterPlugins(pluginPaths);
        LOG_INFO("Registered " + std::to_string(registered.size()) + " USD plugins from " + pluginPath);
    } else {
        LOG_WARNING("No USD plugins found at " + pluginPath);
    }
}

int main(int argc, char* argv[]) {
    try {
        UsdLayerManager::Logger::Instance().SetLogLevel(UsdLayerManager::LogLevel::Info);
        
        LOG_INFO("=== USD Layer Manager Starting ===");

        SetUsdPluginPath();
        
        UsdLayerManager::Application app;
        if (!app.Initialize("USD Layer Manager", 1280, 720)) {
            LOG_ERROR("Failed to initialize application");
            return 1;
        }
        
        app.Run();
        app.Shutdown();
        
        LOG_INFO("=== USD Layer Manager Exiting ===");
        return 0;
        
    } catch (const std::exception& e) {
        LOG_ERROR(std::string("Unhandled exception: ") + e.what());
        return 1;
    } catch (...) {
        LOG_ERROR("Unknown exception occurred");
        return 1;
    }
}
