#ifndef _RIVE_TEXT_INPUT_HPP_
#define _RIVE_TEXT_INPUT_HPP_

#include "rive/generated/text/text_input_base.hpp"
#include "rive/advancing_component.hpp"
#include "rive/text/raw_text_input.hpp"
#include "rive/text/text_interface.hpp"
#include "rive/animation/listener_invocation.hpp"
#include "rive/input/focusable.hpp"
#include <cmath>

namespace rive
{
class TextStyle;
class ScrollConstraint;
class TextInput : public TextInputBase,
                  public TextInterface,
                  public Focusable,
                  public AdvancingComponent
{
public:
    void draw(Renderer* renderer) override;
    Core* hitTest(HitInfo*, const Mat2D&) override;
    bool hitTestPoint(const Vec2D& position,
                      bool skipOnUnclipped,
                      bool isPrimaryHit) override;

#ifdef WITH_RIVE_TEXT
    RawTextInput* rawTextInput() { return &m_rawTextInput; }
#endif

    void markPaintDirty() override;
    void markShapeDirty() override;
    StatusCode onAddedClean(CoreContext* context) override;

    AABB localBounds() const override;
    void update(ComponentDirt value) override;

    Vec2D measureLayout(float width,
                        LayoutMeasureMode widthMode,
                        float height,
                        LayoutMeasureMode heightMode) override;
    void controlSize(Vec2D size,
                     LayoutScaleType widthScaleType,
                     LayoutScaleType heightScaleType,
                     LayoutDirection direction) override;

    bool keyInput(Key value,
                  KeyModifiers modifiers,
                  bool isPressed,
                  bool isRepeat) override;
    bool textInput(const std::string& text) override;
    bool gamepadDispatch(
        const ListenerInvocation& invocation,
        ScriptedDrawable** outDispatchedScriptedDrawable = nullptr) override;
    void focused() override;
    void blurred() override;
    bool worldPosition(Vec2D& outPosition) override;
    bool worldBounds(AABB& outBounds) override;
    Artboard* focusableArtboard() const override { return artboard(); }
    bool acceptsKeyboardInput() const override { return true; }

    /// Called when the user starts dragging on the text input.
    /// Places the cursor at the given world position.
    void startDrag(Vec2D worldPosition);

    /// Called when the user continues dragging on the text input.
    /// Extends the selection to the given world position.
    void drag(Vec2D worldPosition);

    /// Called when the user ends dragging on the text input.
    void endDrag(Vec2D worldPosition);

    /// Selects the word at the current cursor (e.g. on double-click).
    void selectWord();

    /// Selects the visual line at the current cursor (e.g. on triple-click).
    void selectLine();

    /// Advance edge scrolling during drag. Returns true if still scrolling.
    bool advanceDrag(float elapsedSeconds);
    bool advanceComponent(float elapsedSeconds,
                          AdvanceFlags flags = AdvanceFlags::Animate |
                                               AdvanceFlags::NewFrame) override;

    /// Whether currently dragging (for hit test to avoid interference).
    bool isDragging() const { return m_isDragging; }

protected:
    void textChanged() override;
    void selectionRadiusChanged() override;
    void multilineChanged() override;

private:
    /// Convert a world position to local text input coordinates.
    /// Handles viewport clamping and auto-scroll for scroll constraints.
    bool worldToLocalWithViewport(Vec2D worldPosition,
                                  Vec2D& outLocal,
                                  bool enableAutoScroll);

    float edgeScrollSpeedForDistance(float distanceFromEdge) const;
    float edgeActivationDistance(float position, float edgeStart) const;

    void updateMultiline(bool syncDisplayedText = false);
    static std::string strippedLineBreaks(const std::string& text);
    std::string displayedText() const;
    void syncDisplayedTextFromSource(bool preserveCursor);
    void syncSourceTextFromRaw();

    AABB m_worldBounds;
    std::string m_sourceText;
    TextStyle* m_textStyle = nullptr;
    ScrollConstraint* m_scrollConstraint = nullptr;

    /// Whether the user is currently dragging to select text.
    bool m_isDragging = false;
    Vec2D m_lastDragWorldPosition = Vec2D(NAN, NAN);

    /// Scroll velocity for edge scrolling during drag in X.
    float m_scrollX = 0.0f;

    /// Scroll velocity for edge scrolling during drag.
    float m_scrollY = 0.0f;
    float m_layoutWidth = NAN;

#ifdef WITH_RIVE_TEXT
    RawTextInput m_rawTextInput;
#endif
};
} // namespace rive

#endif