#pragma once
#include <vector>
#include <string>
#include <cstdint>

#include <godot_cpp/classes/ref_counted.hpp>
#include <godot_cpp/variant/dictionary.hpp>
#include <godot_cpp/variant/array.hpp>
#include <godot_cpp/variant/string.hpp>
#include <godot_cpp/variant/packed_float32_array.hpp>
#include <godot_cpp/variant/packed_vector3_array.hpp>
#include <godot_cpp/variant/packed_byte_array.hpp>
#include <godot_cpp/variant/packed_string_array.hpp>

#include "wow_chunk_reader.h"

namespace godot {

// ADTLoader
//
// Loads WoW 3.3.5a ADT terrain tiles.
//
// Usage (GDScript):
//   var adt = ADTLoader.new()
//   var data = adt.load_adt("C:/wow/Data/World/Maps/Azeroth/Azeroth_32_48.adt")
//
// Return Dictionary:
//   {
//     "textures":  PackedStringArray,   # all texture filenames in MTEX
//     "m2_names":  PackedStringArray,   # M2 model filenames
//     "wmo_names": PackedStringArray,   # WMO filenames
//     "m2_placements":  Array[Dictionary],
//     "wmo_placements": Array[Dictionary],
//     "chunks": Array[Dictionary],      # 16x16 = 256 entries, row-major
//   }
//
// Placement Dictionary (both M2 and WMO):
//   {
//     "name_id":     int,      # index into m2_names / wmo_names
//     "unique_id":   int,      # MDDF/MODF uniqueId (dedupe key across tiles)
//     "pos":         Vector3,  # Godot world coords
//     "rot":         Vector3,  # Euler angles (radians)
//     "scale":       float,    # M2 only (WMO always 1.0)
//     "flags":       int,      # WMO only
//     "doodad_set":  int,      # WMO only
//     "name_set":    int,      # WMO only
//   }
//
// Chunk Dictionary:
//   {
//     "index_x":  int,           # 0-15
//     "index_y":  int,           # 0-15
//     "origin":   Vector3,       # Godot world position of chunk origin
//     "heights":  PackedFloat32Array,  # 145 values (9x9 outer + 8x8 inner grid)
//     "normals":  PackedVector3Array,  # 145 normals
//     "holes":    int,           # hole bit mask (low 16 bits)
//     "layers":   Array[Dictionary],   # texture layer definitions
//     "alpha_maps": Array[PackedByteArray], # one per layer (layer 0 has none)
//   }
//
// Layer Dictionary:
//   {
//     "texture_id":   int,
//     "flags":        int,
//     "effect_id":    int,
//     "alpha_offset": int,
//   }
class ADTLoader : public RefCounted {
    GDCLASS(ADTLoader, RefCounted)

public:
    Dictionary load_adt(const String &path);
    Dictionary load_adt_from_bytes(const PackedByteArray &bytes);

protected:
    static void _bind_methods();

private:
    static std::vector<uint8_t> read_file(const std::string &path);
    static std::string          to_std(const String &s);
    static String               to_godot(const std::string &s);

    // Shared parse implementation
    static void _parse_adt(const uint8_t *raw, size_t len, Dictionary &result);

    // Parse names from MMDX/MWMO (null-separated) using MMID/MWID offset tables
    static PackedStringArray parse_names_with_offsets(
        const WoWChunk &names_chunk, const WoWChunk &ids_chunk);
};

} // namespace godot
