// wireframe3d.hpp - Meshos 3D wireframe i utilitats per dibuixar-los
// © 2026 JailDesigner
//
// Mesh3D = llista de vèrtexs Vec3 + llista d'arestes (parells d'índexs).
// drawWireframe() aplica una Transform3D al mesh, projecta amb Camera3D i
// emet cada aresta com una línia 2D pel pipeline `Rendering::linea` (mateix
// pipeline que la resta del joc: verd fòsfor via Rendering::DEFAULT_LINE_COLOR si color.a==0).
//
// Sense depth buffer: el caller és responsable d'ordenar els meshos per
// profunditat decreixent si vol oclusió coherent (la pipeline és LINE_LIST
// amb alpha blend additiu).

#pragma once

#include <SDL3/SDL.h>

#include <cstdint>
#include <utility>
#include <vector>

#include "core/graphics/camera3d.hpp"
#include "core/graphics/shape.hpp"
#include "core/rendering/render_context.hpp"
#include "core/types.hpp"

namespace Graphics {

    struct Mesh3D {
        std::vector<Vec3> vertices;
        std::vector<std::pair<std::uint16_t, std::uint16_t>> edges;
    };

    struct Transform3D {
        Vec3 position{};
        // Euler en radians, aplicat en ordre Y (yaw) → X (pitch) → Z (roll).
        Vec3 rotation_euler{};
        float scale{1.0F};
    };

    // Aplica la Transform3D a un vèrtex local del mesh per obtenir-ne la posició
    // mundial. Ordre: scale → rotate (Y,X,Z) → translate.
    [[nodiscard]] auto applyTransform(const Transform3D& transform, const Vec3& local) -> Vec3;

    // Dibuixa el mesh en wireframe a través de la càmera donada. Cada aresta es
    // projecta en CPU i s'emet via `Rendering::linea`. Les arestes amb algun extrem
    // darrere del near plane es descarten per complet (clipping primitiu).
    //   - brightness: multiplicador aplicat al color de línia.
    //   - color: si alpha == 0, usa el color global del oscil·lador (glow verd).
    void drawWireframe(Rendering::Renderer* renderer, const Camera3D& camera, const Mesh3D& mesh, const Transform3D& transform, float brightness = 1.0F, SDL_Color color = {.r = 0, .g = 0, .b = 0, .a = 0});

    // Factory: octaedre regular amb 6 vèrtexs als eixos a distància 1 i 12 arestes.
    // Pensat com a estrella 3D al starfield (escalable amb Transform3D::scale).
    [[nodiscard]] auto makeOctahedron() -> Mesh3D;

    // Factory: extrusió en Z d'un shape 2D. Cada polyline genera dues còpies
    // (z = +depth/2 i z = -depth/2) més arestes de connexió frontal↔posterior
    // per cada vèrtex de la polyline.
    [[nodiscard]] auto extrudeShape2D(const Shape& shape, float depth) -> Mesh3D;

}  // namespace Graphics
