#include <gio/gio.h>
#include <gio/giotypes.h>
#include <kylin-ai/private/aiconfig/modelconfig.h>

#include <cstdio>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <thread>
#include <vector>

#include "kylin-ai/genai/vision/image.h"

static void writeBinaryDataToFile(const std::string& filename,
                                  const std::vector<char>& data) {
    std::ofstream outputFile(
        filename, std::ios::out | std::ios::binary | std::ios::trunc);
    if (!outputFile.is_open()) {
        std::cerr << "Failed to open file for writing." << std::endl;
        return;
    }

    // 写入数据到文件
    outputFile.write(data.data(), data.size());

    // 检查是否写入成功
    if (!outputFile.good()) {
        std::cerr << "Error occurred while writing to file." << std::endl;
    } else {
        std::cout << "Binary data has been written to file: " << filename
            << std::endl;
    }

    // 关闭文件
    outputFile.close();
}

void callback(VisionImageResult* image_data, void* user_data) {
    int imageDataLength;
    const uint8_t* imageData =
        image_result_get_data(image_data, &imageDataLength);
    int imageWidth = image_result_get_size(image_data).width;
    int imageHeight = image_result_get_size(image_data).height;
    ImageFormat format = image_result_get_format(image_data);
    int index = image_result_get_index(image_data);
    int total = image_result_get_total(image_data);

    int errorcode = image_result_get_error_code(image_data);
    std::string errorMsg = image_result_get_error_message(image_data);

    std::vector<char> imagedata{imageData, imageData + imageDataLength};
    writeBinaryDataToFile("./test3.png", imagedata);

    int userData = *(int*)user_data;
    std::cout << "length " << imageDataLength << " width " << imageWidth
        << " height " << imageHeight << " format " << format << std::endl;
    std::cout << "index " << index << " total " << total << " errorCode "
        << errorcode << " errorMag " << errorMsg << " userdata "
        << userData << std::endl;
}

void setXunfeiAuthens() {
    kyai::config::model::ModelConfig mc;
    std::vector<kyai::config::model::MultiAuthentication> modelsAuthens;
    modelsAuthens.push_back(
    {"",
     {
         {"", "appId", ""},
         {"", "apiKey", ""},
         {"", "secretKey", ""},
     }});

    mc.setModelAuthentications("讯飞-图片生成", modelsAuthens);
}

void setBaiduAuthens() {
    kyai::config::model::ModelConfig mc;
    std::vector<kyai::config::model::MultiAuthentication> modelsAuthens;
    modelsAuthens.push_back(
    {"",
     {
         {"", "appId", ""},
         {"", "apiKey", ""},
         {"", "secretKey", ""},
     }});
    mc.setModelAuthentications("百度-文心AI作画高级版", modelsAuthens);
}

void test() {
    GenAiImageSession* session = genai_image_create_session();
    genai_image_init_session(session);

    ImageConfig* config = image_config_create();
    image_config_set_generation_number(config, 1);
    image_config_set_style(config, "写实风格");
    image_config_set_size(config, ImageSize{1280, 720});
    genai_image_set_config(session, config);

    bool imageNumber = genai_image_get_supported_image_number(session);
    std::cout << "supported image number " << imageNumber << std::endl;

    int sizeNumber;
    const ImageSize* imageSize =
        genai_image_get_supported_image_size(session, &sizeNumber);
    int i = 0;
    while (i < sizeNumber) {
        std::cout << "supported image size width " << imageSize[i].width
            << " height " << imageSize[i].height << std::endl;
        ++i;
    }

    int styleNumber;
    int j = 0;
    const char** imageStyle =
        genai_image_get_supported_image_style(session, &styleNumber);
    while (j < styleNumber) {
        std::cout << "supported image style " << imageStyle[j] << std::endl;
        ++j;
    }

    int* a = new int();
    *a = 100;
    genai_image_result_set_callback(session, callback, a);

    genai_image_generate_image_async(session, "生成一张小狗的图片");

    auto* pMainLoop = g_main_loop_new(nullptr, false);

    std::thread ctrlThread([&session, &config, pMainLoop] {
        while (std::getchar() != '\n') {
        }
        image_config_destroy(&config);
        genai_image_destroy_session(&session);
        g_main_loop_quit(pMainLoop);
    });
    ctrlThread.detach();

    g_main_loop_run(pMainLoop);
    g_main_loop_unref(pMainLoop);
}

int main() {
    setBaiduAuthens();
    setXunfeiAuthens();
    test();
    return 0;
}
