#pragma once

#include <cstddef>
#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>

// Entrada d'un recurs dins el pack (format AEE, equivalent a CCAE).
struct ResourceEntry {
    std::string filename;
    uint64_t offset{0};
    uint64_t size{0};
    uint32_t checksum{0};
};

// Pack binari de recursos carregat a memòria. Formato:
//   Header:   "AEE1" (4 bytes) + version uint32 + resource_count uint32
//   Index:    per cada recurs -> filename_len uint32 + filename + offset uint64
//             + size uint64 + checksum uint32
//   Payload:  data_size uint64 + bytes xifrats amb XOR (DEFAULT_ENCRYPT_KEY)
class ResourcePack {
   public:
    ResourcePack();
    ~ResourcePack();

    // I/O del fitxer
    auto loadPack(const std::string& pack_file) -> bool;
    auto savePack(const std::string& pack_file) -> bool;

    // Builders usats per l'eina pack_resources
    auto addFile(const std::string& filename, const std::string& filepath) -> bool;
    auto addDirectory(const std::string& directory) -> bool;

    [[nodiscard]] auto getResource(const std::string& filename) -> std::vector<uint8_t>;
    [[nodiscard]] auto hasResource(const std::string& filename) const -> bool;

    void clear();
    [[nodiscard]] auto getResourceCount() const -> size_t;
    [[nodiscard]] auto getResourceList() const -> std::vector<std::string>;

    static const std::string DEFAULT_ENCRYPT_KEY;

   private:
    std::unordered_map<std::string, ResourceEntry> resources_;
    std::vector<uint8_t> data_;
    bool loaded_{false};

    static auto calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t;
    static void encryptData(std::vector<uint8_t>& data, const std::string& key);
    static void decryptData(std::vector<uint8_t>& data, const std::string& key);
};
