/**
 * @file state_machine.c
 * @brief 引擎状态机实现
 */

#include "state_machine.h"
#include "engine_internal.h"
#include "hal_mutex.h"
#include "hal_log.h"

#define TAG "SM"

/* 状态机私有上下文 (存储回调) */
static state_change_cb_t s_on_change = NULL;
static void             *s_user_ctx  = NULL;

/**
 * 状态转换表：定义每个状态下允许的事件和目标状态
 */
typedef struct {
    aiagent_state_t       from_state;
    state_machine_event_t event;
    aiagent_state_t       to_state;
} state_transition_t;

static const state_transition_t s_transitions[] = {
    /* IDLE → CONNECTING */
    { AIAGENT_STATE_IDLE,         SM_EVT_CONNECT_REQUEST,  AIAGENT_STATE_CONNECTING },

    /* WS 已连接，等待鉴权 */
    { AIAGENT_STATE_CONNECTING,   SM_EVT_CONNECTED,        AIAGENT_STATE_CONNECTING },
    /* CONNECTING → READY */
    { AIAGENT_STATE_CONNECTING,   SM_EVT_AUTH_SUCCESS,     AIAGENT_STATE_READY },
    /* CONNECTING → IDLE (连接或认证失败) */
    { AIAGENT_STATE_CONNECTING,   SM_EVT_AUTH_FAIL,        AIAGENT_STATE_IDLE },
    { AIAGENT_STATE_CONNECTING,   SM_EVT_ERROR,            AIAGENT_STATE_IDLE },
    { AIAGENT_STATE_CONNECTING,   SM_EVT_DISCONNECTED,     AIAGENT_STATE_IDLE },

    /* READY → LISTENING (开始录音/监听) */
    { AIAGENT_STATE_READY,        SM_EVT_START_LISTEN,     AIAGENT_STATE_LISTENING },
    /* READY → SPEAKING (服务端主动开始说话，如唤醒模式下的打招呼/主动回复) */
    { AIAGENT_STATE_READY,        SM_EVT_TTS_BEGIN,        AIAGENT_STATE_SPEAKING },
    /* READY → PROCESSING (服务端推送ASR结果，唤醒/持续模式下服务端做VAD) */
    { AIAGENT_STATE_READY,        SM_EVT_ASR_RESULT,       AIAGENT_STATE_PROCESSING },
    /* READY → IDLE (断开) */
    { AIAGENT_STATE_READY,        SM_EVT_DISCONNECTED,     AIAGENT_STATE_IDLE },
    { AIAGENT_STATE_READY,        SM_EVT_EXIT,             AIAGENT_STATE_EXITING },
    /* READY 吸收迟到事件 */
    { AIAGENT_STATE_READY,        SM_EVT_TTS_END,          AIAGENT_STATE_READY },
    { AIAGENT_STATE_READY,        SM_EVT_STOP_LISTEN,      AIAGENT_STATE_READY },

    /* LISTENING → PROCESSING (用户停止录音/ASR结果) */
    { AIAGENT_STATE_LISTENING,    SM_EVT_STOP_LISTEN,      AIAGENT_STATE_PROCESSING },
    { AIAGENT_STATE_LISTENING,    SM_EVT_ASR_RESULT,       AIAGENT_STATE_PROCESSING },
    /* LISTENING → LISTENING (重复start_listen忽略) */
    { AIAGENT_STATE_LISTENING,    SM_EVT_START_LISTEN,     AIAGENT_STATE_LISTENING },
    /* LISTENING → SPEAKING (AI直接开始回复) */
    { AIAGENT_STATE_LISTENING,    SM_EVT_TTS_BEGIN,        AIAGENT_STATE_SPEAKING },
    /* LISTENING → IDLE */
    { AIAGENT_STATE_LISTENING,    SM_EVT_DISCONNECTED,     AIAGENT_STATE_IDLE },
    { AIAGENT_STATE_LISTENING,    SM_EVT_TIMEOUT,          AIAGENT_STATE_READY },
    { AIAGENT_STATE_LISTENING,    SM_EVT_ERROR,            AIAGENT_STATE_READY },

    /* PROCESSING → SPEAKING (AI开始回复) */
    { AIAGENT_STATE_PROCESSING,   SM_EVT_TTS_BEGIN,        AIAGENT_STATE_SPEAKING },
    /* PROCESSING → READY (对话完成但无TTS) */
    { AIAGENT_STATE_PROCESSING,   SM_EVT_TTS_END,          AIAGENT_STATE_READY },
    { AIAGENT_STATE_PROCESSING,   SM_EVT_DISCONNECTED,     AIAGENT_STATE_IDLE },
    { AIAGENT_STATE_PROCESSING,   SM_EVT_TIMEOUT,          AIAGENT_STATE_READY },
    { AIAGENT_STATE_PROCESSING,   SM_EVT_ERROR,            AIAGENT_STATE_READY },
    /* PROCESSING 吸收迟到事件 */
    { AIAGENT_STATE_PROCESSING,   SM_EVT_ASR_RESULT,       AIAGENT_STATE_PROCESSING },
    { AIAGENT_STATE_PROCESSING,   SM_EVT_STOP_LISTEN,      AIAGENT_STATE_PROCESSING },
    { AIAGENT_STATE_PROCESSING,   SM_EVT_START_LISTEN,     AIAGENT_STATE_PROCESSING },

    /* SPEAKING → READY (AI说完) */
    { AIAGENT_STATE_SPEAKING,     SM_EVT_TTS_END,          AIAGENT_STATE_READY },
    /* SPEAKING → INTERRUPTING (用户打断) */
    { AIAGENT_STATE_SPEAKING,     SM_EVT_INTERRUPT,        AIAGENT_STATE_INTERRUPTING },
    { AIAGENT_STATE_SPEAKING,     SM_EVT_DISCONNECTED,     AIAGENT_STATE_IDLE },
    /* SPEAKING 吸收迟到事件 */
    { AIAGENT_STATE_SPEAKING,     SM_EVT_ASR_RESULT,       AIAGENT_STATE_SPEAKING },
    { AIAGENT_STATE_SPEAKING,     SM_EVT_STOP_LISTEN,      AIAGENT_STATE_SPEAKING },
    { AIAGENT_STATE_SPEAKING,     SM_EVT_START_LISTEN,     AIAGENT_STATE_SPEAKING },
    { AIAGENT_STATE_SPEAKING,     SM_EVT_TTS_BEGIN,        AIAGENT_STATE_SPEAKING },

    /* INTERRUPTING → READY (打断处理完成) */
    { AIAGENT_STATE_INTERRUPTING, SM_EVT_INTERRUPT_DONE,   AIAGENT_STATE_READY },
    /* INTERRUPTING → LISTENING (打断后立即开始录音) */
    { AIAGENT_STATE_INTERRUPTING, SM_EVT_START_LISTEN,     AIAGENT_STATE_LISTENING },
    { AIAGENT_STATE_INTERRUPTING, SM_EVT_TTS_END,          AIAGENT_STATE_READY },
    { AIAGENT_STATE_INTERRUPTING, SM_EVT_DISCONNECTED,     AIAGENT_STATE_IDLE },

    /* 任何活跃状态 → EXITING */
    { AIAGENT_STATE_READY,        SM_EVT_EXIT,             AIAGENT_STATE_EXITING },
    { AIAGENT_STATE_LISTENING,    SM_EVT_EXIT,             AIAGENT_STATE_EXITING },
    { AIAGENT_STATE_PROCESSING,   SM_EVT_EXIT,             AIAGENT_STATE_EXITING },
    { AIAGENT_STATE_SPEAKING,     SM_EVT_EXIT,             AIAGENT_STATE_EXITING },
    { AIAGENT_STATE_INTERRUPTING, SM_EVT_EXIT,             AIAGENT_STATE_EXITING },
};

#define TRANSITION_COUNT  (sizeof(s_transitions) / sizeof(s_transitions[0]))

int state_machine_init(engine_internal_ctx_t *ctx,
                       state_change_cb_t on_change,
                       void *user_ctx)
{
    if (!ctx) {
        return -1;
    }
    ctx->state = AIAGENT_STATE_IDLE;
    s_on_change = on_change;
    s_user_ctx = user_ctx;
    return 0;
}

int state_machine_post_event(engine_internal_ctx_t *ctx, state_machine_event_t event)
{
    if (!ctx) {
        return -1;
    }

    hal_mutex_lock(ctx->state_mutex);

    aiagent_state_t old_state = ctx->state;
    aiagent_state_t new_state = old_state;
    bool found = false;

    for (int i = 0; i < (int)TRANSITION_COUNT; i++) {
        if (s_transitions[i].from_state == old_state &&
            s_transitions[i].event == event) {
            new_state = s_transitions[i].to_state;
            found = true;
            break;
        }
    }

    if (!found) {
        /* 未匹配的状态转换记录为 warning */
        BD_LOGW(TAG, "invalid transition: state=%d event=%d", old_state, event);
        hal_mutex_unlock(ctx->state_mutex);
        return -1;
    }

    if (new_state == old_state) {
        hal_mutex_unlock(ctx->state_mutex);
        return 0;
    }

    ctx->state = new_state;
    hal_mutex_unlock(ctx->state_mutex);

    BD_LOGI(TAG, "state: %d -> %d (event=%d)", old_state, new_state, event);

    /* 通知回调 */
    if (s_on_change) {
        s_on_change(old_state, new_state, s_user_ctx);
    }

    return 0;
}

aiagent_state_t state_machine_get_state(engine_internal_ctx_t *ctx)
{
    if (!ctx) {
        return AIAGENT_STATE_IDLE;
    }
    return ctx->state;
}

void state_machine_reset(engine_internal_ctx_t *ctx)
{
    if (!ctx) {
        return;
    }
    hal_mutex_lock(ctx->state_mutex);
    ctx->state = AIAGENT_STATE_IDLE;
    hal_mutex_unlock(ctx->state_mutex);
    BD_LOGI(TAG, "state machine reset to IDLE");
}

void state_machine_deinit(engine_internal_ctx_t *ctx)
{
    if (!ctx) {
        return;
    }
    ctx->state = AIAGENT_STATE_IDLE;
    s_on_change = NULL;
    s_user_ctx = NULL;
    BD_LOGI(TAG, "state machine deinit");
}
