/*
    SPDX-FileCopyrightText: 2009 Kevin Ottens <ervin@kde.org>

    SPDX-License-Identifier: GPL-2.0-or-later
*/

#pragma once

#include "messagelist/storagemodelbase.h"
#include "messagelist_export.h"

#include <Akonadi/Collection>
#include <Akonadi/Item>
#include <KMime/Message>
#include <QList>

class QAbstractItemModel;
class QItemSelectionModel;

namespace Akonadi
{
class Item;
}

namespace MessageList
{
namespace Core
{
class MessageItem;
}

/*!
 * \class MessageList::StorageModel
 * \inmodule MessageList
 * \inheaderfile MessageList/StorageModel
 *
 * The Akonadi specific implementation of the Core::StorageModel.
 */
class MESSAGELIST_EXPORT StorageModel : public MessageList::Core::StorageModel
{
    Q_OBJECT

public:
    /*!
     * \brief Create a StorageModel wrapping the specified folder.
     * \param model The item model.
     * \param selectionModel The selection model.
     * \param parent The parent object.
     */
    explicit StorageModel(QAbstractItemModel *model, QItemSelectionModel *selectionModel, QObject *parent = nullptr);
    /*!
     * \brief Destructor.
     */
    ~StorageModel() override;

    /*!
     * \brief Get displayed collections.
     * \return The list of displayed collections.
     */
    [[nodiscard]] Akonadi::Collection::List displayedCollections() const;

    /*!
     * \brief Get ID.
     * \return The ID string.
     */
    [[nodiscard]] QString id() const override;
    /*!
     * \brief Check if contains outbound messages.
     * \return True if contains outbound messages.
     */
    [[nodiscard]] bool containsOutboundMessages() const override;

    /*!
     * \brief Check if is outbound folder.
     * \param c The collection to check.
     * \return True if is outbound folder.
     */
    [[nodiscard]] virtual bool isOutBoundFolder(const Akonadi::Collection &c) const;

    /*!
     * \brief Get initial unread row count guess.
     * \return The initial unread row count guess.
     */
    [[nodiscard]] int initialUnreadRowCountGuess() const override;
    /*!
     */
    [[nodiscard]] bool initializeMessageItem(MessageList::Core::MessageItem *mi, int row, bool bUseReceiver) const override;
    /*!
     */
    void fillMessageItemThreadingData(MessageList::Core::MessageItem *mi, int row, ThreadingDataSubset subset) const override;
    /*!
     */
    void updateMessageItemData(MessageList::Core::MessageItem *mi, int row) const override;
    /*!
     */
    void setMessageItemStatus(MessageList::Core::MessageItem *mi, int row, Akonadi::MessageStatus status) override;

    /*!
     */
    [[nodiscard]] int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    /*!
     */
    [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    /*!
     */
    [[nodiscard]] QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
    /*!
     */
    [[nodiscard]] QModelIndex parent(const QModelIndex &index) const override;
    /*!
     */
    [[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;

    /*!
     */
    [[nodiscard]] QMimeData *mimeData(const QList<MessageList::Core::MessageItem *> &) const override;
    /*!
     */
    using MessageList::Core::StorageModel::mimeData;

    /*!
     */
    [[nodiscard]] Akonadi::Item itemForRow(int row) const;
    /*!
     */
    [[nodiscard]] Akonadi::Collection parentCollectionForRow(int row) const;
    /*!
     */
    [[nodiscard]] std::shared_ptr<KMime::Message> messageForRow(int row) const;

    /*!
     */
    [[nodiscard]] Akonadi::Collection collectionForId(Akonadi::Collection::Id colId) const;

    /*!
     */
    void resetModelStorage();

private:
    class StorageModelPrivate;
    std::unique_ptr<StorageModelPrivate> const d;
};
} // namespace MessageList
