#include "FolderListModel.h"
#include <QDebug>

// --- FolderTreeItem ---

FolderTreeItem::FolderTreeItem(Type type, QVariant data, FolderTreeItem *parent)
    : m_type(type), m_data(std::move(data)), m_parentItem(parent)
{
}

FolderTreeItem::~FolderTreeItem()
{
    qDeleteAll(m_childItems);
}

void FolderTreeItem::appendChild(FolderTreeItem *child)
{
    m_childItems.append(child);
}

void FolderTreeItem::clearChildren()
{
    qDeleteAll(m_childItems);
    m_childItems.clear();
}

FolderTreeItem *FolderTreeItem::child(int row)
{
    if (row < 0 || row >= m_childItems.size())
        return nullptr;
    return m_childItems.at(row);
}

int FolderTreeItem::childCount() const
{
    return m_childItems.size();
}

int FolderTreeItem::row() const
{
    if (m_parentItem)
        return m_parentItem->m_childItems.indexOf(const_cast<FolderTreeItem*>(this));
    return 0;
}

FolderTreeItem *FolderTreeItem::parentItem()
{
    return m_parentItem;
}

// --- FolderListModel ---

FolderListModel::FolderListModel(AccountService *accountService, QObject *parent)
    : QAbstractItemModel(parent),
      m_accountService(accountService),
      m_rootItem(new FolderTreeItem(FolderTreeItem::AccountNode, "Root"))
{
    refresh();
}

FolderListModel::~FolderListModel()
{
    delete m_rootItem;
}

QModelIndex FolderListModel::index(int row, int column, const QModelIndex &parent) const
{
    if (!hasIndex(row, column, parent))
        return QModelIndex();

    FolderTreeItem *parentItem;
    if (!parent.isValid())
        parentItem = m_rootItem;
    else
        parentItem = static_cast<FolderTreeItem*>(parent.internalPointer());

    FolderTreeItem *childItem = parentItem->child(row);
    if (childItem)
        return createIndex(row, column, childItem);
    return QModelIndex();
}

QModelIndex FolderListModel::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();

    FolderTreeItem *childItem = static_cast<FolderTreeItem*>(index.internalPointer());
    FolderTreeItem *parentItem = childItem->parentItem();

    if (!parentItem || parentItem == m_rootItem)
        return QModelIndex();

    return createIndex(parentItem->row(), 0, parentItem);
}

int FolderListModel::rowCount(const QModelIndex &parent) const
{
    if (parent.column() > 0)
        return 0;

    FolderTreeItem *parentItem;
    if (!parent.isValid())
        parentItem = m_rootItem;
    else
        parentItem = static_cast<FolderTreeItem*>(parent.internalPointer());

    return parentItem->childCount();
}

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

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

    FolderTreeItem *item = static_cast<FolderTreeItem*>(index.internalPointer());

    if (role == Qt::DisplayRole || role == NameRole) {
        if (item->type() == FolderTreeItem::AccountNode) {
            Account acc = item->data().value<Account>();
            return acc.displayName().isEmpty() ? acc.email() : acc.displayName();
        } else {
            Folder folder = item->data().value<Folder>();
            return folder.name();
        }
    }

    if (role == ItemTypeRole)
        return item->type();

    if (role == AccountIdRole) {
        if (item->type() == FolderTreeItem::AccountNode) {
            Account acc = item->data().value<Account>();
            return acc.id();
        }
    }

    if (role == FolderIdRole) {
        if (item->type() == FolderTreeItem::FolderNode) {
            Folder folder = item->data().value<Folder>();
            return folder.id();
        }
    }

    if (role == UnreadCountRole) {
        if (item->type() == FolderTreeItem::FolderNode) {
            Folder folder = item->data().value<Folder>();
            return folder.unreadCount();
        }
    }

    return QVariant();
}

Qt::ItemFlags FolderListModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::NoItemFlags;
    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}

QHash<int, QByteArray> FolderListModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[ItemTypeRole] = "itemType";
    roles[AccountIdRole] = "accountId";
    roles[FolderIdRole] = "folderId";
    roles[NameRole] = "name";
    roles[UnreadCountRole] = "unreadCount";
    return roles;
}

void FolderListModel::refresh()
{
    beginResetModel();
    clearModel();
    setupModelData();
    endResetModel();
    qDebug() << "FolderListModel refreshed";
}

void FolderListModel::setupModelData()
{
    QVector<Account> accounts = m_accountService->getAllAccounts();

    // If no accounts exist yet, add one sample account with default folders
    if (accounts.isEmpty()) {
        Account sample(1, "javi@example.com", "Javi's Email",
                       AccountType::IMAP);
        accounts.append(sample);
    }

    for (const Account &acc : accounts) {
        QVariant accVariant;
        accVariant.setValue(acc);
        FolderTreeItem *accountItem = new FolderTreeItem(FolderTreeItem::AccountNode, accVariant, m_rootItem);
        m_rootItem->appendChild(accountItem);

        // Get folders for this account
        QVector<Folder> folders = FolderDao::findByAccountId(acc.id());

        // If no folders exist yet, create default ones
        if (folders.isEmpty()) {
            QStringList defaultFolders = {"Inbox", "Sent", "Drafts", "Trash", "Spam"};
            for (const QString &name : defaultFolders) {
                Folder f;
                f.setName(name);
                f.setAccountId(acc.id());
                folders.append(f);
            }
        }

        for (const Folder &folder : folders) {
            QVariant folderVariant;
            folderVariant.setValue(folder);
            FolderTreeItem *folderItem = new FolderTreeItem(FolderTreeItem::FolderNode, folderVariant, accountItem);
            accountItem->appendChild(folderItem);
        }
    }
}

void FolderListModel::clearModel()
{
    m_rootItem->clearChildren();
}

#include "FolderListModel.moc"