// SPDX-FileCopyrightText: 2025 Prayag Jain <prayagjain2@gmail.com>
//
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once
#include "libdrawygui_export.h"

#include <QPainter>
#include <QRect>

#include "item.hpp"

class LIBDRAWYGUI_EXPORT TextItem : public Item
{
public:
    TextItem();
    ~TextItem() override;

    [[nodiscard]] bool intersects(const QRectF &rect) override;

    void draw(QPainter &painter, const QPointF &offset) override;

    void commitTransformation() override;
    [[nodiscard]] bool lockAspectRatioWhenResizing() const override;

    void createTextBox(const QPointF position);

    enum class Mode : int8_t {
        Edit = 0,
        Normal
    };

    [[nodiscard]] Mode mode() const;
    void setMode(Mode mode);

    [[nodiscard]] qsizetype getIndexFromCursor(QPointF cursor) const;
    [[nodiscard]] int getLineFromY(double yPos) const;
    [[nodiscard]] qsizetype getIndexFromX(double xPos, int lineNumber) const;

    [[nodiscard]] qsizetype caret() const;
    [[nodiscard]] qsizetype caretPosInLine() const;
    void setCaret(qsizetype index, bool updatePosInLine = true);
    void setCaret(QPointF cursorPos);

    [[nodiscard]] qsizetype selectionStart() const;
    [[nodiscard]] qsizetype selectionEnd() const;
    [[nodiscard]] QString selectedText() const;
    void setSelectionStart(qsizetype index);
    void setSelectionEnd(qsizetype index);

    [[nodiscard]] const QString &text() const;
    void insertText(const QString &text);
    void deleteSubStr(qsizetype start, qsizetype end);
    void deleteSelection();

    [[nodiscard]] bool hasSelection() const;

    [[nodiscard]] std::pair<qsizetype, qsizetype> getLineRangeForLine(int lineNumber) const;
    [[nodiscard]] std::pair<qsizetype, qsizetype> getLineRangeForPosition(qsizetype position) const;

    [[nodiscard]] qsizetype getPrevBreak(qsizetype pos) const;
    [[nodiscard]] qsizetype getNextBreak(qsizetype pos) const;

    [[nodiscard]] Item::FormType formType() const override;

    constexpr static int INVALID{-1};

    void updateAfterProperty() override;

    [[nodiscard]] QJsonObject serialize(int zorder) const override;
    void deserialize(const QJsonObject &obj) override;

    [[nodiscard]] bool needsCaching() const override;

protected:
    void drawItem(QPainter &painter, const QPointF &offset) const override;

private:
    [[nodiscard]] LIBDRAWYGUI_NO_EXPORT QFont getFont() const;
    [[nodiscard]] LIBDRAWYGUI_NO_EXPORT QPen getPen() const;

    [[nodiscard]] LIBDRAWYGUI_NO_EXPORT static QTextOption getTextOptions();
    constexpr LIBDRAWYGUI_NO_EXPORT static int getTextFlags();

    LIBDRAWYGUI_NO_EXPORT void updateBoundingBox();

    QString m_text;
    qsizetype m_caretIndex{};
    qsizetype m_selectionStart{};
    qsizetype m_selectionEnd{};
    qsizetype m_caretPosInLine{};
    Mode m_mode{Mode::Normal};
};
LIBDRAWYGUI_EXPORT QDebug operator<<(QDebug d, const TextItem &t);
