#ifdef _DEBUG

#include "game/editor/room_saver.hpp"

#include <cmath>     // Para std::round
#include <fstream>   // Para ifstream, ofstream, istreambuf_iterator
#include <iostream>  // Para cout, cerr
#include <sstream>   // Para ostringstream

#include "utils/defines.hpp"  // Para Tile::SIZE

// Carga el YAML original directamente del filesystem (no del resource pack)
auto RoomSaver::loadYAML(const std::string& file_path) -> fkyaml::node {
    std::ifstream file(file_path);
    if (!file.is_open()) {
        std::cerr << "RoomSaver: Cannot open " << file_path << "\n";
        return {};
    }

    std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
    file.close();
    return fkyaml::node::deserialize(content);
}

// Convierte una room connection al formato YAML
auto RoomSaver::roomConnectionToYAML(const std::string& connection) -> std::string {
    if (connection == "0" || connection.empty()) { return "null"; }
    return connection;
}

// Convierte la dirección del conveyor belt a string
auto RoomSaver::conveyorBeltToString(int direction) -> std::string {
    if (direction < 0) { return "left"; }
    if (direction > 0) { return "right"; }
    return "none";
}

// Genera el YAML completo como texto con formato compacto
auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& room_data) -> std::string {  // NOLINT(readability-function-cognitive-complexity)
    std::ostringstream out;

    // --- Cabecera: nombre como comentario ---
    out << "# " << room_data.name << "\n";

    // --- Sección room ---
    out << "room:\n";

    // Escribir todos los campos name_* del YAML original (preserva name_ca, name_en, etc.)
    if (original_yaml.contains("room")) {
        const auto& room_node = original_yaml["room"];
        for (auto it = room_node.begin(); it != room_node.end(); ++it) {
            const auto KEY = it.key().get_value<std::string>();
            if (KEY.substr(0, 5) == "name_") {
                out << "  " << KEY << ": \"" << it.value().get_value<std::string>() << "\"\n";
            }
        }
    }

    out << "  bgColor: " << room_data.bg_color << "\n";
    out << "  border: " << room_data.border_color << "\n";
    out << "  tileSetFile: " << room_data.tile_set_file << "\n";

    // Conexiones
    out << "\n";
    out << "  # Conexiones de la habitación (null = sin conexión)\n";
    out << "  connections:\n";
    out << "    up: " << roomConnectionToYAML(room_data.upper_room) << "\n";
    out << "    down: " << roomConnectionToYAML(room_data.lower_room) << "\n";
    out << "    left: " << roomConnectionToYAML(room_data.left_room) << "\n";
    out << "    right: " << roomConnectionToYAML(room_data.right_room) << "\n";

    // Colores de items
    out << "\n";
    out << "  # Colores de los objetos\n";
    out << "  itemColor1: " << (room_data.item_color1.empty() ? "yellow" : room_data.item_color1) << "\n";
    out << "  itemColor2: " << (room_data.item_color2.empty() ? "magenta" : room_data.item_color2) << "\n";

    // Conveyor belt
    out << "\n";
    out << "  # Dirección de la cinta transportadora: left, none, right\n";
    out << "  conveyorBelt: " << conveyorBeltToString(room_data.conveyor_belt_direction) << "\n";

    // --- Tilemap (16 filas × 32 columnas, formato flow) ---
    out << "\n";
    out << "# Tilemap: 16 filas × 32 columnas (256×192 píxeles @ 8px/tile)\n";
    out << "# Índices de tiles (-1 = vacío)\n";
    out << "tilemap:\n";
    constexpr int MAP_WIDTH = 32;
    constexpr int MAP_HEIGHT = 16;
    for (int row = 0; row < MAP_HEIGHT; ++row) {
        out << "  - [";
        for (int col = 0; col < MAP_WIDTH; ++col) {
            int index = (row * MAP_WIDTH) + col;
            if (index < static_cast<int>(room_data.tile_map.size())) {
                out << room_data.tile_map[index];
            } else {
                out << -1;
            }
            if (col < MAP_WIDTH - 1) { out << ", "; }
        }
        out << "]\n";
    }

    // --- Enemigos ---
    if (!room_data.enemies.empty()) {
        out << "\n";
        out << "# Enemigos en esta habitación\n";
        out << "enemies:\n";
        for (const auto& enemy : room_data.enemies) {
            out << "  - animation: " << enemy.animation_path << "\n";

            int pos_x = static_cast<int>(std::round(enemy.x / Tile::SIZE));
            int pos_y = static_cast<int>(std::round(enemy.y / Tile::SIZE));
            out << "    position: {x: " << pos_x << ", y: " << pos_y << "}\n";

            out << "    velocity: {x: " << enemy.vx << ", y: " << enemy.vy << "}\n";

            int b1_x = enemy.x1 / Tile::SIZE;
            int b1_y = enemy.y1 / Tile::SIZE;
            int b2_x = enemy.x2 / Tile::SIZE;
            int b2_y = enemy.y2 / Tile::SIZE;
            out << "    boundaries:\n";
            out << "      position1: {x: " << b1_x << ", y: " << b1_y << "}\n";
            out << "      position2: {x: " << b2_x << ", y: " << b2_y << "}\n";

            if (!enemy.color.empty() && enemy.color != "white") {
                out << "    color: " << enemy.color << "\n";
            }
            if (enemy.flip) { out << "    flip: true\n"; }
            if (enemy.mirror) { out << "    mirror: true\n"; }
            if (enemy.frame != -1) { out << "    frame: " << enemy.frame << "\n"; }

            out << "\n";
        }
    }

    // --- Items ---
    if (!room_data.items.empty()) {
        out << "# Objetos en esta habitación\n";
        out << "items:\n";
        for (const auto& item : room_data.items) {
            out << "  - tileSetFile: " << item.tile_set_file << "\n";
            out << "    tile: " << item.tile << "\n";

            int item_x = static_cast<int>(std::round(item.x / Tile::SIZE));
            int item_y = static_cast<int>(std::round(item.y / Tile::SIZE));
            out << "    position: {x: " << item_x << ", y: " << item_y << "}\n";

            if (item.counter != 0) {
                out << "    counter: " << item.counter << "\n";
            }

            out << "\n";
        }
    }

    return out.str();
}

// Guarda el YAML a disco
auto RoomSaver::saveYAML(const std::string& file_path, const fkyaml::node& original_yaml, const Room::Data& room_data) -> std::string {
    std::string content = buildYAML(original_yaml, room_data);

    std::ofstream file(file_path);
    if (!file.is_open()) {
        std::cerr << "RoomSaver: Cannot write to " << file_path << "\n";
        return "Error: Cannot write to " + file_path;
    }

    file << content;
    file.close();

    const std::string FILE_NAME = file_path.substr(file_path.find_last_of("\\/") + 1);
    std::cout << "RoomSaver: Saved " << FILE_NAME << "\n";
    return "Saved " + FILE_NAME;
}

#endif  // _DEBUG
