#include "settingsdialog.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFileInfo>
#include <QStandardPaths>
#include <QIntValidator>

// Define static constants
const QString SettingsDialog::DEFAULT_SCREENSHOTS_DIR = QDir::homePath() + "/Screenshots";
const QString SettingsDialog::DEFAULT_DATABASE_FILENAME = "screenshot_ocr.db";
const QString SettingsDialog::CONFIG_FILE_PATH = QDir::homePath() + "/.config/ScreenshotOCRGallery/settings.ini";

SettingsDialog::SettingsDialog(QWidget *parent)
    : QDialog(parent)
{
    setWindowTitle(tr("Settings"));
    setMinimumWidth(500);
    
    // Create UI elements
    createLayout();
    
    // Load saved settings
    loadSettings();
    
    // Connect signals and slots
    connect(m_browseScreenshotsDirBtn, &QPushButton::clicked, this, &SettingsDialog::handleBrowseScreenshotsDir);
    connect(m_browseDatabaseBtn, &QPushButton::clicked, this, &SettingsDialog::handleBrowseDatabase);
    connect(m_buttonBox, &QDialogButtonBox::accepted, this, &SettingsDialog::handleAccepted);
    connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
}

SettingsDialog::~SettingsDialog()
{
    // Qt will handle cleanup of UI elements through parent-child relationships
}

void SettingsDialog::createLayout()
{
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    QGridLayout *formLayout = new QGridLayout();
    
    // Ensure config directory exists
    QFileInfo configFile(CONFIG_FILE_PATH);
    QDir configDir = configFile.absoluteDir();
    if (!configDir.exists()) {
        configDir.mkpath(".");
    }
    
    // Screenshots directory row
    QLabel *screenshotsDirLabel = new QLabel(tr("Screenshots Directory:"), this);
    m_screenshotsDirEdit = new QLineEdit(this);
    m_browseScreenshotsDirBtn = new QPushButton(tr("..."), this);
    m_browseScreenshotsDirBtn->setMaximumWidth(40);
    
    formLayout->addWidget(screenshotsDirLabel, 0, 0);
    formLayout->addWidget(m_screenshotsDirEdit, 0, 1);
    formLayout->addWidget(m_browseScreenshotsDirBtn, 0, 2);
    
    // Database path row
    QLabel *databasePathLabel = new QLabel(tr("Database File Path:"), this);
    m_databasePathEdit = new QLineEdit(this);
    m_browseDatabaseBtn = new QPushButton(tr("..."), this);
    m_browseDatabaseBtn->setMaximumWidth(40);
    
    formLayout->addWidget(databasePathLabel, 1, 0);
    formLayout->addWidget(m_databasePathEdit, 1, 1);
    formLayout->addWidget(m_browseDatabaseBtn, 1, 2);
    
    // Preload count row
    QLabel *preloadCountLabel = new QLabel(tr("Images to pre-load:"), this);
    m_imagePreloadCountEdit = new QLineEdit(this);
    m_imagePreloadCountEdit->setValidator(new QIntValidator(1, 100, this));
    
    formLayout->addWidget(preloadCountLabel, 2, 0);
    formLayout->addWidget(m_imagePreloadCountEdit, 2, 1);
    
    // Help text
    QLabel *helpText = new QLabel(tr("Note: If no filename is provided for the database path, "
                                   "'screenshot_ocr.db' will be used automatically."), this);
    helpText->setWordWrap(true);
    helpText->setStyleSheet("color: #666; font-size: 11px;");
    
    // Button box
    m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
    
    // Add to main layout
    mainLayout->addLayout(formLayout);
    mainLayout->addWidget(helpText);
    mainLayout->addSpacing(10);
    mainLayout->addWidget(m_buttonBox);
    
    setLayout(mainLayout);
}

void SettingsDialog::handleBrowseScreenshotsDir()
{
    QString dir = QFileDialog::getExistingDirectory(
        this, tr("Select Screenshots Directory"),
        m_screenshotsDirEdit->text().isEmpty() ? QDir::homePath() : m_screenshotsDirEdit->text(),
        QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    
    if (!dir.isEmpty()) {
        m_screenshotsDirEdit->setText(dir);
    }
}

void SettingsDialog::handleBrowseDatabase()
{
    QString currentPath = m_databasePathEdit->text();
    if (currentPath.isEmpty()) {
        currentPath = QDir::homePath();
    } else {
        QFileInfo fileInfo(currentPath);
        if (fileInfo.isFile()) {
            currentPath = fileInfo.absolutePath();
        }
    }
    
    QString filePath = QFileDialog::getSaveFileName(
        this, tr("Select Database File"),
        currentPath,
        tr("SQLite Database (*.db);;All Files (*)"));
    
    if (!filePath.isEmpty()) {
        m_databasePathEdit->setText(filePath);
    }
}

void SettingsDialog::handleAccepted()
{
    // Validate settings
    QDir screenshotsDir(m_screenshotsDirEdit->text());
    if (!screenshotsDir.exists()) {
        // Ask if we should create the directory
        QMessageBox::StandardButton reply = QMessageBox::question(
            this, tr("Directory Not Found"),
            tr("The screenshots directory does not exist. Create it?"),
            QMessageBox::Yes | QMessageBox::No);
        
        if (reply == QMessageBox::Yes) {
            if (!screenshotsDir.mkpath(".")) {
                QMessageBox::warning(this, tr("Error"),
                                    tr("Failed to create directory: %1").arg(screenshotsDir.path()));
                return;
            }
        } else {
            // User chose not to create directory
            return;
        }
    }
    
    // Ensure database path has a filename
    m_databasePathEdit->setText(ensureDatabaseFilename(m_databasePathEdit->text()));
    
    // Check if database directory exists
    QFileInfo dbFileInfo(m_databasePathEdit->text());
    QDir dbDir = dbFileInfo.absoluteDir();
    
    if (!dbDir.exists()) {
        QMessageBox::StandardButton reply = QMessageBox::question(
            this, tr("Directory Not Found"),
            tr("The database directory does not exist. Create it?"),
            QMessageBox::Yes | QMessageBox::No);
        
        if (reply == QMessageBox::Yes) {
            if (!dbDir.mkpath(".")) {
                QMessageBox::warning(this, tr("Error"),
                                    tr("Failed to create directory: %1").arg(dbDir.path()));
                return;
            }
        } else {
            // User chose not to create directory
            return;
        }
    }
    
    // Save settings
    saveSettings();
    
    // Accept dialog
    accept();
}

QString SettingsDialog::getScreenshotsDir() const
{
    return m_screenshotsDirEdit->text();
}

QString SettingsDialog::getDatabasePath() const
{
    return m_databasePathEdit->text();
}

void SettingsDialog::loadSettings()
{
    QSettings settings(CONFIG_FILE_PATH, QSettings::IniFormat);
    
    // Load screenshots directory
    QString screenshotsDir = settings.value("screenshotsDir", DEFAULT_SCREENSHOTS_DIR).toString();
    m_screenshotsDirEdit->setText(screenshotsDir);
    
    // Load database path
    const QString defaultDbPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
                                  + "/" + DEFAULT_DATABASE_FILENAME;
    QString databasePath = settings.value("databasePath", defaultDbPath).toString();
    m_databasePathEdit->setText(databasePath);
    
    // Load preload count
    int preloadCount = settings.value("imagePreloadCount", DEFAULT_PRELOAD_COUNT).toInt();
    m_imagePreloadCountEdit->setText(QString::number(preloadCount));
}

void SettingsDialog::saveSettings()
{
    QSettings settings(CONFIG_FILE_PATH, QSettings::IniFormat);
    
    // Save screenshots directory
    settings.setValue("screenshotsDir", getScreenshotsDir());
    
    // Save database path
    settings.setValue("databasePath", getDatabasePath());
    
    // Save preload count
    settings.setValue("imagePreloadCount", getImagePreloadCount());
    
    settings.sync();
}

int SettingsDialog::getImagePreloadCount() const
{
    bool ok;
    int count = m_imagePreloadCountEdit->text().toInt(&ok);
    
    // Return the default if conversion fails or value is invalid
    if (!ok || count < 1) {
        return DEFAULT_PRELOAD_COUNT;
    }
    
    return count;
}

QString SettingsDialog::ensureDatabaseFilename(const QString &path)
{
    if (path.isEmpty()) {
        // If path is empty, use default in home directory
        return QDir::homePath() + "/" + DEFAULT_DATABASE_FILENAME;
    }
    
    QFileInfo fileInfo(path);
    if (fileInfo.isDir()) {
        // If path is a directory, append default filename
        QString dirPath = path;
        // Ensure path ends with a separator
        if (!dirPath.endsWith('/') && !dirPath.endsWith('\\')) {
            dirPath += '/';
        }
        return dirPath + DEFAULT_DATABASE_FILENAME;
    }
    
    // If path already has a filename component, use it as is
    return path;
}