#pragma once

#include <string>
#include <filesystem>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

/**
 * Enhanced package metadata structure with server source tracking
 * Supports both new multi-server format and legacy single-server migration
 */
struct PackageMetadata {
    std::string name;
    std::string version;
    std::string hash;
    std::string arch;
    std::string sourceServer;  // New field for server tracking
    std::string installDate;   // New field for installation tracking
    
    // Default constructor
    PackageMetadata() = default;
    
    // Constructor with all fields
    PackageMetadata(const std::string& name, const std::string& version, 
                   const std::string& hash, const std::string& arch,
                   const std::string& sourceServer, const std::string& installDate = "");
    
    // Serialization methods
    json toJson() const;
    static PackageMetadata fromJson(const json& j);
    
    // Migration support - convert from legacy format
    static PackageMetadata fromLegacyJson(const json& j, const std::string& defaultServer = "getpkg.xyz");
    
    // Validation
    bool isValid() const;
    std::string getValidationError() const;
    
    // File operations
    bool saveToFile(const std::filesystem::path& filePath) const;
    static PackageMetadata loadFromFile(const std::filesystem::path& filePath);
    
    // Utility methods
    std::string getCurrentTimestamp() const;
    bool needsUpdate(const std::string& remoteHash) const;
    
private:
    // Internal validation helpers
    bool isValidName() const;
    bool isValidVersion() const;
    bool isValidHash() const;
    bool isValidArch() const;
    bool isValidServerUrl() const;
    bool isValidTimestamp() const;
};

/**
 * Package metadata manager for handling the packages directory structure
 */
class PackageMetadataManager {
public:
    PackageMetadataManager();
    explicit PackageMetadataManager(const std::filesystem::path& configDir);
    
    // Directory management
    bool ensurePackagesDirectory();
    std::filesystem::path getPackagesDirectory() const;
    std::filesystem::path getPackageFilePath(const std::string& toolName) const;
    
    // Package operations
    bool savePackageMetadata(const PackageMetadata& metadata);
    PackageMetadata loadPackageMetadata(const std::string& toolName);
    bool packageExists(const std::string& toolName) const;
    bool removePackageMetadata(const std::string& toolName);
    
    // Migration support
    bool migrateFromLegacyFormat();
    std::vector<std::string> findLegacyPackageFiles() const;
    bool migrateLegacyPackageFile(const std::filesystem::path& legacyPath, const std::string& defaultServer = "getpkg.xyz");
    
    // Listing and enumeration
    std::vector<std::string> listInstalledPackages() const;
    std::vector<PackageMetadata> getAllPackageMetadata() const;
    
    // Validation and cleanup
    bool validateAllPackageMetadata() const;
    int cleanupInvalidMetadata();
    
private:
    std::filesystem::path configDir_;
    std::filesystem::path packagesDir_;
    
    // Helper methods
    bool isValidPackageFile(const std::filesystem::path& filePath) const;
    std::string extractToolNameFromPath(const std::filesystem::path& filePath) const;
};