#pragma once
#include "Component.h"
#include "../core/utils/TextureAtlas.h"
#include "../core/types/Vec2.h"
#include <unordered_map>
#include <memory>

class TilemapComponent : public Component
{
public:
    TilemapComponent(Object *owner);

    void SetTextureAtlas(uint64_t uaid, int texelWidth, int texelHeight);
    void SetTile(int x, int y, int index);
    int GetTile(int x, int y) const;

    // Overrides
    std::string GetName() const override { return "TilemapComponent"; }
    void Save(YAML::Emitter &out) const override;
    void Load(const YAML::Node &node) override;

    // Accessors
    uint64_t GetTextureUAID() const;
    std::shared_ptr<Texture> GetTexture() const;
    TextureAtlas *GetAtlas();
    const TextureAtlas *GetAtlas() const;
    const core::types::Vec2 &GetTileSize() const;
    void SetTileSize(const core::types::Vec2 &size);
    int GetAtlasColumns() const;
    int GetAtlasRows() const;
    const std::unordered_map<uint64_t, int> &GetTileData() const;

    void PlaceSelection(int gx, int gy);

    bool HasSelection();

    static uint64_t PackCoord(int x, int y);
    static void UnpackCoord(uint64_t key, int &x, int &y);

    bool hasSelection;

    int selStartX = 0, selStartY = 0;
    int selEndX = 0, selEndY = 0;

    void SetSelection(int startX, int startY, int endX, int endY)
    {
        hasSelection = true;
        selStartX = startX;
        selStartY = startY;
        selEndX = endX;
        selEndY = endY;
    }

    void ClearSelection() { hasSelection = false; }
    bool HasSelection() const { return hasSelection; }

    void GetSelectionBounds(int &outX0, int &outY0, int &outX1, int &outY1) const
    {
        if (!hasSelection)
        {
            outX0 = outY0 = outX1 = outY1 = 0;
            return;
        }

        outX0 = std::min(selStartX, selEndX);
        outY0 = std::min(selStartY, selEndY);
        outX1 = std::max(selStartX, selEndX);
        outY1 = std::max(selStartY, selEndY);
    }

private:
    uint64_t textureUAID = 0;
    std::shared_ptr<Texture> texture;
    TextureAtlas atlas;
    RenderType renderType;

    core::types::Vec2 tileSize = {32, 32};
    int atlasColumns = 0;
    int atlasRows = 0;

    std::unordered_map<uint64_t, int> tiles;
};
