#include "rulesmanagerdialog.h"
#include "ruleditordialog.h"
#include "db/dao/ruledao.h"
#include "db/dao/categorydao.h"
#include "db/dao/folderdao.h"
#include "services/rulesengine.h"
#include "services/accountservice.h"
#include <QHeaderView>
#include <QMessageBox>
#include <QInputDialog>
#include <QFileDialog>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLabel>
#include <QMenu>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>

RulesManagerDialog::RulesManagerDialog(qint64 accountId, QWidget *parent) 
    : QDialog(parent), m_accountId(accountId)
{
    setWindowTitle(m_accountId >= 0 ? tr("Reglas de la cuenta") : tr("Reglas globales"));
    resize(900, 600);
    setupUI();
    loadRules();
}

void RulesManagerDialog::setupUI()
{
    QVBoxLayout* mainLayout = new QVBoxLayout(this);
    
    // Toolbar
    QHBoxLayout* toolLayout = new QHBoxLayout();
    m_btnNew = new QPushButton(tr("Nueva regla"));
    m_btnRun = new QPushButton(tr("Ejecutar ahora"));
    m_btnImport = new QPushButton(tr("Importar"));
    m_btnExport = new QPushButton(tr("Exportar"));
    m_btnClose = new QPushButton(tr("Cerrar"));
    
    m_btnNew->setStyleSheet("QPushButton { background: #1976D2; color: white; font-weight: bold; padding: 6px 12px; border-radius: 4px; } QPushButton:hover { background: #1565C0; }");
    m_btnRun->setStyleSheet("QPushButton { background: #4CAF50; color: white; padding: 6px 12px; border-radius: 4px; } QPushButton:hover { background: #43A047; }");
    
    toolLayout->addWidget(m_btnNew);
    toolLayout->addWidget(m_btnRun);
    toolLayout->addStretch();
    toolLayout->addWidget(m_btnImport);
    toolLayout->addWidget(m_btnExport);
    toolLayout->addWidget(m_btnClose);
    mainLayout->addLayout(toolLayout);
    
    // Tree widget
    m_tree = new QTreeWidget();
    m_tree->setHeaderLabels({tr("Activa"), tr("Nombre"), tr("Prioridad"), tr("Condiciones"), tr("Acciones"), tr("Cuenta"), tr("Última ejecución"), tr("Veces")});
    m_tree->setAlternatingRowColors(true);
    m_tree->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_tree->setSelectionMode(QAbstractItemView::SingleSelection);
    m_tree->setContextMenuPolicy(Qt::CustomContextMenu);
    m_tree->header()->setStretchLastSection(false);
    m_tree->header()->setSectionResizeMode(1, QHeaderView::Stretch);
    m_tree->setColumnWidth(0, 60);
    m_tree->setColumnWidth(2, 80);
    m_tree->setColumnWidth(3, 200);
    m_tree->setColumnWidth(4, 200);
    m_tree->setColumnWidth(5, 100);
    m_tree->setColumnWidth(6, 140);
    m_tree->setColumnWidth(7, 60);
    
    connect(m_tree, &QTreeWidget::customContextMenuRequested, this, [this](const QPoint& pos) {
        QTreeWidgetItem* item = m_tree->itemAt(pos);
        if (!item) return;
        
        QMenu menu(this);
        QAction* editAct = menu.addAction(tr("Editar"), [this, item]() { onEditRule(item); });
        QAction* delAct = menu.addAction(tr("Eliminar"), [this, item]() { onDeleteRule(item); });
        menu.addSeparator();
        QAction* toggleAct = menu.addAction(item->checkState(0) == Qt::Checked ? tr("Desactivar") : tr("Activar"), [this, item]() { onToggleEnabled(item); });
        menu.addSeparator();
        QAction* moveUpAct = menu.addAction(tr("Subir prioridad"), [this, item]() {
            int idx = m_tree->indexOfTopLevelItem(item);
            if (idx > 0) {
                QTreeWidgetItem* prev = m_tree->takeTopLevelItem(idx);
                m_tree->insertTopLevelItem(idx - 1, prev);
                // TODO: update priority in DB
            }
        });
        QAction* moveDownAct = menu.addAction(tr("Bajar prioridad"), [this, item]() {
            int idx = m_tree->indexOfTopLevelItem(item);
            if (idx < m_tree->topLevelItemCount() - 1) {
                QTreeWidgetItem* next = m_tree->takeTopLevelItem(idx + 1);
                m_tree->insertTopLevelItem(idx + 1, item);
                // TODO: update priority in DB
            }
        });
        menu.exec(m_tree->viewport()->mapToGlobal(pos));
    });
    
    connect(m_tree, &QTreeWidget::itemDoubleClicked, this, [this](QTreeWidgetItem* item) { onEditRule(item); });
    
    mainLayout->addWidget(m_tree, 1);
    
    // Status
    QLabel* statusLabel = new QLabel(tr("Doble click para editar. Click derecho para más opciones."));
    statusLabel->setStyleSheet("color: #666; font-size: 11px; padding: 4px;");
    mainLayout->addWidget(statusLabel);
    
    // Connect buttons
    connect(m_btnNew, &QPushButton::clicked, this, &RulesManagerDialog::onNewRule);
    connect(m_btnRun, &QPushButton::clicked, this, &RulesManagerDialog::onRunRules);
    connect(m_btnImport, &QPushButton::clicked, this, [this]() { onImportExport(true); });
    connect(m_btnExport, &QPushButton::clicked, this, [this]() { onImportExport(false); });
    connect(m_btnClose, &QPushButton::clicked, this, &QDialog::accept);
}

void RulesManagerDialog::loadRules()
{
    m_tree->clear();
    
    QVector<Rule> rules = RuleDao::findByAccount(m_accountId);
    
    for (const Rule& rule : rules) {
        addRuleToTree(rule);
    }
}

void RulesManagerDialog::addRuleToTree(const Rule& rule)
{
    QTreeWidgetItem* item = new QTreeWidgetItem(m_tree);
    item->setData(0, Qt::UserRole, rule.id);
    item->setCheckState(0, rule.enabled ? Qt::Checked : Qt::Unchecked);
    item->setText(1, rule.name);
    item->setText(2, QString::number(rule.priority));
    
    // Conditions summary
    QStringList condTexts;
    for (const RuleCondition& cond : rule.conditions) {
        QString fieldName;
        switch (cond.field) {
            case RuleCondition::From: fieldName = "De"; break;
            case RuleCondition::To: fieldName = "Para"; break;
            case RuleCondition::Cc: fieldName = "CC"; break;
            case RuleCondition::Subject: fieldName = "Asunto"; break;
            case RuleCondition::Body: fieldName = "Cuerpo"; break;
            case RuleCondition::HasAttachment: fieldName = "Tiene adjuntos"; break;
            case RuleCondition::Size: fieldName = "Tamaño"; break;
            case RuleCondition::Date: fieldName = "Fecha"; break;
            case RuleCondition::Flagged: fieldName = "Marcado"; break;
            case RuleCondition::Read: fieldName = "Leído"; break;
        }
        QString opName;
        switch (cond.op) {
            case RuleCondition::Contains: opName = "contiene"; break;
            case RuleCondition::NotContains: opName = "no contiene"; break;
            case RuleCondition::Equals: opName = "es"; break;
            case RuleCondition::NotEquals: opName = "no es"; break;
            case RuleCondition::StartsWith: opName = "empieza por"; break;
            case RuleCondition::EndsWith: opName = "termina en"; break;
            case RuleCondition::Regex: opName = "regex"; break;
            case RuleCondition::GreaterThan: opName = ">"; break;
            case RuleCondition::LessThan: opName = "<"; break;
            case RuleCondition::Before: opName = "antes de"; break;
            case RuleCondition::After: opName = "después de"; break;
        }
        condTexts.append(QString("%1 %2 \"%3\"").arg(fieldName, opName, cond.value));
    }
    item->setText(3, condTexts.join(rule.matchAll ? " Y " : " O "));
    
    // Actions summary
    QStringList actTexts;
    for (const RuleAction& act : rule.actions) {
        QString actName;
        switch (act.type) {
            case RuleAction::MoveToFolder: actName = QString("Mover a carpeta %1").arg(act.value); break;
            case RuleAction::MarkAsRead: actName = QString("Marcar como %1").arg(act.value == "false" ? "no leído" : "leído"); break;
            case RuleAction::MarkAsFlagged: actName = QString("Marcar como %1").arg(act.value == "false" ? "no marcado" : "marcado"); break;
            case RuleAction::Delete: actName = "Eliminar"; break;
            case RuleAction::AssignCategory: actName = QString("Categoría %1").arg(act.value); break;
            case RuleAction::RemoveCategory: actName = QString("Quitar categoría %1").arg(act.value); break;
            case RuleAction::ForwardTo: actName = QString("Reenviar a %1").arg(act.value); break;
            case RuleAction::SetPriority: actName = QString("Prioridad %1").arg(act.value); break;
            case RuleAction::StopProcessing: actName = "Detener procesamiento"; break;
        }
        actTexts.append(actName);
    }
    item->setText(4, actTexts.join(", "));
    
    item->setText(5, rule.isGlobal() ? tr("Global") : QString::number(rule.accountId));
    item->setText(6, rule.lastRun.isValid() ? rule.lastRun.toString("dd/MM/yyyy hh:mm") : tr("Nunca"));
    item->setText(7, QString::number(rule.runCount));
    
    if (!rule.enabled) {
        for (int i = 0; i < m_tree->columnCount(); ++i) {
            item->setForeground(i, QBrush(QColor("#999")));
        }
    }
}

Rule RulesManagerDialog::itemToRule(QTreeWidgetItem* item) const
{
    qint64 id = item->data(0, Qt::UserRole).toLongLong();
    auto ruleOpt = RuleDao::findById(id);
    return ruleOpt.value_or(Rule());
}

void RulesManagerDialog::onNewRule()
{
    RuleEditorDialog dlg(Rule(), m_accountId, this);
    connect(&dlg, &RuleEditorDialog::ruleSaved, this, &RulesManagerDialog::onRuleSaved);
    dlg.exec();
}

void RulesManagerDialog::onEditRule(QTreeWidgetItem* item)
{
    Rule rule = itemToRule(item);
    if (!rule.isValid()) return;
    
    RuleEditorDialog dlg(rule, m_accountId, this);
    connect(&dlg, &RuleEditorDialog::ruleSaved, this, &RulesManagerDialog::onRuleSaved);
    dlg.exec();
}

void RulesManagerDialog::onRuleSaved(const Rule& rule)
{
    refresh();
    emit rulesChanged();
}

void RulesManagerDialog::onDeleteRule(QTreeWidgetItem* item)
{
    Rule rule = itemToRule(item);
    if (!rule.isValid()) return;
    
    if (QMessageBox::question(this, tr("Eliminar regla"), 
        tr("¿Eliminar la regla \"%1\"?").arg(rule.name),
        QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
        if (RuleDao::remove(rule.id)) {
            refresh();
            emit rulesChanged();
        }
    }
}

void RulesManagerDialog::onToggleEnabled(QTreeWidgetItem* item)
{
    Rule rule = itemToRule(item);
    if (!rule.isValid()) return;
    
    bool newState = item->checkState(0) != Qt::Checked;
    if (RuleDao::setEnabled(rule.id, newState)) {
        item->setCheckState(0, newState ? Qt::Checked : Qt::Unchecked);
        if (!newState) {
            for (int i = 0; i < m_tree->columnCount(); ++i) {
                item->setForeground(i, QBrush(QColor("#999")));
            }
        } else {
            for (int i = 0; i < m_tree->columnCount(); ++i) {
                item->setForeground(i, QBrush(QColor("#000")));
            }
        }
        emit rulesChanged();
    }
}

void RulesManagerDialog::onRunRules()
{
    // TODO: Get selected folder/account from main window
    QMessageBox::information(this, tr("Ejecutar reglas"), tr("Seleccione una carpeta en la ventana principal y pulse 'Ejecutar reglas' en el menú de herramientas."));
}

void RulesManagerDialog::onImportExport(bool import)
{
    if (import) {
        QString file = QFileDialog::getOpenFileName(this, tr("Importar reglas"), QString(), tr("JSON (*.json)"));
        if (file.isEmpty()) return;
        
        // TODO: Parse JSON and create rules
        QMessageBox::information(this, tr("Importar"), tr("Función de importación en desarrollo."));
    } else {
        QString file = QFileDialog::getSaveFileName(this, tr("Exportar reglas"), "rules.json", tr("JSON (*.json)"));
        if (file.isEmpty()) return;
        
        QVector<Rule> rules = RuleDao::findByAccount(m_accountId);
        QJsonArray arr;
        for (const Rule& rule : rules) arr.append(rule.toJson());
        
        QJsonDocument doc(arr);
        QFile f(file);
        if (f.open(QIODevice::WriteOnly)) {
            f.write(doc.toJson(QJsonDocument::Indented));
            QMessageBox::information(this, tr("Exportar"), tr("Reglas exportadas a %1").arg(file));
        }
    }
}

void RulesManagerDialog::refresh()
{
    loadRules();
}