/*
 *
 *  * Copyright (C) 2023, KylinSoft Co., Ltd.
 *  *
 *  * This program is free software: you can redistribute it and/or modify
 *  * it under the terms of the GNU General Public License as published by
 *  * the Free Software Foundation, either version 3 of the License, or
 *  * (at your option) any later version.
 *  *
 *  * This program is distributed in the hope that it will be useful,
 *  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  * GNU General Public License for more details.
 *  *
 *  * You should have received a copy of the GNU General Public License
 *  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *  *
 *  * Authors: Nicole <buxiaoqing@kylinos.cn>
 *  *          zyy <zhangyuanyuan1@kylinos.cn>
 *
 */

#include <KWindowSystem>
#include <QVector>
#include <QDebug>

#include "windowThumbnailModel.h"


//=================== Item ===================
ThumbnailModelItem::ThumbnailModelItem(const ThumbnailItem &thumbnail)
{
    setData(thumbnail);
}

QVariant ThumbnailModelItem::winId() const
{
    return m_data.m_winId;
}

QString ThumbnailModelItem::groupName() const
{
    return m_data.m_groupName;
}

void ThumbnailModelItem::setData(const ThumbnailItem &thumbnail)
{
    m_data = thumbnail;
}


//=================== Model ===================
class ThumbnailModelPrivate
{
public:
    QString m_currentGroupName;
    QList<QVariant> m_currentWinIDList;
    QVector<ThumbnailModelItem> m_thumbnails;
};

ThumbnailModel *ThumbnailModel::instance()
{
    static ThumbnailModel instance;
    return &instance;
}

ThumbnailModel::ThumbnailModel(QObject *parent)
    : QAbstractListModel(parent), d(new ThumbnailModelPrivate)
{
}

ThumbnailModel::~ThumbnailModel()
{
    if(d) {
        delete d;
        d = nullptr;
    }
}

QVariant ThumbnailModel::data(const QModelIndex &index, int role) const
{
    if (index.row() < 0 || index.row() > d->m_thumbnails.count()) {
        return {};
    }

    const ThumbnailModelItem &item = d->m_thumbnails[index.row()];

    switch (role) {
    default:
        case Qt::UserRole:
        return item.winId();
        break;
    }
    return {};
}

int ThumbnailModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return d->m_thumbnails.count();
}

void ThumbnailModel::setModelData(const QList<QVariant> &data, const QString &groupName)
{
    if (!d->m_thumbnails.isEmpty()) {
        d->m_thumbnails.clear();
    }

    d->m_currentGroupName = groupName;

    ThumbnailItem win;
    win.m_groupName = groupName;
    for (QVariant id : data) {
        win.m_winId = id;
        ThumbnailModelItem item(win);
        d->m_thumbnails.append(std::move(item));
    }
}

void ThumbnailModel::clear()
{
    beginRemoveRows(QModelIndex(), 0, d->m_thumbnails.count());
    d->m_thumbnails.clear();
    endRemoveRows();
}

QList<QVariant> ThumbnailModel::getGroupWIndowList(QString groupName)
{
    d->m_currentWinIDList.clear();
    if (groupName == d->m_currentGroupName) {
        for (const ThumbnailModelItem var : d->m_thumbnails) {
            d->m_currentWinIDList.append(var.winId());
        }
        return d->m_currentWinIDList;
    } else {
        return {};
    }
}

void ThumbnailModel::closeWindow(const QVariant &winId)
{
    kdk::WindowManager::closeWindow(winId);
    onWindowRemoved(winId);
}

void ThumbnailModel::activateWindow(const QVariant &winId)
{
    kdk::WindowManager::activateWindow(winId);
}

QString ThumbnailModel::getWindowTitle(const QVariant &winId)
{
    return kdk::WindowManager::getWindowTitle(winId);
}

QIcon ThumbnailModel::getWindowIcon(const QVariant &winId)
{
    return kdk::WindowManager::getWindowIcon(winId);
}

QString ThumbnailModel::getWindowUuid(const QVariant &winId)
{
    //to do 需要等底层实现
    return QString("WindowUuid");
}

void ThumbnailModel::onWIndowAdded(const QVariant &winId, const QString &groupName)
{
    if (d->m_currentGroupName != groupName) {
        //非当前预览窗口
        return;
    }

    int index = findThumbnailIndex(winId);
    if (index >= 0) {
        // 已经存在预览图窗口，更新
        updateWindow(index, winId, groupName);
        return;
    }

    ThumbnailItem win;
    win.m_winId = winId;
    win.m_groupName = groupName;

    ThumbnailModelItem item(win);

    // 插入数据
    beginInsertRows(QModelIndex(), d->m_thumbnails.count(), d->m_thumbnails.count());
    d->m_thumbnails.append(std::move(item));
    endInsertRows();

    Q_EMIT updateWinIdList(getGroupWIndowList(d->m_currentGroupName));
}

void ThumbnailModel::onWindowRemoved(const QVariant &winId)
{
    int index = findThumbnailIndex(winId);
    if (index < 0) {
        return;
    }
    //删除数据
    beginRemoveRows(QModelIndex(), index, index);
    d->m_thumbnails.removeAt(index);
    endRemoveRows();

    Q_EMIT updateWinIdList(getGroupWIndowList(d->m_currentGroupName));
}

void ThumbnailModel::updateWindow(int row, const QVariant &winId, const QString &groupName)
{
    Q_UNUSED(winId);
    Q_UNUSED(groupName);
//    ThumbnailModelItem &item = d->m_thumbnails[row];
//    item.setData(winId, groupName);

    Q_EMIT dataChanged(index(row), index(row));
}

void ThumbnailModel::updateModeData()
{

}

int ThumbnailModel::findThumbnailIndex(const QVariant winId) const
{
    auto it = std::find_if(d->m_thumbnails.constBegin(), d->m_thumbnails.constEnd(), [&winId] (const ThumbnailModelItem &item) {
        return item.winId() == winId;
    });

    if (it == d->m_thumbnails.constEnd()) {
        return -1;
    }

    return std::distance(d->m_thumbnails.constBegin(), it);
}
