/**
 * @file scene_ai_printer.c
 * @brief AI 打印机场景实现
 */

#include "scene_ai_printer.h"
#include "scene_ai_printer_config.h"
#include "aiagent_credentials.h"
#include "aiagent_engine.h"
#include "base64_codec.h"
#include "hal_log.h"
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#define TAG "PRINTER"

/* 场景私有状态 */
static aiagent_engine_t s_engine = NULL;

/* ========== 场景配置 ========== */

/* 场景配置，连接 URL 由引擎层构建 */
static const aiagent_config_t s_printer_config = {
    /* 引擎根据配置参数构建连接 URL */
    .ws_host = AIAGENT_WS_HOST,

    /* 凭证 */
    .appid          = AIAGENT_APPID,
    .license_key    = AIAGENT_LICENSE_KEY,
#if AIAGENT_CONN_MODE == AIAGENT_CONN_MODE_AKSK
    .access_key     = AIAGENT_ACCESS_KEY,
    .secret_key     = AIAGENT_SECRET_KEY,
#elif AIAGENT_CONN_MODE == AIAGENT_CONN_MODE_USERSERVER
    .userserver_url          = AIAGENT_USERSERVER_URL,
    .userserver_create_path  = AIAGENT_USERSERVER_CREATE,
    .userserver_destroy_path = AIAGENT_USERSERVER_DESTROY,
#endif

    /* 上行音频编码 */
    .audio_codec    = "g722",

    /* 云端会话参数 */
    .cfg = {
        .tts_sayhi              = AI_PRINTER_SAYHI_TEXT,
        .ip_to_location         = true,
        .audiocodec             = "g722",
        .dfda                   = true,
        .tts_enable_fast_send   = true,

        /* 文生图分辨率 */
        .screen_width           = AI_PRINTER_SCREEN_WIDTH,
        .screen_height          = AI_PRINTER_SCREEN_HEIGHT,

        .disable_voice_auto_int = true,
        .emotion_cfg = "{\"enable\":true,\"injectToLLM\":true}",
        .voice_fp_url = "{\"appId\":\"" AIAGENT_APPID "\",\"enable\":true,\"firstSentenceRegistration\":true,\"interruptMode\":0,\"enableClassifyOthers\":true,\"similarity\":[0.18,0.22,0.30,0.40]}",
    },

    /* 本地运行参数 */
    .audio_sample_rate      = AI_PRINTER_SAMPLE_RATE,
    .audio_channels         = AI_PRINTER_CHANNELS,
    .default_mode           = AI_PRINTER_DEFAULT_MODE,
    .aec_enable             = false,  /* PTT 模式无需回声消除 */
};

static const aiagent_config_t *printer_get_config(void)
{
    return &s_printer_config;
}

/* ========== 图片生成结果处理 ========== */

/**
 * @brief 从 MEDIA_GENERATE_RESULT 事件数据中提取 Base64 JPEG 数据
 *
 * 事件数据格式: {"msg":"success","task":xxx,"resource_base64":"data:image/jpeg;base64,/9j/...","error":0,"type":"image"}
 */
static int printer_extract_base64_jpeg(const char *data, size_t data_len,
                                       const char **out_base64, size_t *out_base64_len)
{
    if (!data || data_len == 0 || !out_base64 || !out_base64_len) {
        return -1;
    }

    /* 查找 "resource_base64":" 字段 */
    const char *key = "\"resource_base64\":\"";
    size_t key_len = strlen(key);
    const char *pos = NULL;
    const char *end = data + data_len;

    for (const char *p = data; p + key_len < end; p++) {
        if (memcmp(p, key, key_len) == 0) {
            pos = p + key_len;
            break;
        }
    }

    if (!pos) {
        BD_LOGW(TAG, "未找到 resource_base64 字段");
        return -1;
    }

    /* 跳过 base64 前缀 */
    static const char prefix[] = "data:image/jpeg;base64,";
    if (pos + sizeof(prefix) - 1 < end && memcmp(pos, prefix, sizeof(prefix) - 1) == 0) {
        pos += sizeof(prefix) - 1;
    }

    /* 找到 Base64 数据结尾 (下一个双引号) */
    const char *b64_end = pos;
    while (b64_end < end && *b64_end != '"') {
        b64_end++;
    }

    if (b64_end >= end) {
        BD_LOGW(TAG, "Base64数据未正确结束");
        return -1;
    }

    *out_base64 = pos;
    *out_base64_len = (size_t)(b64_end - pos);

    BD_LOGI(TAG, "提取Base64 JPEG: %d 字节", (int)*out_base64_len);
    return 0;
}

/**
 * @brief 处理图片生成结果事件
 *
 * 从服务端下发的 [E]:[MEDIA_GENERATE_RESULT] 中提取 Base64 JPEG 数据，
 * 场景可在此回调中进行解码和打印输出。
 */
static void printer_handle_media_gen_result(const char *data, size_t data_len)
{
    const char *base64_data = NULL;
    size_t base64_len = 0;

    int ret = printer_extract_base64_jpeg(data, data_len, &base64_data, &base64_len);
    if (ret != 0 || !base64_data || base64_len == 0) {
        BD_LOGE(TAG, "图片数据提取失败");
        return;
    }

    BD_LOGI(TAG, "收到生成图片: Base64长度=%d", (int)base64_len);

    if ((base64_len & 3u) != 0) {
        BD_LOGE(TAG, "base64 长度非 4 的倍数: %d", (int)base64_len);
        return;
    }

    /* JPEG 二进制上界：(base64_len / 4) * 3 字节 */
    size_t jpeg_cap = (base64_len / 4) * 3;
    uint8_t *jpeg_buf = (uint8_t *)malloc(jpeg_cap);
    if (!jpeg_buf) {
        BD_LOGE(TAG, "JPEG 缓冲分配失败: %d 字节", (int)jpeg_cap);
        return;
    }

    int jpeg_len = base64_codec_decode(base64_data, base64_len,
                                       jpeg_buf, jpeg_cap);
    if (jpeg_len <= 0) {
        BD_LOGE(TAG, "base64 解码失败: %d", jpeg_len);
        free(jpeg_buf);
        return;
    }

    BD_LOGI(TAG, "JPEG 解码完成: %d 字节", jpeg_len);

    /* 校验 JPEG 完整性：必须以 FFD8 开头、FFD9 结尾 */
    if (jpeg_len < 4 ||
        jpeg_buf[0] != 0xFF || jpeg_buf[1] != 0xD8 ||
        jpeg_buf[jpeg_len - 2] != 0xFF || jpeg_buf[jpeg_len - 1] != 0xD9) {
        BD_LOGW(TAG, "JPEG 数据不完整: head=%02X%02X tail=%02X%02X",
                jpeg_buf[0], jpeg_buf[1],
                jpeg_buf[jpeg_len - 2], jpeg_buf[jpeg_len - 1]);
    } else {
        BD_LOGI(TAG, "JPEG 完整性 OK (FFD8...FFD9)");
    }

    /* JPEG 数据已准备好，可在此对接打印机输出 */
    free(jpeg_buf);
}

/* ========== 场景生命周期回调 ========== */

static int printer_on_init(aiagent_engine_t engine)
{
    s_engine = engine;
    BD_LOGI(TAG, "AI打印机场景初始化");
    return 0;
}

static void printer_on_start(aiagent_engine_t engine)
{
    BD_LOGI(TAG, "AI打印机场景启动");
}

static void printer_on_stop(aiagent_engine_t engine)
{
    BD_LOGI(TAG, "AI打印机场景停止");
    s_engine = NULL;
}

static void printer_on_destroy(void)
{
    BD_LOGI(TAG, "AI打印机场景销毁");
}

static void printer_on_state_change(aiagent_state_t old_st, aiagent_state_t new_st)
{
    BD_LOGD(TAG, "状态变化: %d -> %d", old_st, new_st);

    if (old_st == AIAGENT_STATE_CONNECTING && new_st == AIAGENT_STATE_READY && s_engine) {
        char prompt_json[1024];
        snprintf(prompt_json, sizeof(prompt_json),
                 "{\"model_type\":\"%s\",\"prompt\":\"%s\"}",
                 AI_PRINTER_MODEL_TYPE_IMAGE_GEN,
                 AI_PRINTER_IMAGE_GEN_PROMPT);
        aiagent_engine_update_system_prompt(s_engine, prompt_json);

        char eq_json[256];
        snprintf(eq_json, sizeof(eq_json),
                 "{\"enhance_type\":\"%s\","
                 "\"pre_query\":\"%s\",\"post_query\":\"%s\"}",
                 AI_PRINTER_ENHANCE_TYPE,
                 AI_PRINTER_PRE_QUERY,
                 AI_PRINTER_POST_QUERY);
        aiagent_engine_set_enhance_query(s_engine, eq_json);
        BD_LOGI(TAG, "sent enhance query");
    }
}

static void printer_on_asr_result(const char *text, bool is_final, const aiagent_asr_ext_t *ext)
{
    if (!is_final) {
        return;
    }
    if (ext && ext->emotion) {
        BD_LOGI(TAG, "ASR final: \"%s\"  emotion=[%s] name=[%s]",
                text ? text : "",
                ext->emotion,
                ext->name ? ext->name : "-");
    } else {
        BD_LOGI(TAG, "ASR final: \"%s\"", text ? text : "");
    }
}

static int printer_on_function_call(const char *session_id, const char *name,
                                     const char *params)
{
    BD_LOGI(TAG, "场景FC: name=%s", name ? name : "null");
    return 0;
}

/**
 * @brief 场景事件处理
 *
 * 核心引擎将 MEDIA_GENERATE_RESULT 等事件透传到此回调，
 * 打印机场景在此处理图片生成结果。
 */
static void printer_on_event(aiagent_event_type_t event, const char *data,
                             size_t data_len)
{
    switch (event) {
    case AIAGENT_EVT_MEDIA_GEN_RESULT:
        printer_handle_media_gen_result(data, data_len);
        break;

    default:
        BD_LOGD(TAG, "事件: type=%d", event);
        break;
    }
}

static void printer_on_key_event(int action, int key_value)
{
    BD_LOGD(TAG, "按键事件: action=%d, key=%d", action, key_value);
    /* 按键事件委托给引擎的交互管理器 */
}

static void printer_on_network_event(int event)
{
    BD_LOGI(TAG, "网络事件: %d", event);
}

/* ========== 场景操作表 ========== */

static const aiagent_scene_ops_t s_printer_ops = {
    .name             = "ai_printer",
    .get_config       = printer_get_config,
    .on_init          = printer_on_init,
    .on_start         = printer_on_start,
    .on_stop          = printer_on_stop,
    .on_destroy       = printer_on_destroy,
    .on_state_change  = printer_on_state_change,
    .on_asr_result    = printer_on_asr_result,
    .on_function_call = printer_on_function_call,
    .on_event         = printer_on_event,
    .on_key_event     = printer_on_key_event,
    .on_network_event = printer_on_network_event,
};

const aiagent_scene_ops_t *scene_ai_printer_get_ops(void)
{
    return &s_printer_ops;
}
