#pragma once

#include <string>
#include <vector>
#include <filesystem>
#include <memory>
#include "PackageMetadata.hpp"
#include "ServerManager.hpp"

/**
 * Migration manager for handling the transition from single-server to multi-server configuration
 * Handles migration of server configuration, package metadata, and directory structure
 */
class MigrationManager {
public:
    MigrationManager();
    explicit MigrationManager(const std::filesystem::path& configDir);
    
    // Main migration interface
    bool needsMigration() const;
    bool performMigration();
    
    // Migration status and reporting
    struct MigrationResult {
        bool success = false;
        int migratedPackages = 0;
        int totalPackages = 0;
        bool serverConfigMigrated = false;
        bool packageDirectoryCreated = false;
        std::vector<std::string> errors;
        std::vector<std::string> warnings;
    };
    
    MigrationResult getLastMigrationResult() const { return lastResult_; }
    
    // Individual migration components (for testing and granular control)
    bool migrateServerConfiguration();
    bool migratePackageMetadata();
    bool createPackagesDirectory();
    bool validateMigration() const;
    
    // Rollback capabilities
    bool canRollback() const;
    bool performRollback();
    
    // Backup and restore
    bool createBackup();
    bool restoreFromBackup();
    
private:
    std::filesystem::path configDir_;
    std::filesystem::path packagesDir_;
    std::filesystem::path backupDir_;
    std::filesystem::path legacyTokenDir_;
    
    std::unique_ptr<PackageMetadataManager> packageManager_;
    std::unique_ptr<ServerManager> serverManager_;
    
    mutable MigrationResult lastResult_;
    
    // Migration detection helpers
    bool hasLegacyServerConfiguration() const;
    bool hasLegacyPackageFiles() const;
    bool hasNewFormatConfiguration() const;
    
    // Migration implementation helpers
    bool migrateLegacyTokenFile();
    bool migrateLegacyPackageFile(const std::filesystem::path& legacyPath);
    bool movePackageFilesToSubdirectory();
    bool updatePackageMetadataFormat();
    bool cleanupLegacyFiles();
    
    // Backup and rollback helpers
    bool backupLegacyConfiguration();
    bool backupExistingConfiguration();
    std::string generateBackupTimestamp() const;
    
    // Validation helpers
    bool validateServerConfiguration() const;
    bool validatePackageMetadata() const;
    bool validateDirectoryStructure() const;
    
    // Error handling and logging
    void logError(const std::string& message) const;
    void logWarning(const std::string& message) const;
    void logInfo(const std::string& message) const;
    
    // File system utilities
    bool safeFileMove(const std::filesystem::path& source, const std::filesystem::path& destination);
    bool safeFileCopy(const std::filesystem::path& source, const std::filesystem::path& destination);
    bool safeDirectoryCreate(const std::filesystem::path& directory);
    std::vector<std::filesystem::path> findFilesWithExtension(const std::filesystem::path& directory, const std::string& extension) const;
    
    // Constants
    static constexpr const char* LEGACY_TOKEN_FILENAME = "write_token.txt";
    static constexpr const char* SERVERS_CONFIG_FILENAME = "servers.json";
    static constexpr const char* PACKAGES_DIRECTORY_NAME = "packages";
    static constexpr const char* BACKUP_DIRECTORY_NAME = "migration_backup";
    static constexpr const char* DEFAULT_SERVER_URL = "getpkg.xyz";
};