#ifndef MULTITASKVIEWMODEL_H
#define MULTITASKVIEWMODEL_H

#include <QObject>
#include <QIcon>
#include <QList>
#include <QMap>
#include <QRect>
#include <QVariantList>
#include <QUuid>

#include <kwineffects.h>

class QGSettings;

namespace MultitaskView {

class Window
{
    Q_GADGET

    Q_PROPERTY(int id READ id)

    Q_PROPERTY(QString caption READ caption)

    Q_PROPERTY(int x READ x)

    Q_PROPERTY(int y READ y)

    Q_PROPERTY(int width READ width)

    Q_PROPERTY(int height READ height)

    Q_PROPERTY(bool minimized READ minimized)

    Q_PROPERTY(QUuid uuid READ uuid)

public:

    Window() = default;

    Window(int id, const QString& caption, int x, int y, int width, int height, bool minimized, QUuid uuid)
        : id_(id),
          caption_(caption),
          x_(x),
          y_(y),
          width_(width),
          height_(height),
          minimized_(minimized),
          uuid_(uuid)
    {
    }

    int id() const
    {
        return id_;
    }

    QUuid uuid() const
    {
        return uuid_;
    }

    const QString& caption() const
    {
        return caption_;
    }

    int x() const
    {
        return x_;
    }

    int y() const
    {
        return y_;
    }

    int width() const
    {
        return width_;
    }

    int height() const
    {
        return height_;
    }

    bool minimized() const
    {
        return minimized_;
    }

private:

    int id_ = 0;

    QUuid uuid_;

    QString caption_;

    int x_ = 0;

    int y_ = 0;

    int width_ = 0;

    int height_ = 0;

    bool minimized_ = false;
};


class Screen
{
    Q_GADGET

    Q_PROPERTY(int index READ index)

    Q_PROPERTY(QList<QVariant> windowList READ windowList)

public:

    Screen() = default;

    Screen(int index, const QList<QVariant>& windowList)
        : index_(index),
          windowList_(windowList)
    {}

    int index() const
    {
        return index_;
    }

    const QList<QVariant>& windowList() const
    {
        return windowList_;
    }

private:

    int index_ = 0;

    QList<QVariant> windowList_;
};

class Desktop
{
    Q_GADGET

    Q_PROPERTY(int index READ index)

    Q_PROPERTY(QList<QVariant> screenList READ screenList)

public:

    Desktop() = default;

    Desktop(int index, const QList<QVariant>& screenList)
        : index_(index),
          screenList_(screenList)
    {}

    int index() const
    {
        return index_;
    }

    const QList<QVariant>& screenList() const
    {
        return screenList_;
    }

private:

    int index_ = 1;

    QList<QVariant> screenList_;
};

class MultitaskViewModel : public QObject
{
    Q_OBJECT

    Q_PROPERTY(int logicalScreenCount READ logicalScreenCount NOTIFY screenCountChanged)

    Q_PROPERTY(bool isTabletMode READ isTabletMode)

    Q_PROPERTY(QString rotationMode READ rotationMode NOTIFY rotationModeChanged)

public:

    explicit MultitaskViewModel(QObject *parent = nullptr);

    ~MultitaskViewModel();

    Q_INVOKABLE QList<QVariant> getAppWindowList(int desktopIndex, int screenIndex) const;

    Q_INVOKABLE void removeAppWindow(QUuid windowId);

    Q_INVOKABLE void removeAllAppWindowOnDesktop(int desktopIndex);

    Q_INVOKABLE void moveAppWindowToDesktop(QUuid windowId, int srcDesktopInex, int destDesktopInex) const;

    Q_INVOKABLE void activateAppWindow(QUuid windowId);

    Q_INVOKABLE QIcon getWindowIcon(QUuid windowId);

    Q_INVOKABLE QList<QVariant> getDesktopList() const;

    Q_INVOKABLE void removeDesktop(int desktopIndex);

    Q_INVOKABLE void appendDesktop();

    Q_INVOKABLE void moveDesktop(int srcDesktopIndex, int destDesktopIndex);

    Q_INVOKABLE int getCurrentDesktop();

    Q_INVOKABLE void setCurrentDesktop(int desktopIndex);

    Q_INVOKABLE QRect getFullScreenGeometry(int desktopIndex, int screenIndex) const;

    Q_INVOKABLE bool hasModalChildWindow(QUuid windowId);

    bool isTabletMode() const;

    Q_INVOKABLE QString getUKUIStyleName() const;

    Q_INVOKABLE int getUKUIFontSize() const;

signals:

    void appWindowCreated(int windowId);

    void appWindowRemoved(int windowId);

    void appWindowActivated();

    void appWindowDesktopChanged(int windowId, int oldDesktopIndex, int newDesktopIndex);

    void desktopRemoved(int desktopIndex);

    void desktopAppended(int desktopIndex);

    void desktopMoved(int oldDesktopIndex, int newDesktopIndex);

    void currentDesktopChanged(int oldCurrentDesktopIndex, int newCurrentDesktopIndex);

    void screenCountChanged(int oldScreentCount, int newScreenCount);

    void screenSizeChanged();

    void tabletModeChanged(bool);

    void rotationModeChanged(QString);

private slots:

    void onWindowAdded(KWin::EffectWindow* window);

    void onWindowDeleted(KWin::EffectWindow* window);

    void onWindowActivated(KWin::EffectWindow* window);

    void onDesktopPresenceChanged(KWin::EffectWindow* window, int oldDesktopIndex, int newDesktopIndex);

    void onNumberScreensChanged();

private:

    void updateScreenCount();

    static bool isExtensionMode();

    int logicalScreenCount() const;

    QString rotationMode() const;

    QList<QVariant> createWindowList(int desktopIndex, int screenIndex);

    void updateModelData();

    void moveDesktopWindows(int srcDesktopIndex, int destDesktopIndex);

    void moveDesktopsOneStep(const QVector<int>& desktopIndexList);

    static QVector<int> createDesktopIndexList(int srcDesktopIndex, int destDesktopIndex);

    static bool validateDesktopIndex(int desktopIndex);

    bool validateScreenIndex(int screenIndex) const;

    static WId getWindowId(KWin::EffectWindow* window);

    static QUuid getUuid(KWin::EffectWindow *window);

    static bool shouldAcceptWindow(KWin::EffectWindow* window);

    void connectSignals();

private:

    // 虚拟桌面列表
    QList<QVariant> desktopList_;

    // 屏幕数量
    int screenCount_ = 0;

    // 最大虚拟桌面数量为16
    static constexpr int MAX_DESKTOP_COUNT = 16;

    // 初始化为0，这样首次打开时就没有桌面index与lastDesktopIndex相同
    int lastDesktopIndex = 0;

    QGSettings* settings_ = nullptr;
};

} // namespace MultiTaskView

#endif // MULTITASKVIEWMODEL_H
