#include "urldatabase.h"

ImageUrlDatabase::ImageUrlDatabase(QObject *parent) : QObject(parent)
{
}

ImageUrlDatabase::~ImageUrlDatabase()
{
    if (m_db.isOpen()) {
        m_db.close();
    }
}

bool ImageUrlDatabase::openDatabase(const QString &path)
{
    m_db = QSqlDatabase::addDatabase("QSQLITE");
    m_db.setDatabaseName(path);

    if (!m_db.open()) {
        qWarning() << "Failed to open database:" << m_db.lastError().text();
        return false;
    }

    // 创建表结构
    QSqlQuery query;

    // 创建用户表
    if (!query.exec("CREATE TABLE IF NOT EXISTS users ("
                    "user_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                    "username TEXT NOT NULL UNIQUE, "
                    "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)")) {
        qWarning() << "Failed to create users table:" << query.lastError().text();
        return false;
    }

    // 创建服务器表
    if (!query.exec("CREATE TABLE IF NOT EXISTS servers ("
                    "server_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                    "domain TEXT NOT NULL UNIQUE, "
                    "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)")) {
        qWarning() << "Failed to create servers table:" << query.lastError().text();
        return false;
    }

    // 创建图片URL表
    if (!query.exec("CREATE TABLE IF NOT EXISTS image_urls ("
                    "url_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                    "user_id INTEGER NOT NULL, "
                    "server_id INTEGER NOT NULL, "
                    "image_url TEXT NOT NULL, "
                    "last_accessed TIMESTAMP, "
                    "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
                    "FOREIGN KEY (user_id) REFERENCES users(user_id), "
                    "FOREIGN KEY (server_id) REFERENCES servers(server_id), "
                    "UNIQUE(user_id, server_id, image_url))")) {
        qWarning() << "Failed to create image_urls table:" << query.lastError().text();
        return false;
    }

    // 创建索引
    query.exec("CREATE INDEX IF NOT EXISTS idx_image_user ON image_urls(user_id)");
    query.exec("CREATE INDEX IF NOT EXISTS idx_image_server ON image_urls(server_id)");

    return true;
}

int ImageUrlDatabase::addUser(const QString &username)
{
    QSqlQuery query;
    query.prepare("INSERT OR IGNORE INTO users (username) VALUES (?)");
    query.addBindValue(username);

    if (!query.exec()) {
        qWarning() << "Failed to add user:" << query.lastError().text();
        return -1;
    }

    // 获取用户ID
    return getUserId(username);
}

int ImageUrlDatabase::getUserId(const QString &username)
{
    QSqlQuery query;
    query.prepare("SELECT user_id FROM users WHERE username = ?");
    query.addBindValue(username);

    if (!query.exec() || !query.next()) {
        return -1;
    }

    return query.value(0).toInt();
}

int ImageUrlDatabase::addServer(const QString &domain)
{
    QSqlQuery query;
    query.prepare("INSERT OR IGNORE INTO servers (domain) VALUES (?)");
    query.addBindValue(domain);

    if (!query.exec()) {
        qWarning() << "Failed to add server:" << query.lastError().text();
        return -1;
    }

    // 获取服务器ID
    return getServerId(domain);
}

int ImageUrlDatabase::getServerId(const QString &domain)
{
    QSqlQuery query;
    query.prepare("SELECT server_id FROM servers WHERE domain = ?");
    query.addBindValue(domain);

    if (!query.exec() || !query.next()) {
        return -1;
    }

    return query.value(0).toInt();
}

bool ImageUrlDatabase::addImageUrl(const QString &username, const QString &domain, const QString &imageUrl)
{
    int userId = addUser(username);
    if (userId == -1) return false;

    int serverId = addServer(domain);
    if (serverId == -1) return false;

    QSqlQuery query;
    query.prepare("INSERT OR REPLACE INTO image_urls (user_id, server_id, image_url, last_accessed) "
                  "VALUES (?, ?, ?, datetime('now'))");
    query.addBindValue(userId);
    query.addBindValue(serverId);
    query.addBindValue(imageUrl);

    if (!query.exec()) {
        qWarning() << "Failed to add image URL:" << query.lastError().text();
        return false;
    }

    return true;
}

QList<QString> ImageUrlDatabase::getUserImages(const QString &username)
{
    QList<QString> result;
    int userId = getUserId(username);

    if (userId == -1) return result;

    QSqlQuery query;
    query.prepare("SELECT i.image_url FROM image_urls i "
                  "WHERE i.user_id = ? "
                  "ORDER BY i.last_accessed DESC");
    query.addBindValue(userId);

    if (!query.exec()) {
        qWarning() << "Failed to get user images:" << query.lastError().text();
        return result;
    }

    while (query.next()) {
        result.append(query.value(0).toString());
    }

    return result;
}

QList<QString> ImageUrlDatabase::getServerImages(const QString &domain)
{
    QList<QString> result;
    int serverId = getServerId(domain);

    if (serverId == -1) return result;

    QSqlQuery query;
    query.prepare("SELECT i.image_url FROM image_urls i "
                  "WHERE i.server_id = ? "
                  "ORDER BY i.last_accessed DESC");
    query.addBindValue(serverId);

    if (!query.exec()) {
        qWarning() << "Failed to get server images:" << query.lastError().text();
        return result;
    }

    while (query.next()) {
        result.append(query.value(0).toString());
    }

    return result;
}

bool ImageUrlDatabase::updateLastAccessed(const QString &username, const QString &domain, const QString &imageUrl)
{
    int userId = getUserId(username);
    if (userId == -1) return false;

    int serverId = getServerId(domain);
    if (serverId == -1) return false;

    QSqlQuery query;
    query.prepare("UPDATE image_urls SET last_accessed = datetime('now') "
                  "WHERE user_id = ? AND server_id = ? AND image_url = ?");
    query.addBindValue(userId);
    query.addBindValue(serverId);
    query.addBindValue(imageUrl);

    if (!query.exec()) {
        qWarning() << "Failed to update last accessed time:" << query.lastError().text();
        return false;
    }

    return query.numRowsAffected() > 0;
}
