#include "filefiltermodel.h"

#include "src/data/datadirectory.h"
#include "src/data/datacdrom.h"
#include "src/po/translation.h"
#include "src/view/filefilterrules.h"
#include "src/frame/configuration.h"

#include <QFont>
#include <QBrush>
#include <QDebug>
#include <ukuistylehelper.h>

FileFilterModel::FileFilterModel(QObject *parent)
    : QAbstractItemModel(parent),
      m_iIndex(-1)
{
    m_oHeaders.clear();
    m_oRoots.clear();
}

QVariant FileFilterModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    QFont f;
    if (orientation == Qt::Horizontal)
    {
        switch (role)
        {
        case Qt::DisplayRole:
            if (m_oHeaders.size() && section < m_oHeaders.size())
                return m_oHeaders.at(section);
            else
                return QString();
            break;
        case Qt::FontRole:
            f.setPixelSize(14);
            f.setWeight(60);
            return f;
        default:
            break;
        }
    }
    return QVariant();
}

bool FileFilterModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
    if (value != headerData(section, orientation, role)) {
        switch (role)
        {
        case Qt::DisplayRole:
            if (orientation == Qt::Horizontal)
            {
                if (section > m_oHeaders.size())
                    return false;
                else if (section == m_oHeaders.size())
                    m_oHeaders << value.toString();
                else
                    m_oHeaders.replace(section, value.toString());
            }
            break;
        }
        emit headerDataChanged(orientation, section, section);
        return true;
    }
    return false;
}

QModelIndex FileFilterModel::index(int row, int column, const QModelIndex &parent) const
{
    DataDirectory *p;
    if (!parent.isValid() && row < m_oRoots.size() && row > -1)
        return createIndex(row, 0, m_oRoots.at(row));
    p = (DataDirectory *)(parent.internalPointer());
    if (nullptr == p) return QModelIndex();
    return createIndex(row, column, p->at(row));
    return QModelIndex();
}

QModelIndex FileFilterModel::parent(const QModelIndex &index) const
{
    DataDirectory *root;
    DataDirectory *parent;
    DataFile *data;
    if (!index.isValid())
        return QModelIndex();
    data = static_cast<DataFile *>(index.internalPointer());
    if (nullptr == data) return QModelIndex();
    root = static_cast<DataDirectory *>(m_oRoots.at(m_iIndex));
    if (-1 == root->of(data))
    {
        parent = qobject_cast<DataDirectory *>(data->parent());
        if (nullptr == parent) return QModelIndex();
        root = qobject_cast<DataDirectory *>(parent->parent());
        if (root && root->isDirectory())
            return createIndex(root->of(parent), 0, parent);
    }
    else
    {
        return createIndex(root->of(data), 0, root);
    }
    return QModelIndex();
}

int FileFilterModel::rowCount(const QModelIndex &parent) const
{
    DataDirectory *dir;
    if (!parent.isValid())
        return m_oRoots.size();
    dir = static_cast<DataDirectory *>(parent.internalPointer());
    if (nullptr == dir || !dir->isDirectory()) return 0;
    return dir->counts();
}

int FileFilterModel::columnCount(const QModelIndex &parent) const
{
    return m_oHeaders.size();
}

QVariant FileFilterModel::data(const QModelIndex &index, int role) const
{
    DataFile *item;

    if (!index.isValid())
        return QVariant();

    item = static_cast<DataFile *>(index.internalPointer());
    if (nullptr == item) return QVariant();

    switch (role)
    {
    case Qt::DisplayRole:
        switch (index.column())
        {
        case 0:
            return item->display();
        case 1:
            return item->source();
        }
        break;
    case Qt::EditRole:
        if (0 == index.column())
            return item->display();
    case Qt::DecorationRole:
        if (0 == index.column())
        {
            if (item->isDisk())
            {
                return QIcon(item->icon().pixmap(QSize(24, 24), QIcon::Disabled));
            }
            else
            {
                return item->icon();
            }
        }
        break;
    case Qt::FontRole:
#if 0
        if (item->isSymbolLink() && 0 == index.column())
        {
            f.setItalic(true);
            return f;
        }
#endif
        break;
    case Qt::ForegroundRole:
        if (item->isDisk())
            return QBrush(QColor(179, 179, 179));
    }

    return QVariant();
}

int FileFilterModel::filtered()
{
    int ret;
    DataDirectory *root;

    ret = 0;
    for (int i = 0; i < m_oRoots.size(); ++i)
    {
        root = (DataDirectory *)(m_oRoots.at(i));
        if (root) ret += root->count();
    }
    return ret;
}

void FileFilterModel::addFilterNode(void *c)
{
    DataDirectory *root;
    DataCDROM *cdrom;
    QString path;

    path.clear();
    cdrom = (DataCDROM *)(c);
    if(cdrom->m_iUsing <= 0) return;
    //cdrom->use();
    // path = cdrom->settingTempPath();
    path.append(cdrom->settingTempPath());
    path.append("/.filter/");
    path.append(cdrom->settingVolumnID());
    root = new DataDirectory(path, this);
    m_oRoots << root;
    emit node(cdrom->mediumIcon(), cdrom->mDisplay());
    emit this->root(createIndex(m_oRoots.size() - 1, 0, root));
    //cdrom->release();
}

void FileFilterModel::deleteFilterNode(int idx)
{
    qDebug()<<__LINE__<<__func__<<idx;
    DataDirectory *root;

    if (idx >= m_oRoots.size() || idx < 0) return;

    root = static_cast<DataDirectory *>(m_oRoots.takeAt(idx));
    if (root)
    {
        root->clear();
        delete root;
        root = nullptr;
    }
}

void FileFilterModel::showRules()
{
    DataDirectory *root;
    if (m_iIndex < 0 || m_iIndex >= m_oRoots.size()) return;
    root = static_cast<DataDirectory *>(m_oRoots.at(m_iIndex));
    if (root)
    {
        FILTERRULES->init(root);
        if (FILTERRULES->isHidden()) {
            if(FILTERRULES->isWayland())
                kdk::UkuiStyleHelper::self()->removeHeader(FILTERRULES);
            FILTERRULES->show();
        }
        else
            FILTERRULES->activateWindow();
    }
}

void FileFilterModel::addFilterData(int idx, void *d)
{
    DataDirectory *root;

    root = (DataDirectory *)m_oRoots.at(idx);
    if (nullptr == root) return;
    beginInsertRows(createIndex(idx, 0, root), root->counts(), 1);
    root->append((DataFile *)d);
   // root->filterAppend((DataFile *)d);
    endInsertRows();
    root->turnViewFilterFileToHidden();
    root->turnViewFilterFileToBrokenSymbolLinks();
    root->turnViewFilterFileToRepleaceSymbolLinks();
}

void FileFilterModel::recovery(/*QModelIndexList idxes*/)
{
    DataDirectory *root;
    DataFile      *child;

    QList<void *>  hiddens;
    QList<void *>  brokens;
    QList<void *>  replaces;

    if (m_iIndex < 0) return;

    hiddens.clear();
    brokens.clear();
    replaces.clear();

    root = static_cast<DataDirectory *>(m_oRoots.at(m_iIndex));
    qDebug()<<__LINE__<<__func__<<root->counts();
    for (int i = 0; i < root->counts(); ++i)
    {
        child = root->at(i);
        beginRemoveRows(createIndex(m_iIndex, 0, m_oRoots.at(m_iIndex)), 0, 1);
        root->take(child);
        --i;
        endRemoveRows();
        if (child->attrHidden())
        {
            CFG->set("FilterFile","hidden",!child->attrHidden());
            hiddens << child;
        }

        else if (child->attrSymbolLink() && child->linkTarget())
        {
            CFG->set("FilterFile","Repleace",!child->attrSymbolLink());
            replaces << child;
        }
        else
        {
            CFG->set("FilterFile","broken",false);
            brokens << child;
        }
    }

#if 0
    if (0 == idxes.size())
    {
        for (int i = 0; i < root->counts(); ++i)
        {
            child = root->at(i);
            beginRemoveRows(createIndex(m_iIndex, 0, m_oRoots.at(m_iIndex)), 0, 1);
            root->take(child);
            endRemoveRows();
            if (child->attrHidden()) hiddens << child;
            else if (child->attrSymbolLink() && child->linkTarget()) replaces << child;
            else brokens << child;
        }
    }
    else
    {
        while (idxes.size())
        {
            child = static_cast<DataFile *>(idxes.takeFirst().internalPointer());
            if (!child) continue;
            beginRemoveRows(createIndex(m_iIndex, 0, m_oRoots.at(m_iIndex)), 0, 1);
            root->take(child);
            endRemoveRows();
            if (child->attrHidden()) hiddens << child;
            else if (child->attrSymbolLink() && child->linkTarget()) replaces << child;
            else brokens << child;
        }
    }
#endif
    qDebug()<<__func__<<__LINE__<<"FileFilterModel"<<hiddens.size();
    recovery(hiddens, brokens, replaces);
    root->turnViewFilterFileToHidden();
    root->turnViewFilterFileToBrokenSymbolLinks();
    root->turnViewFilterFileToRepleaceSymbolLinks();
}

QList<void *> FileFilterModel::recoveryHiddenData(int idx, int level)
{
    QList<void *>  ret;
    DataFile      *file;
    DataDirectory *root;
    DataDirectory *parent;

    ret.clear();
    root = static_cast<DataDirectory *>(m_oRoots.at(idx));
    for (int i = 0; i < root->counts(); ++i)
    {
        file = root->at(i);
        if (file->level() >= level && file->attrHidden())
        {
            qDebug()<<__LINE__<<__func__;
            if (file->isDirectory() && file->level() == level) continue;
            beginRemoveRows(createIndex(idx, 0, m_oRoots.at(idx)), 0, 1);
            parent = qobject_cast<DataDirectory *>(file->parent());
            root->take(file);
            --i;
            endRemoveRows();
            ret << file;
        }
    }
    root->turnViewFilterFileToHidden();
    return ret;
}

QList<void *> FileFilterModel::recoveryBrokenData(int idx, int level)
{
    QList<void *>  ret;
    DataFile      *file;
    DataDirectory *root;
    DataDirectory *parent;

    ret.clear();
    root = static_cast<DataDirectory *>(m_oRoots.at(idx));
    for (int i = 0; i < root->counts(); ++i)
    {
        file = root->at(i);
        if (file->level() >= level && file->attrSymbolLink() && nullptr == file->linkTarget())
        {
            if (file->isDirectory() && file->level() == level) continue;
            beginRemoveRows(createIndex(idx, 0, m_oRoots.at(idx)), 0, 1);
            parent = qobject_cast<DataDirectory *>(file->parent());
            root->take(file);
            --i;
            endRemoveRows();
            ret << file;
        }
    }
    root->turnViewFilterFileToBrokenSymbolLinks();
    return ret;
}

QList<void *> FileFilterModel::recoveryRepleaceData(int idx, int level)
{
    QList<void *>  ret;
    DataFile      *file;
    DataDirectory *root;
    DataDirectory *parent;

    ret.clear();
    root = static_cast<DataDirectory *>(m_oRoots.at(idx));
    for (int i = 0; i < root->counts(); ++i)
    {
        file = root->at(i);
        if (file->level() >= level && file->attrSymbolLink())
        {
            if (file->isDirectory() && file->level() == level) continue;
            if (file->linkTarget())
            {
                beginRemoveRows(createIndex(idx, 0, m_oRoots.at(idx)), 0, 1);
                parent = qobject_cast<DataDirectory *>(file->parent());
                root->take(file);
                --i;
                endRemoveRows();
            }
            ret << file;
        }
    }
    root->turnViewFilterFileToRepleaceSymbolLinks();
    return ret;
}
