#include <object/ui/uitextbox.hpp>

namespace Game::Object {
    UITextBox::UITextBox(const std::string& name, std::shared_ptr<Renderer::Font> font, const Transform& transform, float x, float y)
        : Entity(name, font, transform), mX(x), mY(y) { }

    void UITextBox::start() {
        // Center the text box on the position
        mTransform.x -= mTex->getWidth() * mTransform.adjustedScaleX() / 2.f;
        mTransform.y -= mTex->getHeight() * mTransform.adjustedScaleY() / 2.f;

        // Keep a stable interaction area even when current text is empty.
        mBoxWidth = static_cast<float>(mTex->getWidth()) * mTransform.adjustedScaleX();
        mBoxHeight = static_cast<float>(mTex->getHeight()) * mTransform.adjustedScaleY();
        if (mBoxWidth <= 0.f) mBoxWidth = 180.f;
        if (mBoxHeight <= 0.f) mBoxHeight = 36.f;

        refreshVisualText();
    }

    void UITextBox::update(float deltaTime) {
        if (!mIsActive) return;

        if (Input::isMouseButtonJustPressed(SDL_BUTTON_LEFT)) {
            mIsFocused = isMouseInsideBox();
            mNeedsTextRefresh = true;
        }

        if (!mIsFocused) {
            if (mNeedsTextRefresh) {
                refreshVisualText();
            }
            return;
        }

        if (Input::isKeyJustPressed(SDL_SCANCODE_BACKSPACE) && !mText.empty()) {
            mText.pop_back();
            mNeedsTextRefresh = true;
        }

        if (Input::isKeyJustPressed(SDL_SCANCODE_RETURN) || Input::isKeyJustPressed(SDL_SCANCODE_KP_ENTER)) {
            mIsFocused = false;
            mNeedsTextRefresh = true;
        }

        for (int key = 0; key < SDL_SCANCODE_COUNT; ++key) {
            SDL_Scancode scancode = static_cast<SDL_Scancode>(key);
            if (!Input::isKeyJustPressed(scancode)) {
                continue;
            }

            SDL_Keycode keycode = SDL_GetKeyFromScancode(scancode, SDL_GetModState(), true);
            if (keycode >= 32 && keycode <= 126) {
                mText.push_back(static_cast<char>(keycode));
                mNeedsTextRefresh = true;
            }
        }

        if (mNeedsTextRefresh) {
            refreshVisualText();
        }
    }

    void UITextBox::setText(const std::string& text) {
        mText = text;
        mNeedsTextRefresh = true;
        refreshVisualText();
    }

    std::string UITextBox::getText() const {
        return mText;
    }

    std::string UITextBox::getValue() const {
        return mText;
    }

    bool UITextBox::isFocused() const {
        return mIsFocused;
    }

    bool UITextBox::isMouseInsideBox() const {
        const float mouseX = Input::getMouseX();
        const float mouseY = Input::getMouseY();

        const float left = mTransform.x;
        const float right = mTransform.x + mBoxWidth;
        const float top = mTransform.y;
        const float bottom = mTransform.y + mBoxHeight;

        return mouseX >= left && mouseX <= right && mouseY >= top && mouseY <= bottom;
    }

    void UITextBox::refreshVisualText() {
        SDL_Color color = mIsFocused ? SDL_Color{255, 240, 180, 255} : SDL_Color{255, 255, 255, 255};
        std::string rendered = mText.empty() ? " " : mText;
        if (mIsFocused) {
            rendered += "_";
        }

        std::dynamic_pointer_cast<Renderer::Font>(mTex)->build(color, rendered);
        mNeedsTextRefresh = false;
    }

}
