#pragma once

#include "dialogue/DialogueRuntime.h"
#include "render/Renderer.h"
#include "render/TextRenderer.h"
#include "render/TextureManager.h"
#include "UiManager.h"
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

namespace ZL::Dialogue {

class DialogueOverlay {
public:
    bool init(Renderer& renderer, const std::string& zipFile = "");
    void draw(Renderer& renderer, const PresentationModel& model);

    // Coordinates are expected in the game's UI projection space
    bool handlePointerReleased(float x, float y, const PresentationModel& model, int& outChoiceIndex) const;

private:
    struct TexturedQuad {
        UiRect rect;
        VertexRenderStruct mesh;
        bool initialized = false;

        void rebuild(const UiRect& newRect);
    };

    Renderer* rendererRef = nullptr;
    std::string zipFilename;

    std::shared_ptr<Texture> textboxTexture;
    std::shared_ptr<Texture> portraitFrameTexture;
    std::shared_ptr<Texture> choiceMainTexture;
    std::shared_ptr<Texture> choiceOptionalTexture;
    std::shared_ptr<Texture> choiceSelectedTexture;
    std::shared_ptr<Texture> cutsceneSubtitleTexture;

    mutable std::vector<UiRect> lastChoiceRects;

    std::unique_ptr<TextRenderer> nameRenderer;
    std::unique_ptr<TextRenderer> bodyRenderer;
    std::unique_ptr<TextRenderer> choiceRenderer;
    std::unique_ptr<TextRenderer> cutsceneRenderer;

    TexturedQuad portraitQuad;
    TexturedQuad textboxQuad;
    TexturedQuad subtitleQuad;
    TexturedQuad backgroundQuad;
    mutable std::vector<TexturedQuad> choiceQuads;

    std::unordered_map<std::string, std::shared_ptr<Texture>> textureCache;

    void drawDialogue(Renderer& renderer, const PresentationModel& model);
    void drawCutscene(Renderer& renderer, const PresentationModel& model);

    std::shared_ptr<Texture> loadTextureCached(const std::string& path);
    void drawQuad(Renderer& renderer, const TexturedQuad& quad, const std::shared_ptr<Texture>& texture) const;

    static std::string wrapText(const std::string& input, size_t maxLineLength);
};

} // namespace ZL::Dialogue
