/**
 * @file scene_manager.c
 * @brief 场景注册与生命周期管理
 */

#include "aiagent_scene.h"
#include "aiagent_engine.h"
#include "hal_log.h"
#include <string.h>

#define TAG "[SCENE_MGR]"

#define MAX_SCENES  4

/* 场景注册表 */
static const aiagent_scene_ops_t *s_scenes[MAX_SCENES];
static int s_scene_count = 0;

/* 当前激活场景 */
static const aiagent_scene_ops_t *s_active_scene = NULL;
static aiagent_engine_t s_engine = NULL;

/* 引擎回调前向声明 */
static void scene_on_state_change(aiagent_state_t old_st, aiagent_state_t new_st, void *ctx);
static void scene_on_asr_result(const char *text, bool is_final, void *ctx);
static void scene_on_asr_result_ext(const char *text, bool is_final,
                                     const aiagent_asr_ext_t *ext, void *ctx);
static void scene_on_ai_response(const char *text, bool is_final, void *ctx);
static void scene_on_audio_data(const uint8_t *data, size_t len, void *ctx);
static int scene_on_function_call(const char *session_id, const char *name, const char *params, void *ctx);
static void scene_on_error(aiagent_error_t code, const char *msg, void *ctx);
static void scene_on_tts_event(bool is_start, void *ctx);
static void scene_on_license_result(bool pass, void *ctx);
static void scene_on_event(aiagent_event_type_t event, const char *data, size_t data_len, void *ctx);

int aiagent_scene_register(const aiagent_scene_ops_t *scene)
{
    if (!scene || !scene->name) {
        return AIAGENT_ERR_INVALID_PARAM;
    }

    if (s_scene_count >= MAX_SCENES) {
        BD_LOGE(TAG, "scene registry full");
        return AIAGENT_ERR_NO_MEMORY;
    }

    /* 检查是否重复注册 */
    for (int i = 0; i < s_scene_count; i++) {
        if (strcmp(s_scenes[i]->name, scene->name) == 0) {
            BD_LOGW(TAG, "scene '%s' already registered", scene->name);
            return AIAGENT_OK;
        }
    }

    s_scenes[s_scene_count++] = scene;
    BD_LOGI(TAG, "scene '%s' registered (%d/%d)", scene->name, s_scene_count, MAX_SCENES);
    return AIAGENT_OK;
}

int aiagent_scene_start(const char *scene_name)
{
    if (!scene_name) {
        return AIAGENT_ERR_INVALID_PARAM;
    }

    /* 按名称查找场景 */
    const aiagent_scene_ops_t *scene = NULL;
    for (int i = 0; i < s_scene_count; i++) {
        if (strcmp(s_scenes[i]->name, scene_name) == 0) {
            scene = s_scenes[i];
            break;
        }
    }

    if (!scene) {
        BD_LOGE(TAG, "scene '%s' not found", scene_name);
        return AIAGENT_ERR_INVALID_PARAM;
    }

    /* 若已有运行中的场景则先停止 */
    if (s_active_scene) {
        aiagent_scene_stop();
    }

    /* 获取场景配置 */
    const aiagent_config_t *config = NULL;
    if (scene->get_config) {
        config = scene->get_config();
    }
    if (!config) {
        BD_LOGE(TAG, "scene '%s' has no config", scene_name);
        return AIAGENT_ERR_INVALID_PARAM;
    }

    /* 创建引擎并绑定场景回调 */
    aiagent_callbacks_t cbs = {
        .on_state_change  = scene_on_state_change,
        .on_asr_result    = scene_on_asr_result,
        .on_asr_result_ext = scene_on_asr_result_ext,
        .on_ai_response   = scene_on_ai_response,
        .on_audio_data    = scene_on_audio_data,
        .on_function_call = scene_on_function_call,
        .on_error         = scene_on_error,
        .on_tts_event     = scene_on_tts_event,
        .on_license_result = scene_on_license_result,
        .on_event         = scene_on_event,
        .user_ctx         = NULL,
    };

    s_engine = aiagent_engine_create(&cbs);
    if (!s_engine) {
        BD_LOGE(TAG, "engine create fail");
        return AIAGENT_ERR_NO_MEMORY;
    }

    /* 用场景配置初始化引擎 */
    int ret = aiagent_engine_init(s_engine, config);
    if (ret != 0) {
        BD_LOGE(TAG, "engine init fail: %d", ret);
        aiagent_engine_destroy(s_engine);
        s_engine = NULL;
        return ret;
    }

    /* 通知场景初始化完成 */
    s_active_scene = scene;
    if (scene->on_init) {
        ret = scene->on_init(s_engine);
        if (ret != 0) {
            BD_LOGE(TAG, "scene on_init fail: %d", ret);
            aiagent_engine_destroy(s_engine);
            s_engine = NULL;
            s_active_scene = NULL;
            return ret;
        }
    }

    BD_LOGI(TAG, "scene '%s' started (engine created + initialized)", scene_name);
    return AIAGENT_OK;
}

void aiagent_scene_stop(void)
{
    if (!s_active_scene) {
        return;
    }

    BD_LOGI(TAG, "stopping scene '%s'", s_active_scene->name);

    if (s_active_scene->on_stop && s_engine) {
        s_active_scene->on_stop(s_engine);
    }

    if (s_active_scene->on_destroy) {
        s_active_scene->on_destroy();
    }

    if (s_engine) {
        aiagent_engine_destroy(s_engine);
        s_engine = NULL;
    }

    s_active_scene = NULL;
}

const char *aiagent_scene_get_active(void)
{
    return s_active_scene ? s_active_scene->name : NULL;
}

/* ========== 提供给 aiagent_app 的接口 ========== */

aiagent_engine_t aiagent_scene_get_engine(void)
{
    return s_engine;
}

void aiagent_scene_notify_network(int event)
{
    if (s_active_scene && s_active_scene->on_network_event) {
        s_active_scene->on_network_event(event);
    }
}

void aiagent_scene_notify_key(int action, int key_value)
{
    if (s_active_scene && s_active_scene->on_key_event) {
        s_active_scene->on_key_event(action, key_value);
    }
}

/* ========== 引擎回调分发到场景 ========== */

static void scene_on_state_change(aiagent_state_t old_st, aiagent_state_t new_st, void *ctx)
{
    (void)ctx;
    BD_LOGD(TAG, "state: %d -> %d", old_st, new_st);
    if (s_active_scene && s_active_scene->on_state_change) {
        s_active_scene->on_state_change(old_st, new_st);
    }
}

static void scene_on_asr_result(const char *text, bool is_final, void *ctx)
{
    (void)ctx;
    BD_LOGD(TAG, "ASR: %s (final=%d)", text ? text : "", is_final);
}

static void scene_on_asr_result_ext(const char *text, bool is_final,
                                     const aiagent_asr_ext_t *ext, void *ctx)
{
    (void)ctx;
    if (s_active_scene && s_active_scene->on_asr_result) {
        s_active_scene->on_asr_result(text, is_final, ext);
    }
}

static void scene_on_ai_response(const char *text, bool is_final, void *ctx)
{
    (void)ctx;
    BD_LOGD(TAG, "AI: %s (final=%d)", text ? text : "", is_final);
}

static void scene_on_audio_data(const uint8_t *data, size_t len, void *ctx)
{
    (void)ctx;
    /* 音频数据由引擎内部送入播放器 */
}

static int scene_on_function_call(const char *session_id, const char *name, const char *params, void *ctx)
{
    (void)ctx;
    if (s_active_scene && s_active_scene->on_function_call) {
        return s_active_scene->on_function_call(session_id, name, params);
    }
    return 0;
}

static void scene_on_error(aiagent_error_t code, const char *msg, void *ctx)
{
    (void)ctx;
    BD_LOGE(TAG, "error[%d]: %s", code, msg ? msg : "");
}

static void scene_on_tts_event(bool is_start, void *ctx)
{
    (void)ctx;
    BD_LOGD(TAG, "TTS %s", is_start ? "start" : "end");
}

static void scene_on_license_result(bool pass, void *ctx)
{
    (void)ctx;
    BD_LOGI(TAG, "license: %s", pass ? "PASS" : "FAIL");
}

static void scene_on_event(aiagent_event_type_t event, const char *data, size_t data_len, void *ctx)
{
    (void)ctx;
    BD_LOGD(TAG, "event: type=%d, len=%d", event, (int)data_len);
    if (s_active_scene && s_active_scene->on_event) {
        s_active_scene->on_event(event, data, data_len);
    }
}
