#include "HProjectDao.h"

#include "../global.h"

HProjectDao::HProjectDao(QSqlDatabase db) : database(db) {}

bool HProjectDao::addHProject(const HProject &project) {
    QSqlQuery query;
    query.prepare(
        "INSERT INTO h_project (uuid, name, company_code, htid, xmbh, operator_name, "
        "operator_identity, blaster_name, blaster_identity, address_uuid, address_path, "
        "lora_address,pc_sn, "
        "det_sum, file_name, file_url, blast_status,blast_count,created_at, updated_at, "
        "deleted_at, create_by, update_by) "
        "VALUES (:uuid, :name, :companyCode, :htid, :xmbh, :operatorName, :operatorIdentity, "
        ":blasterName, :blasterIdentity, :addressUuid, :addressPath, :loraAddress, :pcSn, :detSum, "
        ":fileName, "
        ":fileUrl, :blastStatus, :blastCount,:createdAt, :updatedAt, :deletedAt, :createBy, "
        ":updateBy)");

    query.bindValue(":uuid", project.getUuid());
    query.bindValue(":name", project.getName());
    query.bindValue(":companyCode", project.getCompanyCode());
    query.bindValue(":htid", project.getHtid());
    query.bindValue(":xmbh", project.getXmbh());
    query.bindValue(":operatorName", project.getOperatorName());
    query.bindValue(":operatorIdentity", project.getOperatorIdentity());
    query.bindValue(":blasterName", project.getBlasterName());
    query.bindValue(":blasterIdentity", project.getBlasterIdentity());
    query.bindValue(":addressUuid", project.getAddressUuid());
    query.bindValue(":addressPath", project.getAddressPath());
    query.bindValue(":loraAddress", project.getLoraAddress());
    query.bindValue(":blastCount", project.getBlastCount());
    query.bindValue(":pcSn", project.getPcSn());
    query.bindValue(":detSum", project.getDetSum());
    query.bindValue(":fileName", project.getFileName());
    query.bindValue(":fileUrl", project.getFileUrl());
    query.bindValue(":blastStatus", project.getBlastStatus());
    query.bindValue(":createdAt", project.getCreatedAt().toString(Qt::ISODateWithMs));
    query.bindValue(":updatedAt", project.getUpdatedAt().toString(Qt::ISODateWithMs));
    query.bindValue(":deletedAt", project.getDeletedAt().toString(Qt::ISODateWithMs));
    query.bindValue(":createBy", project.getCreateBy());
    query.bindValue(":updateBy", project.getUpdateBy());
    qDebug() << "Executing SQL query:" << query.lastQuery();
    if (!query.exec()) {
        return false;
    }

    return true;
}

bool HProjectDao::updateHProject(const HProject &project) {
    QSqlQuery query;
    query.prepare(
        "UPDATE h_project SET "
        "uuid = :uuid, "
        "name = :name, "
        "company_code = :companyCode, "
        "htid = :htid, "
        "xmbh = :xmbh, "
        "operator_name = :operatorName, "
        "operator_identity = :operatorIdentity, "
        "blaster_name = :blasterName, "
        "blaster_identity = :blasterIdentity, "
        "address_uuid = :addressUuid, "
        "address_path = :addressPath, "
        "pc_sn = :pcSn, "
        "det_sum = :detSum, "
        "file_name = :fileName, "
        "file_url = :fileUrl, "
        "blast_status = :blastStatus, "
        "created_at = :createdAt, "
        "updated_at = :updatedAt, "
        "deleted_at = :deletedAt, "
        "create_by = :createBy, "
        "update_by = :updateBy "
        "WHERE id = :id");

    query.bindValue(":id", project.getId());
    query.bindValue(":uuid", project.getUuid());
    query.bindValue(":name", project.getName());
    query.bindValue(":companyCode", project.getCompanyCode());
    query.bindValue(":htid", project.getHtid());
    query.bindValue(":xmbh", project.getXmbh());
    query.bindValue(":operatorName", project.getOperatorName());
    query.bindValue(":operatorIdentity", project.getOperatorIdentity());
    query.bindValue(":blasterName", project.getBlasterName());
    query.bindValue(":blasterIdentity", project.getBlasterIdentity());
    query.bindValue(":addressUuid", project.getAddressUuid());
    query.bindValue(":addressPath", project.getAddressPath());
    query.bindValue(":pcSn", project.getPcSn());
    query.bindValue(":detSum", project.getDetSum());
    query.bindValue(":fileName", project.getFileName());
    query.bindValue(":fileUrl", project.getFileUrl());
    query.bindValue(":blastStatus", project.getBlastStatus());
    query.bindValue(":createdAt", project.getCreatedAt().toString(Qt::ISODateWithMs));
    query.bindValue(":updatedAt", project.getUpdatedAt().toString(Qt::ISODateWithMs));
    query.bindValue(":deletedAt", project.getDeletedAt().toString(Qt::ISODateWithMs));
    query.bindValue(":createBy", project.getCreateBy());
    query.bindValue(":updateBy", project.getUpdateBy());

    if (!query.exec()) {
        return false;
    }

    return true;
}

bool HProjectDao::deleteHProject(const HProject &project) {
    QSqlQuery query;
    query.prepare("DELETE FROM h_project WHERE id = :id");
    query.bindValue(":id", project.getId());
    if (!query.exec()) {
        return false;
    }
    return true;
}

// HProject HProjectDao::getHProjectById(qint64 id)
// {
//     QSqlQuery query;
//     // query.prepare("SELECT * FROM hproject WHERE id = :id");
//     // query.bindValue(":id", id);
//     // if (query.exec() && query.next()) {
//     //     return recordToProject(query.record());
//     // }
//     return HProject();
// }

PaginatedHProjectResult HProjectDao::getAllHProjects(int page, int pageSize) {
    QList<QSharedPointer<HProject>> projects;
    QSqlQuery query(database);
    int offset = (page - 1) * pageSize;
    query.prepare("SELECT * FROM h_project ORDER BY created_at LIMIT :pageSize OFFSET :offset");
    query.bindValue(":pageSize", pageSize);
    query.bindValue(":offset", offset);

    if (query.exec()) {
        while (query.next()) {
            projects.append(recordToProject(query.record()));
        }
    } else {
        qWarning() << "Query execution failed: " << query.lastError().text();
    }

    query.prepare("SELECT COUNT(*) FROM h_project");
    int totalCount = 0;
    if (query.exec() && query.next()) {
        totalCount = query.value(0).toInt();
    }
    return {projects, totalCount};
}

PaginatedHProjectResult HProjectDao::getAllHProjectsByOpera(int page, int pageSize) {
    QList<QSharedPointer<HProject>> projects;
    QSqlQuery query(database);
    int offset = (page - 1) * pageSize;
    query.prepare(
        "SELECT * FROM h_project WHERE blast_status = :safeCheckedStatus ORDER BY created_at "
        "LIMIT :pageSize OFFSET :offset");
    query.bindValue(":safeCheckedStatus", BlastStatus::SafeChecked);
    query.bindValue(":pageSize", pageSize);
    query.bindValue(":offset", offset);
    if (query.exec()) {
        while (query.next()) {
            projects.append(recordToProject(query.record()));
        }
    } else {
        qWarning() << "Query execution failed: " << query.lastError().text();
    }

    query.prepare("SELECT COUNT(*) FROM h_project WHERE blast_status > 1");
    int totalCount = 0;
    if (query.exec() && query.next()) {
        totalCount = query.value(0).toInt();
    }
    return {projects, totalCount};
}

QList<QSharedPointer<HProject>> HProjectDao::getRegistedProjectByAddressUuid(
    QList<QString> addressUuids) {
    QList<QSharedPointer<HProject>> projects;
    QSqlQuery query(database);
    QString placeholders = QString(",").repeated(addressUuids.size() - 1).prepend(":addressUuid");
    query.prepare("SELECT * FROM h_project WHERE address_uuid IN (" + placeholders +
                  ") "
                  "AND blast_status = " +
                  BlastStatus::Registered + " ORDER BY created_at");

    for (const QString &addressUuid : addressUuids) {
        query.bindValue(":addressUuid", addressUuid);
        if (!query.exec()) {
            QMessageBox::critical(
                nullptr, "数据搜索异常",
                QString("通过地址查询注册工程数据异常: %1").arg(query.lastError().text()));
            return projects;
        }
        while (query.next()) {
            projects.append(recordToProject(query.record()));
        }
    }
    return projects;
}

QList<QSharedPointer<HProject>> HProjectDao::getAllHProjectsReg() {
    QList<QSharedPointer<HProject>> projects;
    QSqlQuery query(database);
    query.prepare("SELECT * FROM h_project WHERE blast_status =1 ORDER BY created_at ");
    // 执行查询并打印SQL
    if (query.exec()) {
        while (query.next()) {
            projects.append(recordToProject(query.record()));
        }
    } else {
        qWarning() << "Query execution failed: " << query.lastError().text();
    }
    return projects;
}

// 更改状态
bool HProjectDao::updateBlastStatusByUuid(const QString &uuid, const QString &blastStatus) {
    QSqlQuery query;
    query.prepare(
        "UPDATE h_project SET "
        "blast_status = :blastStatus "
        "WHERE uuid = :uuid");
    query.bindValue(":uuid", uuid);
    query.bindValue(":blastStatus", blastStatus);

    qDebug() << "Executing SQL query to update blast_status:" << query.lastQuery();
    if (!query.exec()) {
        qCritical() << "Failed to update blast_status for HProject:" << query.lastError().text();
        return false;
    }

    qDebug() << "Executing SQL query to update blast_status completed successfully.";
    ;
    return true;
}

QSharedPointer<HProject> HProjectDao::recordToProject(const QSqlRecord &record) {
    QSharedPointer<HProject> project = QSharedPointer<HProject>::create();
    project->setId(record.value("id").toInt());
    project->setUuid(record.value("uuid").toString());
    project->setName(record.value("name").toString());
    project->setCompanyCode(record.value("company_code").toString());
    project->setHtid(record.value("htid").toString());
    project->setXmbh(record.value("xmbh").toString());
    project->setOperatorName(record.value("operator_name").toString());
    project->setOperatorIdentity(record.value("operator_identity").toString());
    project->setBlasterName(record.value("blaster_name").toString());
    project->setBlasterIdentity(record.value("blaster_identity").toString());
    project->setAddressUuid(record.value("address_uuid").toString());
    project->setAddressPath(record.value("address_path").toString());
    project->setPcSn(record.value("pc_sn").toString());
    project->setDetSum(record.value("det_sum").toString());
    project->setBlastCount(record.value("blast_count").toString());
    project->setFileName(record.value("file_name").toString());
    project->setFileUrl(record.value("file_url").toString());
    project->setBlastStatus(record.value("blast_status").toString());
    project->setCreatedAt(
        QDateTime::fromString(record.value("created_at").toString(), Qt::ISODateWithMs));
    project->setUpdatedAt(
        QDateTime::fromString(record.value("updated_at").toString(), Qt::ISODateWithMs));
    project->setDeletedAt(
        QDateTime::fromString(record.value("deleted_at").toString(), Qt::ISODateWithMs));
    project->setCreateBy(record.value("create_by").toInt());
    project->setUpdateBy(record.value("update_by").toInt());
    return project;
}
