/*
 * Copyright (C) 2025, 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: youdiansaodongxi <guojiaqi@kylinos.cn>
 *
 */

#include "shortcut-filter-model.h"
#include "edit-shortcut-model.h"
#include "shortcut-config.h"

#include <QModelIndex>
#include <QtDebug>

using namespace UkuiShortcut;

ShortcutFilterModel::ShortcutFilterModel(
        EditShortcutModel *sourceModel, PluginMetaType::AddState addState, QObject *parent) : QSortFilterProxyModel(parent)
{
    QSortFilterProxyModel::setSourceModel(sourceModel);

    m_sourceModel = sourceModel;
    m_addState = addState;

    connect(m_sourceModel, &EditShortcutModel::dataChanged, this, &ShortcutFilterModel::onSourceModelDataChanged);
    sort(0);
}

QVariant ShortcutFilterModel::data(const QModelIndex &index, int role) const
{
    return sourceModel()->data(mapToSource(index), role);
}

void ShortcutFilterModel::active(int i, PluginMetaType::Action action)
{
    m_sourceModel->active(mapToSource(index(i, 0)).row(), action);
}

void ShortcutFilterModel::setValue(int i, int value)
{
    m_sourceModel->setValue(mapToSource(index(i, 0)).row(), value);
}

void ShortcutFilterModel::disableValueUpdate(bool disable)
{
    m_sourceModel->disableValueUpdate(disable);
}

void ShortcutFilterModel::moveItem(int sourceIndex, int targetIndex)
{
    int srcRow = data(index(sourceIndex, 0), EditShortcutModel::PluginIndex).toInt();
    int targetRow = data(index(targetIndex, 0), EditShortcutModel::PluginIndex).toInt();
    ShortcutConfig::instance().setShortcutOrder(srcRow, targetRow, m_addState);
}

void ShortcutFilterModel::setOrder(QString fromId, int toIndex)
{
    int targetRow = data(index(toIndex, 0), EditShortcutModel::PluginIndex).toInt();
    ShortcutConfig::instance().setShortcutOrder(fromId, targetRow, m_addState);
}

void ShortcutFilterModel::changeState(QString idFrom, PluginMetaType::AddState stateFrom, bool atEnd)
{
    ShortcutConfig::instance().changeShortcutState(idFrom, stateFrom, atEnd);
}

void ShortcutFilterModel::updateItemRect(QQuickItem *flowItem)
{
    QList<QQuickItem *> items = flowItem->childItems();

    int currentRow = 0;
    int currentColumn = 0;

    for (int i = 0; i < items.count(); ++i) {
        QQuickItem* item = items.at(i);
        const int columnSpan = item->property("columnSpan").toInt();

        if (columnSpan == 0) break;

        if (currentColumn + columnSpan > m_columns) {
            currentRow++;
            currentColumn = 0;
        }

        const qreal x = currentColumn * (m_itemWidth + m_columnSpacing);
        const qreal y = currentRow * (m_itemHeight + m_rowSpacing);

        const QRect rect = QRect(x, y, m_itemWidth * columnSpan + m_columnSpacing * (columnSpan - 1), m_itemHeight);

        item->setProperty("targetRect", rect);

        currentColumn += columnSpan;
    }
    flowItem->setProperty("rows", currentRow + 1);

    m_items = items;
}

void ShortcutFilterModel::findTargetItem(qreal x, qreal y, QObject *resultObj)
{
    QList<QQuickItem *> items = m_items;
    for (int i = 0; i < items.count(); ++i) {
        QQuickItem* item = items.at(i);
        const QRect rect = item->property("targetRect").toRect();
        if (rect.contains(x, y)) {
            resultObj->setProperty("index", i);
            resultObj->setProperty("offset", rect.width() > 80 ? (rect.x() + rect.width()/2 > x) ? 0 : 1 : -1);
            return;
        }
    }
    resultObj->setProperty("index", -1);
    resultObj->setProperty("offset", 0);
}

bool ShortcutFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
    const QModelIndex modelIndex = sourceModel()->index(source_row, 0, source_parent);
    return (modelIndex.data(EditShortcutModel::AddState) == m_addState)
            && modelIndex.data(EditShortcutModel::IsEnable).toBool()
            && modelIndex.data(EditShortcutModel::IsVisible).toBool();
}

bool ShortcutFilterModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
    return source_left.data(EditShortcutModel::PluginIndex).toInt() < source_right.data(EditShortcutModel::PluginIndex).toInt();
}

void ShortcutFilterModel::onSourceModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
    if (roles.contains(EditShortcutModel::PluginIndex)) {
        invalidate();
    }
}
