#include "DateGroupProxyModel.h"
#include <QDateTime>
#include <QDate>
#include <QDebug>
#include "EmailListModel.h"

DateGroupProxyModel::DateGroupProxyModel(QObject *parent)
    : QSortFilterProxyModel(parent)
{
    setDynamicSortFilter(true);
}

void DateGroupProxyModel::setGroupByDate(bool enabled)
{
    if (m_groupByDate == enabled) return;
    m_groupByDate = enabled;
    invalidate();
}

bool DateGroupProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
    if (!m_groupByDate) {
        return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
    }
    
    // When grouping, we don't filter rows, we just organize them
    return true;
}

bool DateGroupProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
    // First sort by group, then by date within group (descending)
    if (m_groupByDate) {
        int leftGroup = groupForRow(left.row());
        int rightGroup = groupForRow(right.row());
        
        if (leftGroup != rightGroup) {
            return leftGroup < rightGroup;
        }
        
        // Same group - sort by date descending (newest first)
        QVariant leftDate = sourceModel()->data(left, EmailListModel::DateRole);
        QVariant rightDate = sourceModel()->data(right, EmailListModel::DateRole);
        
        if (leftDate.isValid() && rightDate.isValid()) {
            return leftDate.toDateTime() > rightDate.toDateTime();
        }
    }
    
    return QSortFilterProxyModel::lessThan(left, right);
}

QString DateGroupProxyModel::groupNameForDate(const QDateTime &date)
{
    if (!date.isValid()) return "Sin fecha";
    
    QDate emailDate = date.date();
    QDate today = QDate::currentDate();
    
    int daysDiff = today.daysTo(emailDate);
    
    if (daysDiff == 0) {
        return "Hoy";
    } else if (daysDiff == -1) {
        return "Ayer";
    } else if (daysDiff > -7 && daysDiff < 0) {
        // This week (Monday to Sunday)
        return emailDate.dayOfWeek() == 1 ? "Esta semana (Lunes)" : "Esta semana";
    } else if (daysDiff >= -13 && daysDiff <= -7) {
        return "Semana pasada";
    } else if (daysDiff >= -20 && daysDiff <= -14) {
        return "Hace dos semanas";
    } else if (emailDate.month() == today.month() && emailDate.year() == today.year()) {
        return "Este mes";
    } else if (emailDate.year() == today.year()) {
        // Month name
        static const QString months[] = {
            "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
            "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
        };
        return months[emailDate.month() - 1];
    } else {
        return QString("%1").arg(emailDate.year());
    }
}

void DateGroupProxyModel::updateGroupCache() const
{
    m_groupRowCounts.clear();
    m_groupStartRows.clear();
    
    int rowCount = this->rowCount();
    if (rowCount == 0) return;
    
    QString lastGroup = "";
    int currentGroup = -1;
    
    for (int i = 0; i < rowCount; ++i) {
        QModelIndex idx = index(i, 0);
        QString group = idx.data(GroupRole).toString();
        
        if (group != lastGroup) {
            currentGroup++;
            lastGroup = group;
            m_groupStartRows.append(i);
            m_groupRowCounts.append(1);
        } else {
            m_groupRowCounts[currentGroup]++;
        }
    }
}

int DateGroupProxyModel::groupForRow(int row) const
{
    if (row < 0 || row >= rowCount()) return -1;
    
    if (m_groupStartRows.isEmpty()) {
        updateGroupCache();
    }
    
    // Binary search for group
    int group = 0;
    for (int i = m_groupStartRows.size() - 1; i >= 0; --i) {
        if (row >= m_groupStartRows[i]) {
            return i;
        }
    }
    return 0;
}

QString DateGroupProxyModel::groupNameForRow(int row) const
{
    if (row < 0 || row >= rowCount()) return "";
    
    QModelIndex idx = index(row, 0);
    return idx.data(GroupRole).toString();
}

QVariant DateGroupProxyModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) return QVariant();
    
    if (role == GroupRole) {
        // Return group name for this row
        QModelIndex sourceIdx = mapToSource(index);
        QVariant dateVar = sourceModel()->data(sourceIdx, EmailListModel::DateRole);
        if (dateVar.isValid()) {
            return groupNameForDate(dateVar.toDateTime());
        }
        return "Sin fecha";
    }
    
    if (role == IsGroupHeaderRole) {
        // This would be used if we inserted header rows - not implemented yet
        return false;
    }
    
    if (role == GroupSectionRole) {
        return groupForRow(index.row());
    }
    
    return QSortFilterProxyModel::data(index, role);
}

QVariant DateGroupProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role == GroupRole && orientation == Qt::Horizontal && m_groupByDate) {
        // For the date column, we might want to show group headers
        // This is for column headers, not row grouping
    }
    
    return QSortFilterProxyModel::headerData(section, orientation, role);
}