/*
 * Copyright (C) 2017-2020 by Savoir-faire Linux
 * Author: Anthony Léonard <anthony.leonard@savoirfairelinux.com>
 * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
 * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

#include "smartlistmodel.h"

#include "lrcinstance.h"
#include "pixbufmanipulator.h"
#include "utils.h"

#include "api/contactmodel.h"
#include "globalinstances.h"

#include <QDateTime>

SmartListModel::SmartListModel(const QString &accId,
                               QObject *parent,
                               SmartListModel::Type listModelType,
                               const QString &convUid)
    : QAbstractListModel(parent)
    , accountId_(accId)
    , listModelType_(listModelType)
    , convUid_(convUid)
{
    if (listModelType_ == Type::CONFERENCE) {
        setConferenceableFilter();
    }
}

SmartListModel::~SmartListModel() {}

int
SmartListModel::rowCount(const QModelIndex &parent) const
{
    if (!parent.isValid()) {
        auto &accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
        auto &convModel = accInfo.conversationModel;
        if (listModelType_ == Type::TRANSFER) {
            auto filterType = accInfo.profileInfo.type;
            return convModel->getFilteredConversations(filterType).size();
        } else if (listModelType_ == Type::CONFERENCE) {
            auto calls = conferenceables_[ConferenceableItem::CALL];
            auto contacts = conferenceables_[ConferenceableItem::CONTACT];
            auto rowCount = contacts.size();
            if (calls.size()) {
                rowCount = 2;
                rowCount += sectionState_[tr("Calls")] ? calls.size() : 0;
                rowCount += sectionState_[tr("Contacts")] ? contacts.size() : 0;
            }
            return rowCount;
        }
        return conversations_.size();
    }
    return 0;
}

int
SmartListModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return 1;
}

QVariant
SmartListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) {
        return QVariant();
    }

    try {
        auto &accountInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
        auto &convModel = accountInfo.conversationModel;
        lrc::api::conversation::Info item;
        if (listModelType_ == Type::TRANSFER) {
            auto filterType = accountInfo.profileInfo.type;
            item = convModel->getFilteredConversations(filterType).at(index.row());
            return getConversationItemData(item, accountInfo, role);
        } else if (listModelType_ == Type::CONFERENCE) {
            auto calls = conferenceables_[ConferenceableItem::CALL];
            auto contacts = conferenceables_[ConferenceableItem::CONTACT];
            QString itemConvUid{}, itemAccId{};
            if (calls.size() == 0) {
                itemConvUid = contacts.at(index.row()).at(0).convId;
                itemAccId = contacts.at(index.row()).at(0).accountId;
            } else {
                bool callsOpen = sectionState_[tr("Calls")];
                bool contactsOpen = sectionState_[tr("Contacts")];
                auto callSectionEnd = callsOpen ? calls.size() + 1 : 1;
                auto contactSectionEnd = contactsOpen ? callSectionEnd + contacts.size() + 1
                                                      : callSectionEnd + 1;
                if (index.row() < callSectionEnd) {
                    if (index.row() == 0) {
                        return QVariant(role == Role::SectionName
                                            ? (callsOpen ? "➖ " : "➕ ") + QString(tr("Calls"))
                                            : "");
                    } else {
                        auto idx = index.row() - 1;
                        itemConvUid = calls.at(idx).at(0).convId;
                        itemAccId = calls.at(idx).at(0).accountId;
                    }
                } else if (index.row() < contactSectionEnd) {
                    if (index.row() == callSectionEnd) {
                        return QVariant(role == Role::SectionName
                                            ? (contactsOpen ? "➖ " : "➕ ") + QString(tr("Contacts"))
                                            : "");
                    } else {
                        auto idx = index.row() - (callSectionEnd + 1);
                        itemConvUid = contacts.at(idx).at(0).convId;
                        itemAccId = contacts.at(idx).at(0).accountId;
                    }
                }
            }
            if (role == Role::AccountId) {
                return QVariant(itemAccId);
            }

            auto &itemAccountInfo = LRCInstance::accountModel().getAccountInfo(itemAccId);
            item = itemAccountInfo.conversationModel->getConversationForUID(itemConvUid);
            return getConversationItemData(item, itemAccountInfo, role);
        } else if (listModelType_ == Type::CONVERSATION) {
            item = conversations_.at(index.row());
            return getConversationItemData(item, accountInfo, role);
        }
    } catch (const std::exception &e) {
        qWarning() << e.what();
    }
    return QVariant();
}

QHash<int, QByteArray>
SmartListModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[DisplayName] = "DisplayName";
    roles[DisplayID] = "DisplayID";
    roles[Picture] = "Picture";
    roles[Presence] = "Presence";
    roles[URI] = "URI";
    roles[UnreadMessagesCount] = "UnreadMessagesCount";
    roles[LastInteractionDate] = "LastInteractionDate";
    roles[LastInteraction] = "LastInteraction";
    roles[ContactType] = "ContactType";
    roles[UID] = "UID";
    roles[InCall] = "InCall";
    roles[IsAudioOnly] = "IsAudioOnly";
    roles[CallStackViewShouldShow] = "CallStackViewShouldShow";
    roles[CallState] = "CallState";
    roles[SectionName] = "SectionName";
    roles[AccountId] = "AccountId";
    roles[Draft] = "Draft";
    return roles;
}

void
SmartListModel::setConferenceableFilter(const QString &filter)
{
    beginResetModel();
    auto &accountInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
    auto &convModel = accountInfo.conversationModel;
    conferenceables_ = convModel->getConferenceableConversations(convUid_, filter);
    sectionState_[tr("Calls")] = true;
    sectionState_[tr("Contacts")] = true;
    endResetModel();
}

void
SmartListModel::fillConversationsList()
{
    beginResetModel();
    auto* convModel = LRCInstance::getCurrentConversationModel();
    conversations_.clear();

    for (auto convSearch : convModel->getAllSearchResults()) {
        conversations_.emplace_back(convSearch);
    }

    for (auto convFilt : convModel->allFilteredConversations()) {
        conversations_.emplace_back(convFilt);
    }
    endResetModel();
}

void
SmartListModel::updateConversation(const QString &convUid)
{
    auto* convModel = LRCInstance::getCurrentConversationModel();
    for (lrc::api::conversation::Info &conversation : conversations_) {
        if (conversation.uid == convUid) {
            conversation = convModel->getConversationForUID(convUid);
            return;
        }
    }
}

void
SmartListModel::toggleSection(const QString &section)
{
    beginResetModel();
    if (section.contains(tr("Calls"))) {
        sectionState_[tr("Calls")] ^= true;
    } else if (section.contains(tr("Contacts"))) {
        sectionState_[tr("Contacts")] ^= true;
    }
    endResetModel();
}

int
SmartListModel::currentUidSmartListModelIndex()
{
    const auto convUid = LRCInstance::getCurrentConvUid();
    for (int i = 0; i < rowCount(); i++) {
        if (convUid == data(index(i, 0), Role::UID))
            return i;
    }

    return -1;
}

QVariant
SmartListModel::getConversationItemData(const conversation::Info &item,
                                        const account::Info &accountInfo,
                                        int role) const
{
    if (item.participants.size() <= 0) {
        return QVariant();
    }
    auto &contactModel = accountInfo.contactModel;
    switch (role) {
    case Role::Picture: {
        auto contactImage
            = GlobalInstances::pixmapManipulator().decorationRole(item, accountInfo).value<QImage>();
        return QString::fromLatin1(Utils::QImageToByteArray(contactImage).toBase64().data());
    }
    case Role::DisplayName: {
        if (!item.participants.isEmpty()) {
            auto &contact = contactModel->getContact(item.participants[0]);
            return QVariant(Utils::bestNameForContact(contact));
        }
        return QVariant("");
    }
    case Role::DisplayID: {
        if (!item.participants.isEmpty()) {
            auto &contact = contactModel->getContact(item.participants[0]);
            return QVariant(Utils::bestIdForContact(contact));
        }
        return QVariant("");
    }
    case Role::Presence: {
        if (!item.participants.isEmpty()) {
            auto &contact = contactModel->getContact(item.participants[0]);
            return QVariant(contact.isPresent);
        }
        return QVariant(false);
    }
    case Role::URI: {
        if (!item.participants.isEmpty()) {
            auto &contact = contactModel->getContact(item.participants[0]);
            return QVariant(contact.profileInfo.uri);
        }
        return QVariant("");
    }
    case Role::UnreadMessagesCount:
        return QVariant(item.unreadMessages);
    case Role::LastInteractionDate: {
        if (!item.interactions.empty()) {
            auto &date = item.interactions.at(item.lastMessageUid).timestamp;
            return QVariant(QString::fromStdString(Utils::formatTimeString(date)));
        }
        return QVariant("");
    }
    case Role::LastInteraction: {
        if (!item.interactions.empty()) {
            return QVariant(item.interactions.at(item.lastMessageUid).body);
        }
        return QVariant("");
    }
    case Role::LastInteractionType: {
        if (!item.interactions.empty()) {
            return QVariant(
                Utils::toUnderlyingValue(item.interactions.at(item.lastMessageUid).type));
        }
        return QVariant(0);
    }
    case Role::ContactType: {
        if (!item.participants.isEmpty()) {
            auto &contact = contactModel->getContact(item.participants[0]);
            return QVariant(Utils::toUnderlyingValue(contact.profileInfo.type));
        }
        return QVariant(0);
    }
    case Role::UID:
        return QVariant(item.uid);
    case Role::InCall: {
        auto* convModel = LRCInstance::getCurrentConversationModel();
        const auto convInfo = convModel->getConversationForUID(item.uid);
        if (!convInfo.uid.isEmpty()) {
            auto* callModel = LRCInstance::getCurrentCallModel();
            return QVariant(callModel->hasCall(convInfo.callId));
        }
        return QVariant(false);
    }
    case Role::IsAudioOnly: {
        auto* convModel = LRCInstance::getCurrentConversationModel();
        const auto convInfo = convModel->getConversationForUID(item.uid);
        if (!convInfo.uid.isEmpty()) {
            auto* call = LRCInstance::getCallInfoForConversation(convInfo);
            if (call) {
                return QVariant(call->isAudioOnly);
            }
        }
        return QVariant();
    }
    case Role::CallStackViewShouldShow: {
        auto* convModel = LRCInstance::getCurrentConversationModel();
        const auto convInfo = convModel->getConversationForUID(item.uid);
        if (!convInfo.uid.isEmpty()) {
            auto* callModel = LRCInstance::getCurrentCallModel();
            const auto call = callModel->getCall(convInfo.callId);
            return QVariant(callModel->hasCall(convInfo.callId)
                            && ((!call.isOutgoing
                                 && (call.status == lrc::api::call::Status::IN_PROGRESS
                                     || call.status == lrc::api::call::Status::PAUSED))
                                || call.isOutgoing));
        }
        return QVariant(false);
    }
    case Role::CallState: {
        auto* convModel = LRCInstance::getCurrentConversationModel();
        const auto convInfo = convModel->getConversationForUID(item.uid);
        if (!convInfo.uid.isEmpty()) {
            auto* call = LRCInstance::getCallInfoForConversation(convInfo);
            if (call) {
                return QVariant(static_cast<int>(call->status));
            }
        }
        return QVariant();
    }
    case Role::SectionName:
        return QVariant(QString());
    case Role::Draft: {
        if (!item.uid.isEmpty()) {
            const auto draft = LRCInstance::getContentDraft(item.uid, accountInfo.id);
            if (!draft.isEmpty()) {
                /*
                 * Pencil Emoji
                 */
                uint cp = 0x270F;
                auto emojiString = QString::fromUcs4(&cp, 1);
                return emojiString + LRCInstance::getContentDraft(item.uid, accountInfo.id);
            }
        }
        return QVariant("");
    }
    }
    return QVariant();
}

QModelIndex
SmartListModel::index(int row, int column, const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    if (column != 0) {
        return QModelIndex();
    }

    if (row >= 0 && row < rowCount()) {
        return createIndex(row, column);
    }
    return QModelIndex();
}

QModelIndex
SmartListModel::parent(const QModelIndex &child) const
{
    Q_UNUSED(child);
    return QModelIndex();
}

Qt::ItemFlags
SmartListModel::flags(const QModelIndex &index) const
{
    auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
    auto type = Utils::toEnum<lrc::api::profile::Type>(data(index, Role::ContactType).value<int>());
    auto uid = data(index, Role::UID).value<QString>();
    if (!index.isValid()) {
        return QAbstractItemModel::flags(index);
    } else if ((type == lrc::api::profile::Type::TEMPORARY && uid.isEmpty())) {
        flags &= ~(Qt::ItemIsSelectable);
    }
    return flags;
}

void
SmartListModel::setAccount(const QString &accountId)
{
    accountId_ = accountId;
}
