/*
 * Copyright (C) 2022, 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/>.
 *
 */

//
// Created by hxf on 22-7-28.
//

#include "shortcut-model.h"
#include "shortcut-item.h"
#include "global-settings.h"
#include "edit-shortcut-model.h"

#include <QDebug>

using namespace UkuiShortcut;

ShortcutModel::ShortcutModel(QObject *parent) : QAbstractListModel(parent)
{
    initShortcutModel();
    updateCurrentMode(TABLET_MODE);
}

void ShortcutModel::insertShortcut(Shortcut *shortcut)
{
    if (!shortcut) return;

    ShortcutItem* shortcutItem = new ShortcutItem(shortcut, this);
    //TODO 添加排序
    beginInsertRows(QModelIndex(), m_shortcutItems.length(), m_shortcutItems.length());
    m_shortcutItems.append(shortcutItem);
    endInsertRows();

    connect(shortcutItem, &ShortcutItem::requestExecAction, this, &ShortcutModel::requestExecAction);
    connect(shortcutItem, &ShortcutItem::itemDataChanged, this, [=] (QVector<int> &roles) {
        QModelIndex current = index(m_shortcutItems.indexOf(shortcutItem), 0);
        if (m_disableValueUpdate && roles.contains(EditShortcutModel::Value)) {
            roles.remove(roles.indexOf(EditShortcutModel::Value));
            if (roles.empty()) {
                return;
            }
        }
        Q_EMIT dataChanged(current, current, roles);
    });
}

int ShortcutModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return m_shortcutItems.length();
}

QVariant ShortcutModel::data(const QModelIndex &index, int role) const
{
    int row = index.row();
    if (row < 0 || row >= m_shortcutItems.length()) {
        return {};
    }

    ShortcutItem* shortcut = m_shortcutItems.value(row);
    switch (role) {
        case EditShortcutModel::Disabled: {
            return shortcut->disabled();
        }
        case EditShortcutModel::Name: {
            return shortcut->name();
        }
        case EditShortcutModel::StatusName: {
            return shortcut->statusName();
        }
        case EditShortcutModel::WidgetId: {
            return shortcut->widgetId();
        }
        case EditShortcutModel::Icon: {
            return shortcut->icon();
        }
        case EditShortcutModel::ToolTip: {
            return shortcut->tooltip();
        }
        case EditShortcutModel::Color: {
            return shortcut->color();
        }
        case EditShortcutModel::Value: {
            return shortcut->value();
        }
        case EditShortcutModel::Menu: {
            return shortcut->menu();
        }
        default:
            break;
    }

    return {};
}

QHash<int, QByteArray> ShortcutModel::roleNames() const
{
    QHash<int, QByteArray> names;
    names.insert(EditShortcutModel::Disabled, "disabled");
    names.insert(EditShortcutModel::Name, "name");
    names.insert(EditShortcutModel::StatusName, "statusName");
    names.insert(EditShortcutModel::WidgetId, "widgetId");
    names.insert(EditShortcutModel::Icon, "icon");
    names.insert(EditShortcutModel::ToolTip, "tooltip");
    names.insert(EditShortcutModel::Color, "color");
    names.insert(EditShortcutModel::Value, "value");
    names.insert(EditShortcutModel::Menu, "menu");
    return names;
}

void ShortcutModel::active(int index, PluginMetaType::Action action)
{
    if (index < 0 || index >= m_shortcutItems.size()) return;

    ShortcutItem *shortcutItem = m_shortcutItems.at(index);
    shortcutItem->active(action, m_currentMode);
}

void ShortcutModel::setValue(int index, const int value)
{
    if (index < 0 || index >= m_shortcutItems.size()) return;

    ShortcutItem *shortcutItem = m_shortcutItems.at(index);
    shortcutItem->setValue(value);
}

void ShortcutModel::disableValueUpdate(bool disable)
{
    m_disableValueUpdate = disable;
}

void ShortcutModel::updateValue(int idx)
{
    if (idx < 0 || idx >= m_shortcutItems.size()) return;
    QModelIndex current = index(idx, 0);
    Q_EMIT dataChanged(current, current, {EditShortcutModel::Value});
}

void ShortcutModel::updateCurrentMode(const QString &key)
{
    if (key == TABLET_MODE) {
        bool isTabletMode = Sidebar::GlobalSettings::globalInstance()->getValue(TABLET_MODE).toBool();
        auto mode = isTabletMode ? PluginMetaType::Tablet : PluginMetaType::PC;
        if (mode != m_currentMode) {
            m_currentMode = mode;
        }
    }
}

void ShortcutModel::initShortcutModel()
{
    m_shortcutManager = ShortcutManager::getInstance();

    for (const auto &item : m_shortcutManager->getShortcuts()) {
        if (item->pluginMetaData().value(PluginMetaType::PC).pluginType() == PluginMetaType::ProgressBar) {
            insertShortcut(item);
        }
    }

    connect(Sidebar::GlobalSettings::globalInstance(), &Sidebar::GlobalSettings::valueChanged,
            this, &ShortcutModel::updateCurrentMode);
}
