#include <Windows.h>
#include <string>
#include <thread>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <filesystem>
#include <QApplication>

#include "common/Utils.h"
#include "common/Snowflake.h"
#include "common/JsonN.h"
#include "common/Spdlogger.h"
#include "common/XlsxEntity.h"
#include "common/Crypto.h"

#include "app/Application.h"
#include "app/Config.h"
#include "app/DataStruct.h"

#include "database/Dao.h"
#include "protocol/TcpEntity.h"
#include "widgets/MainWindow.h"
#include "qt/MainWeb.h"
#include "qt/MainApp.h"

int SM2_test()
{

    // 未压缩格式（最常见）
    // 前缀 : 04 (1字节) X坐标 : 32字节(64个十六进制字符)， Y坐标 : 32字节(64个十六进制字符)，总长度 : 1 + 32 + 32 = 65字节 = 130个十六进制字符
    std::string hex_pub_key = "04661013d0b881d817085a251f0c0a7024e72c76e6eb0fd22c0170a508b123864ef7514df30cecb45deecf9b35810d0315b5164d63199c971ac3323c228ab48606";
    std::string hex_pri_key = "b935087295c448b221abc571d88018ee9d037407c32aa4d7fbf627a143ad86a0";

    std::string cipherText = Crypto::gmssl_sm2Encrypt(hex_pub_key, hex_pri_key, "123456");
    std::cout << "加密: " << Utils::toHex(cipherText) << std::endl;


    std::string text = "306f022100f180bb383cddea024dfb6fea6c321f4b6901a468646df3da7d0040ebf107199f022009c363df8958c037f658da7060d429647802ac40560140e79685884a38f81cb10420783eb5b893994afdf7f68e2123e0c6e9469b3ea1f26297cb2b8e9cf6e27162a60406f99e4cbe6655";
    std::string plainText = Crypto::gmssl_sm2Decrypt(hex_pub_key, hex_pri_key, Utils::fromHex(text));
    std::cout << "解密: " << plainText << std::endl;

    //{
    //    SM2_KEY sm2k;

    //    FILE* f = fopen("D:/sm2pub.pem", "rb");
    //    if (f)
    //    {
    //        sm2_public_key_info_from_pem(&sm2k, f);
    //        std::vector<uint8_t> plainText(SM2_MAX_PLAINTEXT_SIZE);
    //        std::vector<uint8_t> ciphertext(SM2_MAX_CIPHERTEXT_SIZE);
    //        size_t ciphertext_len = -1;
    //        int ret = sm2_encrypt(&sm2k, plainText.data(), plainText.size(), ciphertext.data(), &ciphertext_len);
    //        std::cout << "加密: " << Utils::toHex(ciphertext, ciphertext_len) << std::endl;
    //    }

    //    FILE* f1 = fopen("D:/sm2.pem", "rb");
    //    if (f1)
    //    {
    //        sm2_private_key_info_from_pem(&sm2k, f1);
    //    }
    //    sm2_key_print(stderr, 0, 4, "SM2_KEY", &sm2k);

    //    std::cout << "";
    //}

    return 0;
}


#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <sstream>

// 错误处理函数
void HandleOpensslError() {
    ERR_print_errors_fp(stderr);
    exit(EXIT_FAILURE);
}

// 将16进制字符串转换为字节数组
std::vector<unsigned char> hexToBytes(const std::string& hex) {
    std::vector<unsigned char> bytes;

    for (size_t i = 0; i < hex.length(); i += 2) {
        std::string byteString = hex.substr(i, 2);
        unsigned char byte = static_cast<unsigned char>(strtol(byteString.c_str(), NULL, 16));
        bytes.push_back(byte);
    }

    return bytes;
}

// 将字节数组转换为16进制字符串
std::string bytes_to_hex(const std::vector<unsigned char>& bytes) {
    std::stringstream ss;
    ss << std::hex << std::setfill('0');

    for (unsigned char byte : bytes) {
        ss << std::setw(2) << static_cast<unsigned int>(byte);
    }

    return ss.str();
}

void OpensslSM2_test()
{
    // 初始化 OpenSSL
    OpenSSL_add_all_algorithms();

    ERR_load_crypto_strings();

    // 示例16进制密钥
    std::string private_key_hex = "b935087295c448b221abc571d88018ee9d037407c32aa4d7fbf627a143ad86a0";
    std::string public_key_hex = "04661013d0b881d817085a251f0c0a7024e72c76e6eb0fd22c0170a508b123864ef7514df30cecb45deecf9b35810d0315b5164d63199c971ac3323c228ab48606";

    // 要加密的明文
    std::string plaintext = "123";

    std::cout << "Original text: " << plaintext << std::endl;
    std::cout << "Private key (hex): " << private_key_hex << std::endl;
    std::cout << "Public key (hex): " << public_key_hex << std::endl;

    // 加密
    auto ciphertext = Crypto::ssl_sm2Encrypt(public_key_hex, plaintext);
    std::cout << "Ciphertext (hex): " << Utils::toHex(ciphertext) << std::endl;

    // 解密^
    auto decryptedText = Crypto::ssl_sm2Decrypt(private_key_hex, ciphertext);
    std::cout << "Decrypted text: " << decryptedText << std::endl;

    // 验证加解密是否正确
    if (plaintext == decryptedText) {
        std::cout << "SM2 encryption and decryption successful!" << std::endl;
    }
    else {
        std::cout << "SM2 encryption and decryption failed!" << std::endl;
    }

    {
        // 未压缩格式（最常见）
        // 前缀 : 04 (1字节) X坐标 : 32字节(64个十六进制字符)， Y坐标 : 32字节(64个十六进制字符)，总长度 : 1 + 32 + 32 = 65字节 = 130个十六进制字符
        //std::string private_key_hex = "04661013d0b881d817085a251f0c0a7024e72c76e6eb0fd22c0170a508b123864ef7514df30cecb45deecf9b35810d0315b5164d63199c971ac3323c228ab48606";
        //std::string public_key_hex = "b935087295c448b221abc571d88018ee9d037407c32aa4d7fbf627a143ad86a0";

        //std::string cipherText = Crypto::sm2Encrypt(public_key_hex, private_key_hex, "123456");
        //std::cout << "加密: " << Utils::toHex(cipherText) << std::endl;

        std::string text(ciphertext.begin(), ciphertext.end());
        //std::string textHex = "306f022100f180bb383cddea024dfb6fea6c321f4b6901a468646df3da7d0040ebf107199f022009c363df8958c037f658da7060d429647802ac40560140e79685884a38f81cb10420783eb5b893994afdf7f68e2123e0c6e9469b3ea1f26297cb2b8e9cf6e27162a60406f99e4cbe6655";
        //std::string text = Utils::fromHex(text);
        std::string plainText = Crypto::gmssl_sm2Decrypt(public_key_hex, private_key_hex, text);
        std::cout << "解密: " << plainText << std::endl;
    }
}

int main(int argc, char** argv)
{
    // 设置控制台输出为 UTF-8 编码
    SetConsoleOutputCP(CP_UTF8);
    // 设置控制台输入为 UTF-8 编码（如果需要输入中文）
    SetConsoleCP(CP_UTF8);

    // 启动数据库服务
    system("net start mysql");

    //OpensslSM2_test();
    //SM2_test();

    // 初始化日志
    Spdlogger::init(spdlog::level::info, "");
    spdlog::info("[main] start ... ======================================================================");
    qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--ignore-gpu-blacklist --enable-gpu-rasterization --enable-native-gpu-memory-buffers --num-raster-threads=4");

    // 运行后台服务
    Application::instance().init();
    std::cout << "ess server is running ... " << std::endl;

    if (Config::option.windowEnabled)
    {
        QApplication qapp(argc, argv);
        QString fontFile = QCoreApplication::applicationDirPath() + "/assets/fonts/优设标题黑.ttf";
        QFontDatabase::addApplicationFont(fontFile);
        QFont font("Cascadia Code, Microsoft YaHei", 10, 600);
        QApplication::setFont(font);
        MainApp mainApp;
        return qapp.exec();
    }
    else
    {

        while (1)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        };
        return 0;
    }

    // 启动 PV 服务主线程
    //std::thread([=]() 
    //    {
    //        // 运行pv主流程
    //        PARAM p;
    //        int   s;
    //        pvInit(argc, argv, &p);
    //        /* here you may interpret ac,av and set p->user to your data */
    //        while (1)
    //        {
    //            s = pvAccept(&p);
    //            if (s != -1) pvCreateThread(&p, s);
    //            std::this_thread::sleep_for(std::chrono::milliseconds(10));
    //        }
    //    }).detach();

    //QApplication qapp(argc, argv);
    //qapp.setWindowIcon(QIcon("./yhicon.ico"));
    //MainWeb mainWin;
    //qapp.exec();

    //QApplication a(argc, argv);
    //QMainWindow w;

    //QWebEngineView webView(&w);
    //webView.load(QUrl("http://127.0.0.1:19600/"));

    //w.setCentralWidget(&webView);
    //w.setWindowTitle("Qt 6.7 WebEngine Demo");
    //w.resize(1280, 720);
    //w.show();
    //webView.show();
    //a.exec();

    // 运行QT主窗口
    //QApplication qapp(argc, argv);
    //MainWindow mainWin;
    //mainWin.setWindowTitle("风光储能站控制管理系统");
    //mainWin.resize(1920, 1080);
    //mainWin.show();
    //qapp.exec();
    return 0;
}