#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 <QHBoxLayout>
#include <QVBoxLayout>
#include <QFormLayout>
#include <QTableWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QSpinBox>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QGroupBox>
#include <QDebug>

RuleEditorDialog::RuleEditorDialog(const Rule& rule, qint64 accountId, QWidget *parent)
    : QDialog(parent), m_rule(rule), m_accountId(accountId)
{
    setWindowTitle(rule.isValid() ? tr("Editar regla") : tr("Nueva regla"));
    resize(800, 600);
    setupUI();
    populateFromRule();
}

void RuleEditorDialog::setupUI()
{
    QVBoxLayout* mainLayout = new QVBoxLayout(this);
    
    // Form header
    QGroupBox* headerGroup = new QGroupBox(tr("Información básica"));
    QFormLayout* headerLayout = new QFormLayout(headerGroup);
    
    m_nameEdit = new QLineEdit();
    m_nameEdit->setPlaceholderText(tr("Nombre de la regla"));
    headerLayout->addRow(tr("Nombre:"), m_nameEdit);
    
    m_descEdit = new QTextEdit();
    m_descEdit->setMaximumHeight(60);
    m_descEdit->setPlaceholderText(tr("Descripción opcional"));
    headerLayout->addRow(tr("Descripción:"), m_descEdit);
    
    m_accountCombo = new QComboBox();
    loadAccounts();
    headerLayout->addRow(tr("Cuenta:"), m_accountCombo);
    
    QHBoxLayout* optionsLayout = new QHBoxLayout();
    m_enabledCheck = new QCheckBox(tr("Activada"));
    m_enabledCheck->setChecked(true);
    m_matchAllCheck = new QCheckBox(tr("Todas las condiciones (Y)"));
    m_matchAllCheck->setChecked(true);
    m_matchAllCheck->setToolTip(tr("Desactivar = Cualquier condición (O)"));
    m_prioritySpin = new QSpinBox();
    m_prioritySpin->setRange(1, 999);
    m_prioritySpin->setValue(100);
    m_prioritySpin->setToolTip(tr("Menor = mayor prioridad"));
    
    optionsLayout->addWidget(m_enabledCheck);
    optionsLayout->addWidget(m_matchAllCheck);
    optionsLayout->addStretch();
    optionsLayout->addWidget(new QLabel(tr("Prioridad:")));
    optionsLayout->addWidget(m_prioritySpin);
    headerLayout->addRow(optionsLayout);
    
    mainLayout->addWidget(headerGroup);
    
    // Conditions table
    QGroupBox* condGroup = new QGroupBox(tr("Condiciones"));
    QVBoxLayout* condLayout = new QVBoxLayout(condGroup);
    
    m_conditionsTable = new QTableWidget();
    m_conditionsTable->setColumnCount(5);
    m_conditionsTable->setHorizontalHeaderLabels({tr("Campo"), tr("Operador"), tr("Valor"), tr("Mayúsculas"), ""});
    m_conditionsTable->horizontalHeader()->setStretchLastSection(true);
    m_conditionsTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
    m_conditionsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_conditionsTable->verticalHeader()->setVisible(false);
    condLayout->addWidget(m_conditionsTable);
    
    QHBoxLayout* condBtnLayout = new QHBoxLayout();
    QPushButton* btnAddCond = new QPushButton(tr("+ Añadir condición"));
    btnAddCond->setStyleSheet("QPushButton { background: #1976D2; color: white; padding: 6px 12px; border-radius: 4px; }");
    connect(btnAddCond, &QPushButton::clicked, this, &RuleEditorDialog::onAddCondition);
    QPushButton* btnRemCond = new QPushButton(tr("- Eliminar"));
    connect(btnRemCond, &QPushButton::clicked, this, &RuleEditorDialog::onRemoveCondition);
    condBtnLayout->addWidget(btnAddCond);
    condBtnLayout->addWidget(btnRemCond);
    condBtnLayout->addStretch();
    condLayout->addLayout(condBtnLayout);
    
    mainLayout->addWidget(condGroup, 1);
    
    // Actions table
    QGroupBox* actGroup = new QGroupBox(tr("Acciones"));
    QVBoxLayout* actLayout = new QVBoxLayout(actGroup);
    
    m_actionsTable = new QTableWidget();
    m_actionsTable->setColumnCount(4);
    m_actionsTable->setHorizontalHeaderLabels({tr("Tipo"), tr("Parámetro"), tr("Detalles"), ""});
    m_actionsTable->horizontalHeader()->setStretchLastSection(true);
    m_actionsTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
    m_actionsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_actionsTable->verticalHeader()->setVisible(false);
    actLayout->addWidget(m_actionsTable);
    
    QHBoxLayout* actBtnLayout = new QHBoxLayout();
    QPushButton* btnAddAct = new QPushButton(tr("+ Añadir acción"));
    btnAddAct->setStyleSheet("QPushButton { background: #4CAF50; color: white; padding: 6px 12px; border-radius: 4px; }");
    connect(btnAddAct, &QPushButton::clicked, this, &RuleEditorDialog::onAddAction);
    QPushButton* btnRemAct = new QPushButton(tr("- Eliminar"));
    connect(btnRemAct, &QPushButton::clicked, this, &RuleEditorDialog::onRemoveAction);
    actBtnLayout->addWidget(btnAddAct);
    actBtnLayout->addWidget(btnRemAct);
    actBtnLayout->addStretch();
    actLayout->addLayout(actBtnLayout);
    
    mainLayout->addWidget(actGroup, 1);
    
    // Buttons
    QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    connect(buttonBox, &QDialogButtonBox::accepted, this, &RuleEditorDialog::onAccept);
    connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
    mainLayout->addWidget(buttonBox);
}

void RuleEditorDialog::loadAccounts()
{
    m_accountCombo->clear();
    m_accountCombo->addItem(tr("Global (todas las cuentas)"), -1);
    
    // Get accounts via AccountService (singleton doesn't have instance(), use parent's accountService)
    // For now, we'll just add the global option and let the main window handle account-specific rules
    if (m_accountId >= 0) {
        int idx = m_accountCombo->findData(m_accountId);
        if (idx >= 0) m_accountCombo->setCurrentIndex(idx);
    }
}

void RuleEditorDialog::populateFromRule()
{
    if (!m_rule.isValid()) return;
    
    m_nameEdit->setText(m_rule.name);
    m_descEdit->setPlainText(m_rule.description);
    m_enabledCheck->setChecked(m_rule.enabled);
    m_matchAllCheck->setChecked(m_rule.matchAll);
    m_prioritySpin->setValue(m_rule.priority);
    
    int idx = m_accountCombo->findData(m_rule.accountId >= 0 ? m_rule.accountId : -1);
    if (idx >= 0) m_accountCombo->setCurrentIndex(idx);
    
    for (const RuleCondition& cond : m_rule.conditions) {
        int row = m_conditionsTable->rowCount();
        m_conditionsTable->insertRow(row);
        setupConditionRow(row, cond);
    }
    
    for (const RuleAction& act : m_rule.actions) {
        int row = m_actionsTable->rowCount();
        m_actionsTable->insertRow(row);
        setupActionRow(row, act);
    }
}

void RuleEditorDialog::setupConditionRow(int row, const RuleCondition& cond)
{
    // Field combo
    QComboBox* fieldCombo = new QComboBox();
    fieldCombo->addItem(tr("De"), RuleCondition::From);
    fieldCombo->addItem(tr("Para"), RuleCondition::To);
    fieldCombo->addItem(tr("CC"), RuleCondition::Cc);
    fieldCombo->addItem(tr("Asunto"), RuleCondition::Subject);
    fieldCombo->addItem(tr("Cuerpo"), RuleCondition::Body);
    fieldCombo->addItem(tr("Tiene adjuntos"), RuleCondition::HasAttachment);
    fieldCombo->addItem(tr("Tamaño"), RuleCondition::Size);
    fieldCombo->addItem(tr("Fecha"), RuleCondition::Date);
    fieldCombo->addItem(tr("Marcado"), RuleCondition::Flagged);
    fieldCombo->addItem(tr("Leído"), RuleCondition::Read);
    fieldCombo->setCurrentIndex(fieldCombo->findData(cond.field));
    connect(fieldCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), 
            [this, row](int) { onConditionFieldChanged(row); });
    m_conditionsTable->setCellWidget(row, 0, fieldCombo);
    
    // Operator combo
    QComboBox* opCombo = new QComboBox();
    opCombo->addItem(tr("Contiene"), RuleCondition::Contains);
    opCombo->addItem(tr("No contiene"), RuleCondition::NotContains);
    opCombo->addItem(tr("Es igual a"), RuleCondition::Equals);
    opCombo->addItem(tr("No es igual a"), RuleCondition::NotEquals);
    opCombo->addItem(tr("Empieza por"), RuleCondition::StartsWith);
    opCombo->addItem(tr("Termina en"), RuleCondition::EndsWith);
    opCombo->addItem(tr("Expresión regular"), RuleCondition::Regex);
    opCombo->addItem(tr("Mayor que"), RuleCondition::GreaterThan);
    opCombo->addItem(tr("Menor que"), RuleCondition::LessThan);
    opCombo->addItem(tr("Antes de"), RuleCondition::Before);
    opCombo->addItem(tr("Después de"), RuleCondition::After);
    opCombo->setCurrentIndex(opCombo->findData(cond.op));
    m_conditionsTable->setCellWidget(row, 1, opCombo);
    
    // Value edit
    QLineEdit* valueEdit = new QLineEdit(cond.value);
    m_conditionsTable->setCellWidget(row, 2, valueEdit);
    
    // Case sensitive checkbox
    QCheckBox* caseCheck = new QCheckBox();
    caseCheck->setChecked(cond.caseSensitive);
    caseCheck->setStyleSheet("QCheckBox { margin-left: 50%; }");
    m_conditionsTable->setCellWidget(row, 3, caseCheck);
    
    // Remove button
    QPushButton* removeBtn = new QPushButton("✕");
    removeBtn->setFixedSize(24, 24);
    removeBtn->setToolTip(tr("Eliminar condición"));
    removeBtn->setStyleSheet("QPushButton { background: transparent; color: #d32f2f; border: none; font-weight: bold; } QPushButton:hover { background: #fdeaea; border-radius: 3px; }");
    connect(removeBtn, &QPushButton::clicked, [this, row]() {
        m_conditionsTable->removeRow(row);
    });
    m_conditionsTable->setCellWidget(row, 4, removeBtn);
    
    onConditionFieldChanged(row);
}

void RuleEditorDialog::onConditionFieldChanged(int row)
{
    QComboBox* fieldCombo = qobject_cast<QComboBox*>(m_conditionsTable->cellWidget(row, 0));
    QComboBox* opCombo = qobject_cast<QComboBox*>(m_conditionsTable->cellWidget(row, 1));
    QLineEdit* valueEdit = qobject_cast<QLineEdit*>(m_conditionsTable->cellWidget(row, 2));
    QCheckBox* caseCheck = qobject_cast<QCheckBox*>(m_conditionsTable->cellWidget(row, 3));
    
    if (!fieldCombo || !opCombo) return;
    
    RuleCondition::Field field = static_cast<RuleCondition::Field>(fieldCombo->currentData().toInt());
    
    // Clear and repopulate operators based on field type
    opCombo->clear();
    
    bool isTextField = (field == RuleCondition::From || field == RuleCondition::To || 
                       field == RuleCondition::Cc || field == RuleCondition::Subject || 
                       field == RuleCondition::Body);
    bool isBooleanField = (field == RuleCondition::HasAttachment || field == RuleCondition::Flagged || field == RuleCondition::Read);
    bool isNumericField = (field == RuleCondition::Size);
    bool isDateField = (field == RuleCondition::Date);
    
    if (isTextField) {
        opCombo->addItem(tr("Contiene"), RuleCondition::Contains);
        opCombo->addItem(tr("No contiene"), RuleCondition::NotContains);
        opCombo->addItem(tr("Es igual a"), RuleCondition::Equals);
        opCombo->addItem(tr("No es igual a"), RuleCondition::NotEquals);
        opCombo->addItem(tr("Empieza por"), RuleCondition::StartsWith);
        opCombo->addItem(tr("Termina en"), RuleCondition::EndsWith);
        opCombo->addItem(tr("Expresión regular"), RuleCondition::Regex);
        valueEdit->setPlaceholderText(tr("Texto a buscar..."));
        caseCheck->setVisible(true);
    } else if (isBooleanField) {
        opCombo->addItem(tr("Es"), RuleCondition::Equals);
        opCombo->addItem(tr("No es"), RuleCondition::NotEquals);
        valueEdit->setPlaceholderText("true/false");
        valueEdit->setText("true");
        caseCheck->setVisible(false);
    } else if (isNumericField) {
        opCombo->addItem(tr("Mayor que"), RuleCondition::GreaterThan);
        opCombo->addItem(tr("Menor que"), RuleCondition::LessThan);
        opCombo->addItem(tr("Es igual a"), RuleCondition::Equals);
        valueEdit->setPlaceholderText("Tamaño en bytes");
        caseCheck->setVisible(false);
    } else if (isDateField) {
        opCombo->addItem(tr("Antes de"), RuleCondition::Before);
        opCombo->addItem(tr("Después de"), RuleCondition::After);
        opCombo->addItem(tr("Es igual a"), RuleCondition::Equals);
        valueEdit->setPlaceholderText("YYYY-MM-DD");
        caseCheck->setVisible(false);
    }
}

void RuleEditorDialog::setupActionRow(int row, const RuleAction& act)
{
    // Type combo
    QComboBox* typeCombo = new QComboBox();
    typeCombo->addItem(tr("Mover a carpeta"), RuleAction::MoveToFolder);
    typeCombo->addItem(tr("Marcar como leído/no leído"), RuleAction::MarkAsRead);
    typeCombo->addItem(tr("Marcar/Desmarcar"), RuleAction::MarkAsFlagged);
    typeCombo->addItem(tr("Eliminar"), RuleAction::Delete);
    typeCombo->addItem(tr("Asignar categoría"), RuleAction::AssignCategory);
    typeCombo->addItem(tr("Quitar categoría"), RuleAction::RemoveCategory);
    typeCombo->addItem(tr("Reenviar a"), RuleAction::ForwardTo);
    typeCombo->addItem(tr("Establecer prioridad"), RuleAction::SetPriority);
    typeCombo->addItem(tr("Detener procesamiento"), RuleAction::StopProcessing);
    typeCombo->setCurrentIndex(typeCombo->findData(act.type));
    connect(typeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), 
            [this, row](int) { onActionTypeChanged(row); });
    m_actionsTable->setCellWidget(row, 0, typeCombo);
    
    // Parameter edit (dynamic based on type)
    QWidget* paramWidget = createParameterWidget(act);
    m_actionsTable->setCellWidget(row, 1, paramWidget);
    
    // Details label
    QLabel* detailsLabel = new QLabel();
    detailsLabel->setStyleSheet("color: #666; font-size: 11px;");
    updateActionDetails(act, detailsLabel);
    m_actionsTable->setCellWidget(row, 2, detailsLabel);
    
    // Remove button
    QPushButton* removeBtn = new QPushButton("✕");
    removeBtn->setFixedSize(24, 24);
    removeBtn->setToolTip(tr("Eliminar acción"));
    removeBtn->setStyleSheet("QPushButton { background: transparent; color: #d32f2f; border: none; font-weight: bold; } QPushButton:hover { background: #fdeaea; border-radius: 3px; }");
    connect(removeBtn, &QPushButton::clicked, [this, row]() {
        m_actionsTable->removeRow(row);
    });
    m_actionsTable->setCellWidget(row, 3, removeBtn);
}

QWidget* RuleEditorDialog::createParameterWidget(const RuleAction& act)
{
    QWidget* container = new QWidget();
    QHBoxLayout* layout = new QHBoxLayout(container);
    layout->setContentsMargins(0, 0, 0, 0);
    
    switch (act.type) {
        case RuleAction::MoveToFolder: {
            QComboBox* folderCombo = new QComboBox();
            folderCombo->addItem(tr("Seleccionar carpeta..."), -1);
            // Load folders from database
            QSqlDatabase db = DatabaseManager::instance().database();
            QSqlQuery query(db);
            query.exec("SELECT id, name FROM Folder ORDER BY name");
            while (query.next()) {
                folderCombo->addItem(query.value(1).toString(), query.value(0).toLongLong());
            }
            if (act.value.toLongLong() > 0) {
                int idx = folderCombo->findData(act.value.toLongLong());
                if (idx >= 0) folderCombo->setCurrentIndex(idx);
            }
            layout->addWidget(folderCombo, 1);
            break;
        }
        case RuleAction::MarkAsRead: {
            QComboBox* combo = new QComboBox();
            combo->addItem(tr("Leído"), "true");
            combo->addItem(tr("No leído"), "false");
            combo->setCurrentIndex(combo->findData(act.value));
            layout->addWidget(combo, 1);
            break;
        }
        case RuleAction::MarkAsFlagged: {
            QComboBox* combo = new QComboBox();
            combo->addItem(tr("Marcado"), "true");
            combo->addItem(tr("No marcado"), "false");
            combo->setCurrentIndex(combo->findData(act.value));
            layout->addWidget(combo, 1);
            break;
        }
        case RuleAction::AssignCategory:
        case RuleAction::RemoveCategory: {
            QComboBox* catCombo = new QComboBox();
            catCombo->addItem(tr("Seleccionar categoría..."), -1);
            QVector<Category> cats = CategoryDao::findAll();
            for (const Category& cat : cats) {
                catCombo->addItem(cat.name, cat.id);
            }
            if (act.value.toLongLong() > 0) {
                int idx = catCombo->findData(act.value.toLongLong());
                if (idx >= 0) catCombo->setCurrentIndex(idx);
            }
            layout->addWidget(catCombo, 1);
            break;
        }
        case RuleAction::ForwardTo: {
            QLineEdit* edit = new QLineEdit(act.value);
            edit->setPlaceholderText("email@dominio.com");
            layout->addWidget(edit, 1);
            break;
        }
        case RuleAction::SetPriority: {
            QComboBox* combo = new QComboBox();
            combo->addItem(tr("Alta"), "high");
            combo->addItem(tr("Normal"), "normal");
            combo->addItem(tr("Baja"), "low");
            combo->setCurrentIndex(combo->findData(act.value));
            layout->addWidget(combo, 1);
            break;
        }
        case RuleAction::Delete:
        case RuleAction::StopProcessing:
        default: {
            QLabel* label = new QLabel(tr("(sin parámetros)"));
            label->setStyleSheet("color: #999; font-style: italic;");
            layout->addWidget(label, 1);
            break;
        }
    }
    
    return container;
}

void RuleEditorDialog::updateActionDetails(const RuleAction& act, QLabel* label)
{
    QString details;
    switch (act.type) {
        case RuleAction::MoveToFolder:
            details = tr("Mueve el correo a la carpeta seleccionada");
            break;
        case RuleAction::MarkAsRead:
            details = tr("Cambia el estado de lectura del correo");
            break;
        case RuleAction::MarkAsFlagged:
            details = tr("Cambia el estado de marcado/estrella");
            break;
        case RuleAction::Delete:
            details = tr("Elimina el correo permanentemente");
            break;
        case RuleAction::AssignCategory:
            details = tr("Añade la categoría al correo");
            break;
        case RuleAction::RemoveCategory:
            details = tr("Quita la categoría del correo");
            break;
        case RuleAction::ForwardTo:
            details = tr("Reenvía el correo a la dirección indicada");
            break;
        case RuleAction::SetPriority:
            details = tr("Marca el correo como alta prioridad (flagged)");
            break;
        case RuleAction::StopProcessing:
            details = tr("Detiene la evaluación de más reglas para este correo");
            break;
    }
    label->setText(details);
}

void RuleEditorDialog::onActionTypeChanged(int row)
{
    QComboBox* typeCombo = qobject_cast<QComboBox*>(m_actionsTable->cellWidget(row, 0));
    if (!typeCombo) return;
    
    RuleAction::Type type = static_cast<RuleAction::Type>(typeCombo->currentData().toInt());
    
    // Replace parameter widget
    QWidget* oldWidget = m_actionsTable->cellWidget(row, 1);
    if (oldWidget) oldWidget->deleteLater();
    
    RuleAction act;
    act.type = type;
    QWidget* newWidget = createParameterWidget(act);
    m_actionsTable->setCellWidget(row, 1, newWidget);
    
    // Update details
    QLabel* detailsLabel = qobject_cast<QLabel*>(m_actionsTable->cellWidget(row, 2));
    if (detailsLabel) updateActionDetails(act, detailsLabel);
}

void RuleEditorDialog::onAddCondition()
{
    int row = m_conditionsTable->rowCount();
    m_conditionsTable->insertRow(row);
    setupConditionRow(row);
}

void RuleEditorDialog::onRemoveCondition()
{
    int row = m_conditionsTable->currentRow();
    if (row >= 0) {
        m_conditionsTable->removeRow(row);
    }
}

void RuleEditorDialog::onAddAction()
{
    int row = m_actionsTable->rowCount();
    m_actionsTable->insertRow(row);
    setupActionRow(row);
}

void RuleEditorDialog::onRemoveAction()
{
    int row = m_actionsTable->currentRow();
    if (row >= 0) {
        m_actionsTable->removeRow(row);
    }
}

RuleCondition RuleEditorDialog::conditionFromRow(int row) const
{
    RuleCondition cond;
    QComboBox* fieldCombo = qobject_cast<QComboBox*>(m_conditionsTable->cellWidget(row, 0));
    QComboBox* opCombo = qobject_cast<QComboBox*>(m_conditionsTable->cellWidget(row, 1));
    QLineEdit* valueEdit = qobject_cast<QLineEdit*>(m_conditionsTable->cellWidget(row, 2));
    QCheckBox* caseCheck = qobject_cast<QCheckBox*>(m_conditionsTable->cellWidget(row, 3));
    
    if (fieldCombo) cond.field = static_cast<RuleCondition::Field>(fieldCombo->currentData().toInt());
    if (opCombo) cond.op = static_cast<RuleCondition::Operator>(opCombo->currentData().toInt());
    if (valueEdit) cond.value = valueEdit->text();
    if (caseCheck) cond.caseSensitive = caseCheck->isChecked();
    
    return cond;
}

RuleAction RuleEditorDialog::actionFromRow(int row) const
{
    RuleAction act;
    QComboBox* typeCombo = qobject_cast<QComboBox*>(m_actionsTable->cellWidget(row, 0));
    QWidget* paramWidget = m_actionsTable->cellWidget(row, 1);
    
    if (typeCombo) act.type = static_cast<RuleAction::Type>(typeCombo->currentData().toInt());
    
    if (!paramWidget) return act;
    
    // Extract value based on action type
    if (act.type == RuleAction::MoveToFolder || 
        act.type == RuleAction::AssignCategory || 
        act.type == RuleAction::RemoveCategory) {
        QComboBox* combo = paramWidget->findChild<QComboBox*>();
        if (combo && combo->currentData().toLongLong() > 0) {
            act.value = QString::number(combo->currentData().toLongLong());
        }
    } else if (act.type == RuleAction::MarkAsRead || 
               act.type == RuleAction::MarkAsFlagged ||
               act.type == RuleAction::SetPriority) {
        QComboBox* combo = paramWidget->findChild<QComboBox*>();
        if (combo) act.value = combo->currentData().toString();
    } else if (act.type == RuleAction::ForwardTo) {
        QLineEdit* edit = paramWidget->findChild<QLineEdit*>();
        if (edit) act.value = edit->text();
    }
    
    return act;
}

void RuleEditorDialog::onAccept()
{
    if (m_nameEdit->text().trimmed().isEmpty()) {
        QMessageBox::warning(this, tr("Error"), tr("El nombre de la regla es obligatorio."));
        m_nameEdit->setFocus();
        return;
    }
    
    m_rule.name = m_nameEdit->text().trimmed();
    m_rule.description = m_descEdit->toPlainText().trimmed();
    m_rule.enabled = m_enabledCheck->isChecked();
    m_rule.matchAll = m_matchAllCheck->isChecked();
    m_rule.priority = m_prioritySpin->value();
    m_rule.accountId = m_accountCombo->currentData().toLongLong();
    if (m_rule.accountId < 0) m_rule.accountId = -1;
    
    m_rule.conditions.clear();
    for (int i = 0; i < m_conditionsTable->rowCount(); ++i) {
        m_rule.conditions.append(conditionFromRow(i));
    }
    
    m_rule.actions.clear();
    for (int i = 0; i < m_actionsTable->rowCount(); ++i) {
        m_rule.actions.append(actionFromRow(i));
    }
    
    m_rule.updatedAt = QDateTime::currentDateTime();
    
    if (m_rule.isValid()) {
        if (RuleDao::update(m_rule)) {
            emit ruleSaved(m_rule);
            accept();
        } else {
            QMessageBox::critical(this, tr("Error"), tr("No se pudo actualizar la regla."));
        }
    } else {
        if (RuleDao::insert(m_rule)) {
            emit ruleSaved(m_rule);
            accept();
        } else {
            QMessageBox::critical(this, tr("Error"), tr("No se pudo crear la regla."));
        }
    }
}