/**
 * @file interact_manager.c
 * @brief 交互管理器实现（策略模式）
 */

#include "interact/interact_manager.h"
#include "interact/interact_press.h"
#include "interact/interact_continuous.h"
#include "interact/interact_wakeup.h"
#include "engine_internal.h"
#include "hal_log.h"
#include <string.h>
#include <stdlib.h>

#define TAG "IM"

/* 交互管理器上下文 */
struct interact_mgr_ctx {
    const interact_mode_ops_t *current_ops;     /* 当前模式操作表 */
    aiagent_interact_mode_t    current_mode;    /* 当前交互模式 */
};

/**
 * @brief 根据模式枚举获取对应的操作表
 */
static const interact_mode_ops_t *get_mode_ops(aiagent_interact_mode_t mode)
{
    switch (mode) {
    case AIAGENT_INTERACT_PRESS:
        return &interact_press_ops;
    case AIAGENT_INTERACT_CONTINUOUS:
        return &interact_continuous_ops;
    case AIAGENT_INTERACT_WAKEUP:
        return &interact_wakeup_ops;
    default:
        /* 未知模式默认使用 Press */
        return &interact_press_ops;
    }
}

/**
 * @brief 初始化交互管理器
 *
 * 分配管理器上下文，设置默认模式并进入该模式。
 */
int interact_mgr_init(engine_internal_ctx_t *ctx, aiagent_interact_mode_t default_mode)
{
    if (!ctx) {
        BD_LOGE(TAG, "初始化失败: ctx 为空");
        return -1;
    }

    /* 分配管理器上下文 */
    interact_mgr_ctx_t *mgr = (interact_mgr_ctx_t *)malloc(sizeof(interact_mgr_ctx_t));
    if (!mgr) {
        BD_LOGE(TAG, "初始化失败: 内存分配失败");
        return -1;
    }

    memset(mgr, 0, sizeof(interact_mgr_ctx_t));
    mgr->current_mode = default_mode;
    mgr->current_ops = get_mode_ops(default_mode);

    /* 将管理器挂载到引擎上下文 */
    ctx->interact_mgr = mgr;

    /* 进入默认模式 */
    if (mgr->current_ops && mgr->current_ops->enter) {
        mgr->current_ops->enter(ctx);
    }

    BD_LOGI(TAG, "交互管理器初始化完成, 默认模式=%d(%s)",
             default_mode, mgr->current_ops ? mgr->current_ops->name : "unknown");
    return 0;
}

/**
 * @brief 切换交互模式
 *
 * 先退出当前模式，再进入目标模式。相同模式不做切换。
 */
int interact_mgr_switch_mode(engine_internal_ctx_t *ctx, aiagent_interact_mode_t mode)
{
    if (!ctx || !ctx->interact_mgr) {
        BD_LOGE(TAG, "切换模式失败: 管理器未初始化");
        return -1;
    }

    interact_mgr_ctx_t *mgr = ctx->interact_mgr;

    /* 相同模式无需切换 */
    if (mgr->current_mode == mode) {
        BD_LOGD(TAG, "模式相同(%d), 无需切换", mode);
        return 0;
    }

    /* 退出当前模式 */
    if (mgr->current_ops && mgr->current_ops->exit) {
        mgr->current_ops->exit(ctx);
    }

    /* 更新模式 */
    aiagent_interact_mode_t old_mode = mgr->current_mode;
    mgr->current_mode = mode;
    mgr->current_ops = get_mode_ops(mode);

    /* 进入新模式 */
    if (mgr->current_ops && mgr->current_ops->enter) {
        mgr->current_ops->enter(ctx);
    }

    BD_LOGI(TAG, "模式切换: %d -> %d(%s)", old_mode, mode,
             mgr->current_ops ? mgr->current_ops->name : "unknown");
    return 0;
}

/**
 * @brief 重新进入当前交互模式
 *
 * 连接就绪后重新执行当前模式的 enter()。
 */
int interact_mgr_reenter(engine_internal_ctx_t *ctx)
{
    if (!ctx || !ctx->interact_mgr) {
        return -1;
    }

    interact_mgr_ctx_t *mgr = ctx->interact_mgr;
    if (mgr->current_ops && mgr->current_ops->enter) {
        mgr->current_ops->enter(ctx);
    }

    BD_LOGI(TAG, "重新进入模式(%s)",
             mgr->current_ops ? mgr->current_ops->name : "unknown");
    return 0;
}

/**
 * @brief 获取当前交互模式
 */
aiagent_interact_mode_t interact_mgr_get_mode(engine_internal_ctx_t *ctx)
{
    if (!ctx || !ctx->interact_mgr) {
        return AIAGENT_INTERACT_PRESS;
    }
    return ctx->interact_mgr->current_mode;
}

/**
 * @brief 获取当前交互模式名称
 */
const char *interact_mgr_get_mode_name(engine_internal_ctx_t *ctx)
{
    if (!ctx || !ctx->interact_mgr || !ctx->interact_mgr->current_ops) {
        return NULL;
    }
    return ctx->interact_mgr->current_ops->name;
}

/**
 * @brief 分发按键事件到当前模式
 *
 * 根据事件类型调用对应的 on_key_press / on_key_release / on_key_long_press 回调。
 */
void interact_mgr_notify_key(engine_internal_ctx_t *ctx, interact_key_event_t event)
{
    if (!ctx || !ctx->interact_mgr || !ctx->interact_mgr->current_ops) {
        return;
    }

    const interact_mode_ops_t *ops = ctx->interact_mgr->current_ops;

    switch (event) {
    case INTERACT_KEY_PRESS:
        if (ops->on_key_press) {
            ops->on_key_press(ctx);
        }
        break;
    case INTERACT_KEY_RELEASE:
        if (ops->on_key_release) {
            ops->on_key_release(ctx);
        }
        break;
    case INTERACT_KEY_LONG_PRESS:
        if (ops->on_key_long_press) {
            ops->on_key_long_press(ctx);
        }
        break;
    default:
        BD_LOGW(TAG, "未知按键事件: %d", event);
        break;
    }
}

/**
 * @brief 分发 TTS 事件到当前模式
 *
 * @param is_start  true 表示 TTS 开始播放，false 表示 TTS 播放结束
 */
void interact_mgr_notify_tts(engine_internal_ctx_t *ctx, bool is_start)
{
    if (!ctx || !ctx->interact_mgr || !ctx->interact_mgr->current_ops) {
        return;
    }

    const interact_mode_ops_t *ops = ctx->interact_mgr->current_ops;

    if (is_start) {
        if (ops->on_tts_start) {
            ops->on_tts_start(ctx);
        }
    } else {
        if (ops->on_tts_end) {
            ops->on_tts_end(ctx);
        }
    }
}

/**
 * @brief 分发唤醒词检测事件到当前模式
 */
void interact_mgr_notify_wakeword(engine_internal_ctx_t *ctx)
{
    if (!ctx || !ctx->interact_mgr || !ctx->interact_mgr->current_ops) {
        return;
    }

    if (ctx->interact_mgr->current_ops->on_wakeword) {
        ctx->interact_mgr->current_ops->on_wakeword(ctx);
    }
}

/**
 * @brief 释放交互管理器
 *
 * 退出当前模式并释放管理器上下文内存。
 */
void interact_mgr_deinit(engine_internal_ctx_t *ctx)
{
    if (!ctx || !ctx->interact_mgr) {
        return;
    }

    interact_mgr_ctx_t *mgr = ctx->interact_mgr;

    /* 退出当前模式 */
    if (mgr->current_ops && mgr->current_ops->exit) {
        mgr->current_ops->exit(ctx);
    }

    BD_LOGI(TAG, "交互管理器已释放");

    /* 释放管理器内存 */
    free(mgr);
    ctx->interact_mgr = NULL;
}
