#include "core/rendering/screenshot.hpp"

#include <SDL3/SDL.h>

#include <chrono>      // Para system_clock, time_point
#include <ctime>       // Para localtime, strftime, time_t, tm
#include <filesystem>  // Para create_directories
#include <string>      // Para string
#include <vector>      // Para vector

#include "core/rendering/surface.hpp"  // Para Surface
#include "external/stb_image_write.h"  // Para stbi_write_png (impl en source/external/stb_image_write_impl.cpp)

namespace Screenshot {

    namespace {
        // Genera la ruta del fichero y crea la carpeta si no existe
        auto generateFilePath(std::string& filename) -> std::string {
            std::filesystem::create_directories("screenshots");

            auto now = std::chrono::system_clock::now();
            std::time_t time = std::chrono::system_clock::to_time_t(now);
            const std::tm* tm = std::localtime(&time);

            char timestamp[20];
            std::strftime(timestamp, sizeof(timestamp), "%Y%m%d_%H%M%S", tm);

            filename = std::string("scr_") + timestamp + ".png";
            return "screenshots/" + filename;
        }

        // Convierte ARGB8888 a RGBA8888 in-place y guarda como PNG
        auto writePng(Uint32* buffer, int width, int height, const std::string& filepath) -> bool {
            for (int i = 0; i < width * height; ++i) {
                Uint32 p = buffer[i];
                Uint32 a = (p >> 24) & 0xFF;
                Uint32 r = (p >> 16) & 0xFF;
                Uint32 g = (p >> 8) & 0xFF;
                Uint32 b = p & 0xFF;
                buffer[i] = r | (g << 8) | (b << 16) | (a << 24);
            }
            return stbi_write_png(filepath.c_str(), width, height, 4, buffer, width * 4) != 0;
        }
    }  // namespace

    auto save(const Surface& surface) -> std::string {
        const int WIDTH = surface.getWidth();
        const int HEIGHT = surface.getHeight();
        std::vector<Uint32> buffer(static_cast<size_t>(WIDTH * HEIGHT));
        surface.toARGBBuffer(buffer.data());

        std::string filename;
        std::string filepath = generateFilePath(filename);

        return writePng(buffer.data(), WIDTH, HEIGHT, filepath) ? filename : "";
    }

    auto save(const Uint32* buffer, int width, int height) -> std::string {
        // Copia local para la conversión ARGB → RGBA
        std::vector<Uint32> copy(buffer, buffer + static_cast<size_t>(width * height));

        std::string filename;
        std::string filepath = generateFilePath(filename);

        return writePng(copy.data(), width, height, filepath) ? filename : "";
    }

}  // namespace Screenshot
