/*
 * 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[CallStateStr] = "CallStateStr";
    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::CallStateStr: {
        auto* convModel = LRCInstance::getCurrentConversationModel();
        const auto convInfo = convModel->getConversationForUID(item.uid);
        if (!convInfo.uid.isEmpty()) {
            auto* call = LRCInstance::getCallInfoForConversation(convInfo);
            if (call) {
                auto statusString = call::to_string(call->status);
                return QVariant(statusString);
            }
        }
        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;
}
