#include "application.h"
#include "board.h"
#include "wifi_board.h"
#include "display.h"
#include "system_info.h"
#include "ml307_ssl_transport.h"
#include "audio_codec.h"
#include "settings.h"
#include "mqtt_protocol.h"
#include "websocket_protocol.h"
#include "font_awesome_symbols.h"
#include "iot/thing_manager.h"
#include "assets/lang_config.h"
#include "boards/common/qmi8658a.h"  // 添加qmi8658a_data_t类型的头文件
#include "boards/movecall-moji-esp32s3/movecall_moji_esp32s3.h"  // 添加MovecallMojiESP32S3类的头文件

#include <cstring>
#include <esp_log.h>
#include <cJSON.h>
#include <driver/gpio.h>
#include <arpa/inet.h>
#include <esp_app_desc.h>
#include <cmath>  // 用于sqrt函数

#define TAG "Application"
#define MAC_TAG "WiFiMAC"


static const char* const STATE_STRINGS[] = {
    "unknown",
    "starting",
    "configuring",
    "idle",
    "connecting",
    "listening",
    "speaking",
    "upgrading",
    "activating",
    "fatal_error",
    "invalid_state"
};

Application::Application() {
    event_group_ = xEventGroupCreate();
    background_task_ = new BackgroundTask(4096 * 8);

    esp_timer_create_args_t clock_timer_args = {
        .callback = [](void* arg) {
            Application* app = (Application*)arg;
            app->OnClockTimer();
        },
        .arg = this,
        .dispatch_method = ESP_TIMER_TASK,
        .name = "clock_timer",
        .skip_unhandled_events = true
    };
    esp_timer_create(&clock_timer_args, &clock_timer_handle_);
}

Application::~Application() {
    if (clock_timer_handle_ != nullptr) {
        esp_timer_stop(clock_timer_handle_);
        esp_timer_delete(clock_timer_handle_);
    }
    if (background_task_ != nullptr) {
        delete background_task_;
    }
    vEventGroupDelete(event_group_);
}

void Application::CheckNewVersion() {
    auto& board = Board::GetInstance();
    auto display = board.GetDisplay();
    // Check if there is a new firmware version available
    ota_.SetPostData(board.GetJson());// 发送当前设备的JSON数据到OTA服务器，用于检查是否有新的固件版本 包办板载信息 BOARD_TYPE

    const int MAX_RETRY = 10;
    int retry_count = 0;

    while (true) {
        if (!ota_.CheckVersion()) {
            retry_count++;
            if (retry_count >= MAX_RETRY) {
                ESP_LOGE(TAG, "Too many retries, exit version check");
                return;
            }
            ESP_LOGW(TAG, "Check new version failed, retry in %d seconds (%d/%d)", 60, retry_count, MAX_RETRY);
            vTaskDelay(pdMS_TO_TICKS(60000));
            continue;
        }
        retry_count = 0;

        if (ota_.HasNewVersion()) {
            Alert(Lang::Strings::OTA_UPGRADE, Lang::Strings::UPGRADING, "happy", Lang::Sounds::P3_UPGRADE);
            // Wait for the chat state to be idle
            do {
                vTaskDelay(pdMS_TO_TICKS(3000));
            } while (GetDeviceState() != kDeviceStateIdle);

            // Use main task to do the upgrade, not cancelable
            Schedule([this, display]() {
                SetDeviceState(kDeviceStateUpgrading);

                display->SetIcon(FONT_AWESOME_DOWNLOAD);
                std::string message = std::string(Lang::Strings::NEW_VERSION) + ota_.GetFirmwareVersion();
                display->SetChatMessage("system", message.c_str());

                auto& board = Board::GetInstance();
                board.SetPowerSaveMode(false);// 关闭低功耗模式
#if CONFIG_USE_WAKE_WORD_DETECT || CONFIG_USE_CUSTOM_WAKE_WORD
                wake_word_detect_.Stop();
#endif
                // 预先关闭音频输出，避免升级过程有音频操作
                auto codec = board.GetAudioCodec();
                codec->EnableInput(false);
                codec->EnableOutput(false);
                {
                    std::lock_guard<std::mutex> lock(mutex_);
                    audio_decode_queue_.clear();
                }
                background_task_->WaitForCompletion();
                delete background_task_;
                background_task_ = nullptr;
                vTaskDelay(pdMS_TO_TICKS(1000));

                ota_.StartUpgrade([display](int progress, size_t speed) {
                    char buffer[64];
                    snprintf(buffer, sizeof(buffer), "%d%% %zuKB/s", progress, speed / 1024);
                    display->SetChatMessage("system", buffer);
                });

                // If upgrade success, the device will reboot and never reach here
                display->SetStatus(Lang::Strings::UPGRADE_FAILED);
                ESP_LOGI(TAG, "Firmware upgrade failed...");
                vTaskDelay(pdMS_TO_TICKS(3000));
                Reboot();
            });

            return;
        }

        // No new version, mark the current version as valid
        ota_.MarkCurrentVersionValid();
        std::string message = std::string(Lang::Strings::VERSION) + ota_.GetCurrentVersion();
        display->ShowNotification(message.c_str());

        // 检查是否有设备激活码
        // if (ota_.HasActivationCode()) {
        //     // Activation code is valid
        //     SetDeviceState(kDeviceStateActivating);//设置设备状态为激活中
        //     // ShowActivationCode();//显示设备激活码

        //     // Check again in 60 seconds or until the device is idle
        //     for (int i = 0; i < 60; ++i) {
        //         if (device_state_ == kDeviceStateIdle) {
        //             break;
        //         }
        //         vTaskDelay(pdMS_TO_TICKS(1000));
        //     }
        //     continue;
        // }

        SetDeviceState(kDeviceStateIdle);
        display->SetChatMessage("system", "");
        ResetDecoder();
        PlaySound(Lang::Sounds::P3_SUCCESS);
        // Exit the loop if upgrade or idle
        break;
    }
}

// 取消设备激活码播报,当前设备绑定使用Wi-Fi的Mac地址进行绑定
// void Application::ShowActivationCode() {
//     auto& message = ota_.GetActivationMessage();
//     auto& code = ota_.GetActivationCode();

//     struct digit_sound {
//         char digit;
//         const std::string_view& sound;
//     };
//     static const std::array<digit_sound, 10> digit_sounds{{
//         digit_sound{'0', Lang::Sounds::P3_0},
//         digit_sound{'1', Lang::Sounds::P3_1}, 
//         digit_sound{'2', Lang::Sounds::P3_2},
//         digit_sound{'3', Lang::Sounds::P3_3},
//         digit_sound{'4', Lang::Sounds::P3_4},
//         digit_sound{'5', Lang::Sounds::P3_5},
//         digit_sound{'6', Lang::Sounds::P3_6},
//         digit_sound{'7', Lang::Sounds::P3_7},
//         digit_sound{'8', Lang::Sounds::P3_8},
//         digit_sound{'9', Lang::Sounds::P3_9}
//     }};

//     // This sentence uses 9KB of SRAM, so we need to wait for it to finish
//     Alert(Lang::Strings::ACTIVATION, message.c_str(), "happy", Lang::Sounds::P3_ACTIVATION);
//     vTaskDelay(pdMS_TO_TICKS(1000));
//     background_task_->WaitForCompletion();

//     for (const auto& digit : code) {
//         auto it = std::find_if(digit_sounds.begin(), digit_sounds.end(),
//             [digit](const digit_sound& ds) { return ds.digit == digit; });
//         if (it != digit_sounds.end()) {
//             PlaySound(it->sound);
//         }
//     }
// }

// 新增代码(小程序控制 暂停播放 音频)
// =========================================================
void Application::PauseAudioPlayback() {
    std::unique_lock<std::mutex> lock(mutex_);
    if (!audio_paused_) {
        audio_paused_ = true;// 暂停播放(更新标志位)
        ESP_LOGI(TAG, "🔇 从服务器接收到暂停播放指令");

        // 恢复原始处理方式：立即停止音频输出
        auto codec = Board::GetInstance().GetAudioCodec();
        if (codec) {
            codec->EnableOutput(false);// 暂停时立即停止音频输出
            ESP_LOGI(TAG, "⏸️ 音频编解码器输出已禁用，实现立即暂停");
        }
        ESP_LOGI(TAG, "⏸️ 音频播放已暂停");
    }
}
// 新增代码(小程序控制 继续播放 音频)
void Application::ResumeAudioPlayback() {
    std::unique_lock<std::mutex> lock(mutex_);
    if (audio_paused_) {
        audio_paused_ = false;// 恢复播放(更新标志位)
        ESP_LOGI(TAG, "� 从服务器接收到继续播放指令");

        // 恢复原始处理方式：重新启用音频输出
        auto codec = Board::GetInstance().GetAudioCodec();
        if (codec) {
            codec->EnableOutput(true);// 恢复时重新启用音频输出
            ESP_LOGI(TAG, "▶️ 音频编解码器输出已启用");
        }
        ESP_LOGI(TAG, "▶️ 音频播放已恢复");
    }
}
// =========================================================

void Application::Alert(const char* status, const char* message, const char* emotion, const std::string_view& sound) {
    ESP_LOGW(TAG, "Alert %s: %s [%s]", status, message, emotion);
    auto display = Board::GetInstance().GetDisplay();
    display->SetStatus(status);
    display->SetEmotion(emotion);
    display->SetChatMessage("system", message);
    if (!sound.empty()) {
        ResetDecoder();
        PlaySound(sound);
    }
}

void Application::DismissAlert() {
    if (device_state_ == kDeviceStateIdle) {
        auto display = Board::GetInstance().GetDisplay();
        display->SetStatus(Lang::Strings::STANDBY);
        display->SetEmotion("neutral");
        display->SetChatMessage("system", "");
    }
}

void Application::PlaySound(const std::string_view& sound) {
    // The assets are encoded at 16000Hz, 60ms frame duration
    SetDecodeSampleRate(16000, 60);
    const char* data = sound.data();
    size_t size = sound.size();
    for (const char* p = data; p < data + size; ) {
        auto p3 = (BinaryProtocol3*)p;
        p += sizeof(BinaryProtocol3);

        auto payload_size = ntohs(p3->payload_size);
        std::vector<uint8_t> opus;
        opus.resize(payload_size);
        memcpy(opus.data(), p3->payload, payload_size);
        p += payload_size;

        std::lock_guard<std::mutex> lock(mutex_);
        audio_decode_queue_.emplace_back(std::move(opus));
    }
}

// 切换聊天状态的函数，用于在不同的设备状态之间进行切换
void Application::ToggleChatState() {
    // 如果当前设备状态是激活中，则将状态设置为空闲并返回
    if (device_state_ == kDeviceStateActivating) {
        SetDeviceState(kDeviceStateIdle);  // 设置设备状态为空闲
        return;  // 直接返回，不执行后续逻辑
    }

    // 检查协议对象是否已初始化
    if (!protocol_) {
        ESP_LOGE(TAG, "Protocol not initialized");  // 记录错误日志：协议未初始化
        return;  // 协议未初始化则直接返回
    }

    // 如果当前设备状态是idle空闲，则尝试开始聊天
    if (device_state_ == kDeviceStateIdle) {
        // 使用Schedule函数异步执行以下操作
        Schedule([this]() {
            SetDeviceState(kDeviceStateConnecting);  // 设置设备状态为连接中
            ESP_LOGI(TAG, "Attempting to open audio channel");  // 记录信息日志：尝试打开音频通道

            // 尝试打开音频通道
            if (!protocol_->OpenAudioChannel()) {
                ESP_LOGW(TAG, "Failed to open audio channel, will retry in 2 seconds");  // 记录警告日志：打开音频通道失败
                SetDeviceState(kDeviceStateIdle);  // 将设备状态重新设置为空闲

                // 2秒后自动重试
                Schedule([this]() {
                    vTaskDelay(pdMS_TO_TICKS(2000));  // 延迟2000毫秒（2秒）
                    ESP_LOGI(TAG, "Retrying audio channel connection");  // 记录信息日志：重试音频通道连接
                    ToggleChatState();  // 递归调用自身，重新尝试切换聊天状态
                });
                return;  // 返回，不执行后续的SetListeningMode
            }

            // 音频通道打开成功，根据实时聊天是否启用来设置监听模式
            SetListeningMode(realtime_chat_enabled_ ? kListeningModeRealtime : kListeningModeAutoStop);
        });
    } else if (device_state_ == kDeviceStateSpeaking) {  // 如果当前设备状态是说话中
        // 异步执行中止说话操作
        Schedule([this]() {
            AbortSpeaking(kAbortReasonNone);  // 中止说话，原因为无特定原因
        });
    } else if (device_state_ == kDeviceStateListening) {  // 如果当前设备状态是监听中
        // 异步执行关闭音频通道操作
        Schedule([this]() {
            protocol_->CloseAudioChannel();  // 关闭音频通道
        });
    }
}

void Application::ToggleListeningState() {
    if (device_state_ == kDeviceStateActivating) {
        SetDeviceState(kDeviceStateIdle);
        return;
    }

    if (!protocol_) {
        ESP_LOGE(TAG, "Protocol not initialized");
        return;
    }

    // 简单的状态切换：idle <-> listening
    if (device_state_ == kDeviceStateIdle) {
        // 从待命状态进入聆听状态
        Schedule([this]() {
            SetDeviceState(kDeviceStateConnecting);
            if (!protocol_->OpenAudioChannel()) {
                return;
            }
            SetListeningMode(kListeningModeManualStop);
            ESP_LOGI(TAG, "Interrupt button: Entering listening state");
        });
    } else if (device_state_ == kDeviceStateListening) {
        // 从聆听状态返回待命状态
        Schedule([this]() {
            protocol_->CloseAudioChannel();
            ESP_LOGI(TAG, "Interrupt button: Returning to idle state");
        });
    } else if (device_state_ == kDeviceStateSpeaking) {
        // 如果正在说话，中止说话并返回待命状态
        Schedule([this]() {
            AbortSpeaking(kAbortReasonNone);
            ESP_LOGI(TAG, "Interrupt button: Stopping speech and returning to idle state");
        });
    } else if (device_state_ == kDeviceStateConnecting) {
        // 如果正在连接，直接返回待命状态
        Schedule([this]() {
            SetDeviceState(kDeviceStateIdle);
            ESP_LOGI(TAG, "Interrupt button: Canceling connection and returning to idle state");
        });
    }
}

void Application::StartListening() {
    if (device_state_ == kDeviceStateActivating) {
        SetDeviceState(kDeviceStateIdle);
        return;
    }

    if (!protocol_) {
        ESP_LOGE(TAG, "Protocol not initialized");
        return;
    }

    if (device_state_ == kDeviceStateIdle) {
        Schedule([this]() {
            if (!protocol_->IsAudioChannelOpened()) {
                SetDeviceState(kDeviceStateConnecting);
                if (!protocol_->OpenAudioChannel()) {
                    return;
                }
            }

            SetListeningMode(kListeningModeManualStop);
        });
    } else if (device_state_ == kDeviceStateSpeaking) {
        Schedule([this]() {
            AbortSpeaking(kAbortReasonNone);
            SetListeningMode(kListeningModeManualStop);
        });
    }
}

void Application::StopListening() {
    Schedule([this]() {
        if (device_state_ == kDeviceStateListening) {
            protocol_->SendStopListening();
            SetDeviceState(kDeviceStateIdle);
        }
    });
}

void Application::SendTextMessage(const std::string& text) {
    if (!protocol_) {
        ESP_LOGE(TAG, "Protocol not initialized");
        return;
    }

    if (device_state_ == kDeviceStateIdle) {
        Schedule([this, text]() {
            SetDeviceState(kDeviceStateConnecting);
            if (!protocol_->OpenAudioChannel()) {
                return;
            }

            // 发送文本消息
            protocol_->SendTextMessage(text);
            ESP_LOGI(TAG, "Sent text message: %s", text.c_str());

            // 立即启动监听模式以接收语音回复
            ESP_LOGI(TAG, "realtime_chat_enabled_=%s", realtime_chat_enabled_ ? "true" : "false");
            SetListeningMode(realtime_chat_enabled_ ? kListeningModeRealtime : kListeningModeManualStop);
        });
    } else if (device_state_ == kDeviceStateSpeaking) {
        Schedule([this, text]() {
            AbortSpeaking(kAbortReasonNone);
            protocol_->SendTextMessage(text);
            ESP_LOGI(TAG, "Sent text message: %s", text.c_str());

            // 启动监听模式以接收语音回复
            ESP_LOGI(TAG, "realtime_chat_enabled_=%s", realtime_chat_enabled_ ? "true" : "false");
            SetListeningMode(realtime_chat_enabled_ ? kListeningModeRealtime : kListeningModeManualStop);
        });
    } else if (device_state_ == kDeviceStateListening) {
        Schedule([this, text]() {
            protocol_->SendTextMessage(text);
            ESP_LOGI(TAG, "Sent text message: %s", text.c_str());
        });
    }
}

void Application::Start() {
    auto& board = Board::GetInstance();
    SetDeviceState(kDeviceStateStarting);

    /* Setup the display */
    auto display = board.GetDisplay();

    /* Setup the audio codec */
    auto codec = board.GetAudioCodec();
    opus_decoder_ = std::make_unique<OpusDecoderWrapper>(codec->output_sample_rate(), 1, OPUS_FRAME_DURATION_MS);
    opus_encoder_ = std::make_unique<OpusEncoderWrapper>(16000, 1, OPUS_FRAME_DURATION_MS);
    if (realtime_chat_enabled_) {
        ESP_LOGI(TAG, "Realtime chat enabled, setting opus encoder complexity to 0");
        opus_encoder_->SetComplexity(0);
    } else if (board.GetBoardType() == "ml307") {
        ESP_LOGI(TAG, "ML307 board detected, setting opus encoder complexity to 5");
        opus_encoder_->SetComplexity(5);
    } else {
        ESP_LOGI(TAG, "WiFi board detected, setting opus encoder complexity to 3");
        opus_encoder_->SetComplexity(3);
    }

    if (codec->input_sample_rate() != 16000) {
        input_resampler_.Configure(codec->input_sample_rate(), 16000);
        reference_resampler_.Configure(codec->input_sample_rate(), 16000);
    }
    codec->Start();
    {
        int battery_level = 0;
        bool charging = false;
        bool discharging = false;
        if (board.GetBatteryLevel(battery_level, charging, discharging)) {
            // 如果电池电量低于25%，则将输出音量设置为0（静音）
            if (battery_level <= 25) {
                codec->SetOutputVolumeRuntime(0);
            } else {
                Settings s("audio", false);
                int vol = s.GetInt("output_volume", AudioCodec::default_output_volume());
                if (vol <= 0) {
                    vol = AudioCodec::default_output_volume();
                }
                codec->SetOutputVolumeRuntime(vol);// 设置运行时输出音量
            }
        }
    }

    xTaskCreatePinnedToCore([](void* arg) {
        Application* app = (Application*)arg;
        app->AudioLoop();
        vTaskDelete(NULL);
    }, "audio_loop", 4096 * 2, this, 8, &audio_loop_task_handle_, realtime_chat_enabled_ ? 1 : 0);

    /* Start the main loop */
    xTaskCreatePinnedToCore([](void* arg) {
        Application* app = (Application*)arg;
        app->MainLoop();
        vTaskDelete(NULL);
    }, "main_loop", 4096 * 2, this, 4, &main_loop_task_handle_, 0);

    // 播放开机播报语音 - 在网络连接之前
    ESP_LOGI(TAG, "设备启动完成，正在播放开机音效！");
    //PlaySound(Lang::Sounds::P3_KAIJIBOBAO); 原有蜡笔小新音色

    if(strcmp(CONFIG_DEVICE_ROLE, "KAKA") == 0){
        PlaySound(Lang::Sounds::P3_KAKA_KAIJIBOBAO);
    }
    else if(strcmp(CONFIG_DEVICE_ROLE, "LALA") == 0){
        PlaySound(Lang::Sounds::P3_LALA_KAIJIBOBAO);
    }

    /* Wait for the network to be ready */
    board.StartNetwork();

    // Initialize the protocol
    display->SetStatus(Lang::Strings::LOADING_PROTOCOL);
#ifdef CONFIG_CONNECTION_TYPE_WEBSOCKET
    protocol_ = std::make_unique<WebsocketProtocol>();
#else
    protocol_ = std::make_unique<MqttProtocol>();
#endif
    protocol_->OnNetworkError([this](const std::string& message) {
        // SetDeviceState(kDeviceStateIdle);
        // Alert(Lang::Strings::ERROR, message.c_str(), "sad", Lang::Sounds::P3_EXCLAMATION);

        ESP_LOGW(TAG, "Network error occurred: %s", message.c_str());
        // 检查是否是TLS连接重置错误
        if (message.find("TLS") != std::string::npos || message.find("-76") != std::string::npos) {
            ESP_LOGI(TAG, "TLS connection reset detected, will retry connection");
            SetDeviceState(kDeviceStateIdle);

            // 3秒后自动重试连接
            Schedule([this]() {
                vTaskDelay(pdMS_TO_TICKS(3000));
                if (GetDeviceState() == kDeviceStateIdle) {
                    ESP_LOGI(TAG, "Auto-retrying connection after TLS error");
                    ToggleChatState();
                }
            });
        } else {
            // 其他网络错误正常处理
            SetDeviceState(kDeviceStateIdle);
            Alert(Lang::Strings::ERROR, message.c_str(), "sad", Lang::Sounds::P3_EXCLAMATION);
        }
    });
    protocol_->OnIncomingAudio([this](std::vector<uint8_t>&& data) {
        std::lock_guard<std::mutex> lock(mutex_);
        audio_decode_queue_.emplace_back(std::move(data));
    });
    protocol_->OnAudioChannelOpened([this, codec, &board]() {
        ESP_LOGI(TAG, "🟢 音频通道已打开");

        // 🔧 关键修复：立即取消所有待执行的电源管理任务
        static TaskHandle_t power_save_task = nullptr;
        if (power_save_task != nullptr) {
            vTaskDelete(power_save_task);
            power_save_task = nullptr;
            ESP_LOGI(TAG, "🔧 取消了待执行的电源管理任务");
        }

        // 唤醒PowerSaveTimer，从低功耗模式恢复到正常模式
        board.WakeUp();

        // 立即禁用电源管理，确保连接稳定
        ESP_LOGI(TAG, "🔄 禁用电源低功耗管理模式");
        board.SetPowerSaveMode(false);

        if (protocol_->server_sample_rate() != codec->output_sample_rate()) {
            ESP_LOGW(TAG, "⚠️ 服务器采样率 %d 与设备输出采样率 %d 不匹配，重采样可能导致失真",
                protocol_->server_sample_rate(), codec->output_sample_rate());
        }

        SetDecodeSampleRate(protocol_->server_sample_rate(), protocol_->server_frame_duration());

        // 发送IoT状态信息
        auto& thing_manager = iot::ThingManager::GetInstance();
        protocol_->SendIotDescriptors(thing_manager.GetDescriptorsJson());
        std::string states;
        if (thing_manager.GetStatesJson(states, false)) {
            protocol_->SendIotStates(states);
        }

        ESP_LOGI(TAG, "🟢 音频通道初始化完成");
    });
    protocol_->OnAudioChannelClosed([this, &board]() {
        ESP_LOGI(TAG, "🔴 音频通道关闭，开始清理任务");

        // 🔧 关键修复：取消所有待执行的电源管理任务，防止时序冲突
        static TaskHandle_t power_save_task = nullptr;
        if (power_save_task != nullptr) {
            vTaskDelete(power_save_task);
            power_save_task = nullptr;
            ESP_LOGI(TAG, "🔧 取消了之前的电源管理任务，防止时序冲突");
        }

        // 音频处理器已经在WebSocket断开时停止了
        // 等待所有后台任务完成
        background_task_->WaitForCompletion();
        ESP_LOGI(TAG, "🔴 后台任务完成");

        // 🔧 方案2：先设置设备状态，再启用电源管理，避免时序问题
        Schedule([this, &board]() {
            ESP_LOGI(TAG, "🔄 设置设备为空闲状态");
            auto display = Board::GetInstance().GetDisplay();
            display->SetChatMessage("system", "");
            SetDeviceState(kDeviceStateIdle);

            // 状态设置完成后，再启用电源管理
            vTaskDelay(pdMS_TO_TICKS(100));
            ESP_LOGI(TAG, "🔄 设备已稳定在idle状态，启用电源低功耗管理");
            try {
                board.SetPowerSaveMode(true);
            } catch (...) {
                ESP_LOGE(TAG, "❌ 设置电源管理模式失败");
            }
        });
    });
    protocol_->OnIncomingJson([this, display](const cJSON* root) {
        // Parse JSON data
        auto type = cJSON_GetObjectItem(root, "type");
        if (strcmp(type->valuestring, "tts") == 0) {
            auto state = cJSON_GetObjectItem(root, "state");
            if (strcmp(state->valuestring, "start") == 0) {
                Schedule([this]() {
                    aborted_ = false;
                    if (device_state_ == kDeviceStateIdle || device_state_ == kDeviceStateListening) {
                        SetDeviceState(kDeviceStateSpeaking);
                    }
                });
            } else if (strcmp(state->valuestring, "stop") == 0) {
                Schedule([this]() {
                    background_task_->WaitForCompletion();
                    if (device_state_ == kDeviceStateSpeaking) {
                        if (listening_mode_ == kListeningModeManualStop) {
                            SetDeviceState(kDeviceStateIdle);
                        } else {
                            SetDeviceState(kDeviceStateListening);
                        }
                    }
                });
            } else if (strcmp(state->valuestring, "sentence_start") == 0) {
                auto text = cJSON_GetObjectItem(root, "text");
                if (text != NULL) {
                    ESP_LOGI(TAG, "<< %s", text->valuestring);
                    Schedule([this, display, message = std::string(text->valuestring)]() {
                        display->SetChatMessage("assistant", message.c_str());
                    });
                }
            }
        } else if (strcmp(type->valuestring, "stt") == 0) {
            auto text = cJSON_GetObjectItem(root, "text");
            if (text != NULL) {
                ESP_LOGI(TAG, ">> %s", text->valuestring);
                Schedule([this, display, message = std::string(text->valuestring)]() {
                    display->SetChatMessage("user", message.c_str());
                });
            }
        } else if (strcmp(type->valuestring, "llm") == 0) {
            auto emotion = cJSON_GetObjectItem(root, "emotion");
            if (emotion != NULL) {
                Schedule([this, display, emotion_str = std::string(emotion->valuestring)]() {
                    display->SetEmotion(emotion_str.c_str());
                });
            }
        } else if (strcmp(type->valuestring, "iot") == 0) {
            auto commands = cJSON_GetObjectItem(root, "commands");
            if (commands != NULL) {
                auto& thing_manager = iot::ThingManager::GetInstance();
                for (int i = 0; i < cJSON_GetArraySize(commands); ++i) {
                    auto command = cJSON_GetArrayItem(commands, i);
                    thing_manager.Invoke(command);
                }
            }
        // 新增代码(小程序控制 暂停/继续播放 音频)
        // ====================================================================
        } 
        else if (strcmp(type->valuestring, "music_control") == 0) {
            auto action = cJSON_GetObjectItem(root, "action");
            if (action && cJSON_IsString(action) && strcmp(action->valuestring, "pause") == 0) {
                // 只有在speaking状态下才响应暂停指令
                if (device_state_ == kDeviceStateSpeaking) {
                    ESP_LOGI(TAG, "🔇 从服务器接收到暂停播放指令 (speaking状态)");
                    Schedule([this]() {
                        PauseAudioPlayback();// 暂停播放
                    });
                } else {
                    ESP_LOGI(TAG, "🔇 收到暂停指令但设备不在speaking状态，忽略指令 (当前状态: %s)", STATE_STRINGS[device_state_]);
                }
            } else if (action && cJSON_IsString(action) && strcmp(action->valuestring, "resume") == 0) {
                // 只有在speaking状态下才响应恢复播放指令
                if (device_state_ == kDeviceStateSpeaking) {
                    ESP_LOGI(TAG, "🔊 从服务器接收到继续播放指令 (speaking状态)");
                    Schedule([this]() {
                        ResumeAudioPlayback();// 恢复播放
                    });
                } else {
                    ESP_LOGI(TAG, "🔊 收到恢复播放指令但设备不在speaking状态，忽略指令 (当前状态: %s)", STATE_STRINGS[device_state_]);
                }
            } else if (action && cJSON_IsString(action) && strcmp(action->valuestring, "play") == 0) {
                // 处理新故事推送 - 确保在音频暂停状态和播放状态下都能正常播放
                ESP_LOGI(TAG, "🎵 从服务器接收到新故事推送指令 (action: play)");
                Schedule([this]() {
                    // 参考 AbortSpeakingAndReturnToListening 第1583-1651行的逻辑
                    // 检查并处理音频暂停状态，确保新故事能正常播放
                    if (audio_paused_) {
                        ESP_LOGI(TAG, "🔵 检测到音频暂停状态，为新故事推送清除暂停状态");
                        audio_paused_ = false;
                        ESP_LOGI(TAG, "✅ 音频暂停状态已清除");

                        // 清空音频播放队列，避免播放暂停时残留的音频
                        std::unique_lock<std::mutex> lock(mutex_);
                        audio_decode_queue_.clear();
                        lock.unlock();
                        ESP_LOGI(TAG, "🧹 已清空音频播放队列，避免播放残留音频");

                        // 重新启用音频编解码器输出
                        auto& board = Board::GetInstance();
                        auto codec = board.GetAudioCodec();
                        if (codec) {
                            codec->EnableOutput(true);
                            ESP_LOGI(TAG, "🔧 为新故事推送重新启用音频编解码器输出");
                        }
                    }

                    // 如果当前在播放状态，也需要清空队列确保新故事能正常播放
                    if (device_state_ == kDeviceStateSpeaking) {
                        ESP_LOGI(TAG, "🔵 当前在播放状态，为新故事推送清空音频队列");
                        std::unique_lock<std::mutex> lock(mutex_);
                        audio_decode_queue_.clear();
                        lock.unlock();
                        ESP_LOGI(TAG, "🧹 已清空音频播放队列，准备播放新故事");

                        // 确保音频编解码器输出已启用
                        auto& board = Board::GetInstance();
                        auto codec = board.GetAudioCodec();
                        if (codec) {
                            codec->EnableOutput(true);
                            ESP_LOGI(TAG, "🔧 确保音频编解码器输出已启用");
                        }
                    }

                    ESP_LOGI(TAG, "🎵 新故事推送处理完成，音频系统已准备就绪");
                });
            }
        } 
        // ====================================================================
    });
    protocol_->Start();

    // Check for new firmware version or get the MQTT broker address
    ota_.SetCheckVersionUrl(CONFIG_OTA_VERSION_URL);
    ota_.SetHeader("Device-Id", SystemInfo::GetMacAddress().c_str());
    ota_.SetHeader("Client-Id", board.GetUuid());
    ota_.SetHeader("Accept-Language", Lang::CODE);
    auto app_desc = esp_app_get_description();
    ota_.SetHeader("User-Agent", std::string(BOARD_NAME "/") + app_desc->version);

    // 禁用自动OTA升级更新 - 注释掉下面的任务创建 
    xTaskCreate([](void* arg) {
        Application* app = (Application*)arg;
        app->CheckNewVersion();
        vTaskDelete(NULL);
    }, "check_new_version", 4096 * 2, this, 2, nullptr);


#if CONFIG_USE_AUDIO_PROCESSOR
    audio_processor_.Initialize(codec, realtime_chat_enabled_);

    // 🎯 根据语音打断功能启用状态配置VAD参数
    EchoAwareVadParams enhanced_params;
    if (realtime_chat_enabled_) {
        // 语音打断功能启用：配置增强的回声感知参数 - 基于小智AI官方优化方案
        // 🎯 平衡配置 - 防误触发同时保证音频流畅
        enhanced_params.snr_threshold = 60.0f;      // 平衡基础阈值：足够严格但不过度
        enhanced_params.min_silence_ms = 2000;      // 平衡静音要求：2秒
        enhanced_params.interrupt_cooldown_ms = 10000; // 平衡冷却时间：10秒
        enhanced_params.adaptive_threshold = true;   // 启用自适应阈值

        // 🔊 平衡噪声抑制参数 - 优化性能与效果
        enhanced_params.adaptive_noise_suppression = true;  // 启用自适应噪声抑制
        enhanced_params.noise_suppression_base = 5.0f;      // 平衡基础抑制强度
        enhanced_params.volume_sensitivity = 3.0f;          // 平衡音量敏感度：适度的音量影响
        enhanced_params.echo_detection_threshold = 0.15f;   // 平衡回声检测阈值
        enhanced_params.distance_estimation_factor = 3.0f;  // 平衡距离估算因子
        ESP_LOGI(TAG, "🎯 Adaptive noise suppression enabled for realtime chat - smart volume/distance adjustment");
    } else {
        // 🔧 语音打断功能禁用：关闭复杂VAD，只使用简单VAD
        enhanced_params.adaptive_threshold = false;   // 禁用自适应阈值
        enhanced_params.adaptive_noise_suppression = false;  // 禁用自适应噪声抑制
        ESP_LOGI(TAG, "🔧 Using simple VAD for basic voice detection - complex echo-aware VAD disabled");
    }
    audio_processor_.SetEchoAwareParams(enhanced_params);

    audio_processor_.OnOutput([this](std::vector<int16_t>&& data) {
        background_task_->Schedule([this, data = std::move(data)]() mutable {
            opus_encoder_->Encode(std::move(data), [this](std::vector<uint8_t>&& opus) {
                Schedule([this, opus = std::move(opus)]() {
                    protocol_->SendAudio(opus);
                });
            });
        });
    });
    // 🎯 根据语音打断功能启用状态选择VAD类型
    if (realtime_chat_enabled_) {
        // 语音打断功能启用：使用复杂的回声感知VAD
        audio_processor_.OnVadStateChange([this](bool speaking) {
            ESP_LOGI(TAG, "Complex VAD state change: speaking=%s, device_state=%d, listening_mode=%d", 
                     speaking ? "true" : "false", (int)device_state_, (int)listening_mode_);

            if (device_state_ == kDeviceStateListening) {
                Schedule([this, speaking]() {
                    if (speaking) {
                        voice_detected_ = true;
                    } else {
                        voice_detected_ = false;
                    }
                    auto led = Board::GetInstance().GetLed();
                    led->OnStateChanged();
                });
            }
        });
    }

    // 🔧 简单VAD：用于普通业务（触摸忽略、LED状态等）
    audio_processor_.OnSimpleVadStateChange([this](bool speaking) {
        ESP_LOGI(TAG, "Simple VAD state change: speaking=%s, device_state=%d", 
                 speaking ? "true" : "false", (int)device_state_);

        if (device_state_ == kDeviceStateListening) {
            Schedule([this, speaking]() {
                if (speaking) {
                    voice_detected_ = true;
                } else {
                    voice_detected_ = false;
                }
                auto led = Board::GetInstance().GetLed();
                led->OnStateChanged();
            });
        }

        // 🔊 语音打断逻辑：只在简单VAD中处理，因为复杂VAD可能过于严格
        if (device_state_ == kDeviceStateSpeaking && listening_mode_ == kListeningModeRealtime) {
            Schedule([this, speaking]() {
                static auto speech_start_time = std::chrono::steady_clock::now();
                static bool speech_confirmation_pending = false;
                auto now = std::chrono::steady_clock::now();

                if (speaking) {
                    // 小智AI方案：检测到人声开始，启动确认流程
                    speech_start_time = now;
                    speech_confirmation_pending = true;
                    ESP_LOGD(TAG, "Human voice detected during playback, starting interrupt evaluation");
                } else if (speech_confirmation_pending) {
                    // 小智AI方案：人声结束，评估是否触发打断
                    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - speech_start_time);

                    // 🎯 平衡自适应打断策略：防误触发同时保证响应性
                    // 基础持续时间：3秒，平衡根据干扰情况调整
                    int required_duration = 3000; // 基础要求3秒

                    // 🔊 根据当前音量动态调整持续时间要求（平衡策略）
                    if (current_speaker_volume_ > 0.4f) {
                        required_duration = 5000; // 高音量：5秒
                    } else if (current_speaker_volume_ > 0.1f) {
                        required_duration = 4000; // 中音量：4秒
                    }
                    // 低音量或静音：保持3秒

                    if (duration.count() >= required_duration) {
                        static auto last_interrupt_time = std::chrono::steady_clock::now();
                        auto interrupt_duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_interrupt_time);

                        // 🎯 平衡自适应多重保护机制：防误触发同时保证性能
                        bool volume_protection = (current_speaker_volume_ > 0.01f); // 平衡音量保护：1%阈值
                        bool cooldown_protection = (interrupt_duration.count() <= 10000); // 平衡冷却：10秒
                        static int false_positive_count = 0; // 误触发计数器

                        // 🎯 平衡连续误触发保护：适度学习机制
                        if (interrupt_duration.count() <= 20000) { // 20秒内的误触发相关
                            false_positive_count++;
                        } else if (interrupt_duration.count() > 60000) { // 60秒后开始衰减
                            false_positive_count = std::max(false_positive_count - 1, 0); // 适度衰减
                        }

                        bool consecutive_protection = (false_positive_count >= 2); // 2次误触发后保护

                        if (!volume_protection && !cooldown_protection && !consecutive_protection) {
                            // 小智AI核心逻辑：StopPlayback -> SetDeviceState(Listening)
                            ESP_LOGI(TAG, "🎯 Adaptive voice interrupt triggered (duration: %.0fms/%dms, vol: %.3f) - stopping playback", 
                                    (float)duration.count(), required_duration, current_speaker_volume_);
                            AbortSpeaking(kAbortReasonVoiceInterrupt);
                            SetDeviceState(kDeviceStateListening);
                            last_interrupt_time = now;
                        } else {
                            ESP_LOGI(TAG, "🎯 Adaptive interrupt suppressed - vol_protection: %s (%.3f), cooldown: %.0fms, consecutive: %d", 
                                    volume_protection ? "true" : "false", current_speaker_volume_,
                                    10000.0f - (float)interrupt_duration.count(), false_positive_count);
                        }
                    } else {
                        ESP_LOGI(TAG, "🎯 Voice too brief (%.0fms), likely echo or noise - adaptive threshold: %dms", 
                                (float)duration.count(), required_duration);
                    }
                    speech_confirmation_pending = false;
                }
            });
        }
    });
#endif

#if CONFIG_USE_WAKE_WORD_DETECT || CONFIG_USE_CUSTOM_WAKE_WORD
    if (!wake_word_detect_.Initialize(codec)) {
        ESP_LOGE(TAG, "Failed to initialize wake word detection");
        return;
    }
    wake_word_detect_.OnWakeWordDetected([this](const std::string& wake_word) {
        Schedule([this, &wake_word]() {
            if (device_state_ == kDeviceStateIdle) {
                SetDeviceState(kDeviceStateConnecting);
                wake_word_detect_.EncodeWakeWordData();
                // 打开音频通道并发送唤醒词数据到服务器
                if (!protocol_->OpenAudioChannel()) {
                    wake_word_detect_.Start();
                    return;
                }
                // 编码并发送唤醒词音频数据
                std::vector<uint8_t> opus;
                // Encode and send the wake word data to the server
                while (wake_word_detect_.GetWakeWordOpus(opus)) {
                    protocol_->SendAudio(opus);
                }
                // Set the chat state to wake word detected
                protocol_->SendWakeWordDetected(wake_word);
                ESP_LOGI(TAG, "Wake word detected: %s", wake_word.c_str());
                SetListeningMode(realtime_chat_enabled_ ? kListeningModeRealtime : kListeningModeAutoStop);
            } else if (device_state_ == kDeviceStateSpeaking) {
                AbortSpeaking(kAbortReasonWakeWordDetected);
            } else if (device_state_ == kDeviceStateActivating) {
                SetDeviceState(kDeviceStateIdle);
            }
        });
    });
    wake_word_detect_.Start();
#endif

    SetDeviceState(kDeviceStateIdle);
    esp_timer_start_periodic(clock_timer_handle_, 1000000);

#if 0
    while (true) {
        SystemInfo::PrintRealTimeStats(pdMS_TO_TICKS(1000));
        vTaskDelay(pdMS_TO_TICKS(10000));
    }
#endif
}
// 时钟定时器回调函数
void Application::OnClockTimer() {
    clock_ticks_++;

    // Print the debug info every 10 seconds
    if (clock_ticks_ % 10 == 0) {
        int free_sram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
        int min_free_sram = heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL);
        ESP_LOGI(TAG, "Free internal: %u minimal internal: %u", free_sram, min_free_sram);
        // // 打印Wi-Fi的Mac地址
        // ESP_LOGI(MAC_TAG, "Wi-Fi MAC Address: %s", SystemInfo::GetMacAddress().c_str());// 生产测试打印

        //ESP_LOGI(TAG, "此设备角色为: %s",CONFIG_DEVICE_ROLE);
        // ESP_LOGI(TAG, "此设备角色为: KAKA 1028 升级成功!");

        // If we have synchronized server time, set the status to clock "HH:MM" if the device is idle
        if (ota_.HasServerTime()) {
            if (device_state_ == kDeviceStateIdle) {
                Schedule([this]() {
                    // Set status to clock "HH:MM"
                    time_t now = time(NULL);
                    char time_str[64];
                    strftime(time_str, sizeof(time_str), "%H:%M  ", localtime(&now));
                    Board::GetInstance().GetDisplay()->SetStatus(time_str);
                });
            }
        }
    }
}

// 添加任务到主循环
void Application::Schedule(std::function<void()> callback) {
    {
        std::lock_guard<std::mutex> lock(mutex_);// 加锁保护任务队列
        main_tasks_.push_back(std::move(callback));// 添加任务到队列
    }
    xEventGroupSetBits(event_group_, SCHEDULE_EVENT);// 通知主循环有任务需要执行
}

// The Main Loop controls the chat state and websocket connection
// If other tasks need to access the websocket or chat state,
// they should use Schedule to call this function
void Application::MainLoop() {
    while (true) {
        auto bits = xEventGroupWaitBits(event_group_, SCHEDULE_EVENT, pdTRUE, pdFALSE, portMAX_DELAY);

        if (bits & SCHEDULE_EVENT) {
            std::unique_lock<std::mutex> lock(mutex_);
            std::list<std::function<void()>> tasks = std::move(main_tasks_);
            lock.unlock();
            for (auto& task : tasks) {
                task();
            }
        }
    }
}

// The Audio Loop is used to input and output audio data
void Application::AudioLoop() {
    auto codec = Board::GetInstance().GetAudioCodec();
    while (true) {
        OnAudioInput();
        if (codec->output_enabled()) {
            OnAudioOutput();
        }
    }
}

// 音频输出函数
void Application::OnAudioOutput() {
    auto now = std::chrono::steady_clock::now();
    auto codec = Board::GetInstance().GetAudioCodec();
    const int max_silence_seconds = 10;

    std::unique_lock<std::mutex> lock(mutex_);

    // 新增代码(小程序控制 暂停/继续播放 音频)
    // =========================================================
    // 🔧 暂停状态下停止从队列取数据，但保留队列状态
    if (audio_paused_) {
        // 暂停时重置音量状态，避免误判
        if (current_speaker_volume_ > 0.0f) {
            current_speaker_volume_ = 0.0f;
#if CONFIG_USE_AUDIO_PROCESSOR
            audio_processor_.SetSpeakerVolume(0.0f);
#endif
        }
        return;
    }
    // =========================================================

    if (audio_decode_queue_.empty()) {
        // 重要：没有音频数据时立即重置音量状态
        if (current_speaker_volume_ > 0.0f) {
            current_speaker_volume_ = 0.0f;
#if CONFIG_USE_AUDIO_PROCESSOR
            audio_processor_.SetSpeakerVolume(0.0f);
#endif
        }

        // Disable the output if there is no audio data for a long time
        if (device_state_ == kDeviceStateIdle) {
            auto duration = std::chrono::duration_cast<std::chrono::seconds>(now - last_output_time_).count();
            if (duration > max_silence_seconds) {
                codec->EnableOutput(false);
            }
        }
        return;
    }

    if (device_state_ == kDeviceStateListening) {
        audio_decode_queue_.clear();
        // 重要：清空播放队列时重置音量状态，避免误判
        current_speaker_volume_ = 0.0f;
#if CONFIG_USE_AUDIO_PROCESSOR
        audio_processor_.SetSpeakerVolume(0.0f);
#endif
        return;
    }

    auto opus = std::move(audio_decode_queue_.front());
    audio_decode_queue_.pop_front();
    lock.unlock();

    background_task_->Schedule([this, codec, opus = std::move(opus)]() mutable {
        if (aborted_) {
            return;
        }

        std::vector<int16_t> pcm;
        if (!opus_decoder_->Decode(std::move(opus), pcm)) {
            return;
        }
        // Resample if the sample rate is different
        if (opus_decoder_->sample_rate() != codec->output_sample_rate()) {
            int target_size = output_resampler_.GetOutputSamples(pcm.size());
            std::vector<int16_t> resampled(target_size);
            output_resampler_.Process(pcm.data(), pcm.size(), resampled.data());
            pcm = std::move(resampled);
        }
        // 计算并同步音频输出音量到音频处理器，用于动态VAD阈值调整
        if (realtime_chat_enabled_ && !pcm.empty()) {
            // 计算音频块的RMS音量 (0.0 - 1.0)
            float sum_squares = 0.0f;
            for (const auto& sample : pcm) {
                float normalized = (float)sample / 32768.0f;
                sum_squares += normalized * normalized;
            }
            float rms_volume = std::sqrt(sum_squares / pcm.size());

#if CONFIG_USE_AUDIO_PROCESSOR
            // 同步音量到音频处理器，用于动态阈值调整
            current_speaker_volume_ = rms_volume; // 保存当前音量供打断逻辑使用
            audio_processor_.SetSpeakerVolume(rms_volume);
#endif
        }

        codec->OutputData(pcm);
        last_output_time_ = std::chrono::steady_clock::now();
    });
}

void Application::OnAudioInput() {
    std::vector<int16_t> data;

#if CONFIG_USE_WAKE_WORD_DETECT || CONFIG_USE_CUSTOM_WAKE_WORD
    if (wake_word_detect_.IsRunning()) {
        ReadAudio(data, 16000, wake_word_detect_.GetFeedSize());
        wake_word_detect_.Feed(data);// 将音频数据喂给唤醒词检测器
        return;
    }
#endif
#if CONFIG_USE_AUDIO_PROCESSOR
    if (audio_processor_.IsRunning()) {
        ReadAudio(data, 16000, audio_processor_.GetFeedSize());
        audio_processor_.Feed(data);
        return;
    }
#else
    if (device_state_ == kDeviceStateListening) {
        ReadAudio(data, 16000, 30 * 16000 / 1000);
        background_task_->Schedule([this, data = std::move(data)]() mutable {
            opus_encoder_->Encode(std::move(data), [this](std::vector<uint8_t>&& opus) {
                Schedule([this, opus = std::move(opus)]() {
                    protocol_->SendAudio(opus);
                });
            });
        });
        return;
    }
#endif
    vTaskDelay(pdMS_TO_TICKS(30));
}

void Application::ReadAudio(std::vector<int16_t>& data, int sample_rate, int samples) {
    auto codec = Board::GetInstance().GetAudioCodec();
    if (codec->input_sample_rate() != sample_rate) {
        data.resize(samples * codec->input_sample_rate() / sample_rate);
        if (!codec->InputData(data)) {
            return;
        }
        if (codec->input_channels() == 2) {
            auto mic_channel = std::vector<int16_t>(data.size() / 2);
            auto reference_channel = std::vector<int16_t>(data.size() / 2);
            for (size_t i = 0, j = 0; i < mic_channel.size(); ++i, j += 2) {
                mic_channel[i] = data[j];
                reference_channel[i] = data[j + 1];
            }
            auto resampled_mic = std::vector<int16_t>(input_resampler_.GetOutputSamples(mic_channel.size()));
            auto resampled_reference = std::vector<int16_t>(reference_resampler_.GetOutputSamples(reference_channel.size()));
            input_resampler_.Process(mic_channel.data(), mic_channel.size(), resampled_mic.data());
            reference_resampler_.Process(reference_channel.data(), reference_channel.size(), resampled_reference.data());
            data.resize(resampled_mic.size() + resampled_reference.size());
            for (size_t i = 0, j = 0; i < resampled_mic.size(); ++i, j += 2) {
                data[j] = resampled_mic[i];
                data[j + 1] = resampled_reference[i];
            }
        } else {
            auto resampled = std::vector<int16_t>(input_resampler_.GetOutputSamples(data.size()));
            input_resampler_.Process(data.data(), data.size(), resampled.data());
            data = std::move(resampled);
        }
    } else {
        data.resize(samples);
        if (!codec->InputData(data)) {
            return;
        }
    }
}

// 打断语音播报(终止播放)
void Application::AbortSpeaking(AbortReason reason) {
    // 🔧 防止重复中止操作，避免竞态条件
    bool expected = false;
    if (!is_aborting_.compare_exchange_strong(expected, true)) {
        ESP_LOGD(TAG, "AbortSpeaking already in progress, ignoring duplicate call");
        return;
    }

    ESP_LOGI(TAG, "🔴 Abort speaking - immediate stop");
    aborted_ = true;

    // 🔧 更新安全操作时间戳
    last_safe_operation_.store(std::chrono::steady_clock::now());

    // 🔧 修复：立即清空音频队列，确保音频播放立即停止
    {
        std::lock_guard<std::mutex> lock(mutex_);
        if (!audio_decode_queue_.empty()) {
            ESP_LOGI(TAG, "🔴 Clearing %zu audio frames from queue", audio_decode_queue_.size());
            audio_decode_queue_.clear();

            // 重置音量状态
            current_speaker_volume_ = 0.0f;
#if CONFIG_USE_AUDIO_PROCESSOR
            audio_processor_.SetSpeakerVolume(0.0f);
#endif
        }
    }

    // ⚠️ 移除WaitForCompletion避免死锁，让后台任务通过aborted_标志自然结束
    ESP_LOGI(TAG, "🔴 Audio queue cleared, background tasks will stop on next iteration");

    // 🔧 修复：安全地发送中止消息，避免WebSocket崩溃
    if (protocol_ && device_state_ == kDeviceStateSpeaking && IsSafeToOperate()) {
        try {
            // 🔧 额外的连接状态验证
            if (protocol_->IsAudioChannelOpened()) {
                protocol_->SendAbortSpeaking(reason);
                ESP_LOGI(TAG, "AbortSpeaking message sent successfully");
                // 更新安全操作时间戳
                last_safe_operation_.store(std::chrono::steady_clock::now());
            } else {
                ESP_LOGW(TAG, "Audio channel not properly opened, skipping AbortSpeaking");
            }
        } catch (const std::exception& e) {
            ESP_LOGW(TAG, "Failed to send AbortSpeaking message: %s", e.what());
        }
    } else {
        ESP_LOGD(TAG, "Skipping AbortSpeaking message - conditions not safe");
    }

    // 🔧 重置中止标志，允许后续操作
    is_aborting_.store(false);
}

// 发送讲故事请求  【新增】
void Application::SendStoryRequest() {
    if (!protocol_) {
        ESP_LOGE(TAG, "Protocol not initialized");
        return;
    }

    if (device_state_ == kDeviceStateIdle) {    // 设备状态为待机
        Schedule([this]() {
            SetDeviceState(kDeviceStateConnecting);
            if (!protocol_->OpenAudioChannel()) {
                return;
            }
            protocol_->SendStoryRequest();  // 发送讲故事请求
            ESP_LOGI(TAG, "Sent story request");

            // 立即启动监听模式以接收语音回复
            ESP_LOGI(TAG, "SendStoryRequest: realtime_chat_enabled_ = %s", realtime_chat_enabled_ ? "true" : "false");
            SetListeningMode(realtime_chat_enabled_ ? kListeningModeRealtime : kListeningModeManualStop);
        });
    } else if (device_state_ == kDeviceStateSpeaking) { // 设备状态为说话
        Schedule([this]() {
            AbortSpeaking(kAbortReasonNone);
            protocol_->SendStoryRequest();  // 发送讲故事请求
            ESP_LOGI(TAG, "Sent story request");

            // 启动监听模式以接收语音回复
            ESP_LOGI(TAG, "SendStoryRequest: realtime_chat_enabled_ = %s", realtime_chat_enabled_ ? "true" : "false");
            SetListeningMode(realtime_chat_enabled_ ? kListeningModeRealtime : kListeningModeManualStop);
        });
    } else if (device_state_ == kDeviceStateListening) { // 设备状态为监听
        Schedule([this]() {
            protocol_->SendStoryRequest();  // 发送讲故事请求（调用协议层）
            ESP_LOGI(TAG, "Sent story request");
        });
    }
}

void Application::SetListeningMode(ListeningMode mode) {
    ESP_LOGI(TAG, "Setting listening mode to %d", (int)mode);
    listening_mode_ = mode;
    SetDeviceState(kDeviceStateListening);
}

void Application::SetDeviceState(DeviceState state) {
    if (device_state_ == state) {
        return;
    }

    clock_ticks_ = 0;
    auto previous_state = device_state_;
    device_state_ = state;
    ESP_LOGI(TAG, "STATE: %s", STATE_STRINGS[device_state_]);
    // The state is changed, wait for all background tasks to finish
    background_task_->WaitForCompletion();

    auto& board = Board::GetInstance();
    auto display = board.GetDisplay();
    auto led = board.GetLed();
    led->OnStateChanged();

    // 检查是否正在进行BluFi配网，配网时禁止播放待命音效(新增代码)
    // =================================================================
    bool is_blufi_provisioning = false;
    if (Board::GetInstance().GetBoardType() == "wifi") {
        auto& wifi_board = static_cast<WifiBoard&>(Board::GetInstance());
        is_blufi_provisioning = wifi_board.IsBluFiProvisioningActive();
    }
    // =================================================================

    switch (state) {
        case kDeviceStateUnknown:
        case kDeviceStateIdle:
            display->SetStatus(Lang::Strings::STANDBY);
            display->SetEmotion("neutral");


            // // 只有从非待命状态进入待命状态时才播放待命音效，避免重复播放(原来的代码)
            // if (previous_state != kDeviceStateIdle && 
            //     previous_state != kDeviceStateUnknown &&
            //     previous_state != kDeviceStateWifiConfiguring) {
            //     ESP_LOGI(TAG, "Entering idle state, playing standby sound");
            //     PlaySound(Lang::Sounds::P3_DAIMING);
            // }
            // 开机后 进入待命状态 播报 卡卡正在待命(配网模式下不播报“卡卡正在待命”)-新增代码
            //=====================================================================================
            if (previous_state != kDeviceStateIdle && previous_state != kDeviceStateUnknown && 
                previous_state != kDeviceStateWifiConfiguring && !is_blufi_provisioning && !IsLowBatteryTransition()) {
                ESP_LOGI(TAG, "Entering idle state, playing standby sound");
                // PlaySound(Lang::Sounds::P3_DAIMING); 原有 待命 播报
                    if(strcmp(CONFIG_DEVICE_ROLE, "KAKA") == 0){
                        PlaySound(Lang::Sounds::P3_KAKA_DAIMING);
                    }
                    else if(strcmp(CONFIG_DEVICE_ROLE, "LALA") == 0){
                        PlaySound(Lang::Sounds::P3_LALA_DAIMING);
                    }
            }
            //=====================================================================================

#if CONFIG_USE_AUDIO_PROCESSOR
            audio_processor_.Stop();
#endif
#if CONFIG_USE_WAKE_WORD_DETECT || CONFIG_USE_CUSTOM_WAKE_WORD
            wake_word_detect_.Start();
#endif
            break;
        case kDeviceStateConnecting:
            display->SetStatus(Lang::Strings::CONNECTING);
            display->SetEmotion("neutral");
            display->SetChatMessage("system", "");
            break;
        case kDeviceStateListening:
            display->SetStatus(Lang::Strings::LISTENING);
            display->SetEmotion("neutral");

            // 关键修复：只有在非音效播放状态下才重置音量，避免中断正在播放的音效
            // 检查是否有音频正在播放，如果有则延迟重置音量
            if (IsAudioQueueEmpty()) {
                current_speaker_volume_ = 0.0f;
#if CONFIG_USE_AUDIO_PROCESSOR
                audio_processor_.SetSpeakerVolume(0.0f);
#endif
            } else {
                // 如果有音频正在播放，延迟重置音量
                Schedule([this]() {
                    vTaskDelay(pdMS_TO_TICKS(500)); // 等待音效播放完成
                    current_speaker_volume_ = 0.0f;
#if CONFIG_USE_AUDIO_PROCESSOR
                    audio_processor_.SetSpeakerVolume(0.0f);
#endif
                });
            }

            // Update the IoT states before sending the start listening command
            UpdateIotStates();

            // Make sure the audio processor is running
#if CONFIG_USE_AUDIO_PROCESSOR
            if (!audio_processor_.IsRunning()) {
#else
            if (true) {
#endif
                // 🔧 关键修复：检查协议连接状态，防止发送到无效连接
                if (protocol_ && protocol_->IsAudioChannelOpened()) {
                    // Send the start listening command
                    protocol_->SendStartListening(listening_mode_);
                    if (listening_mode_ == kListeningModeAutoStop && previous_state == kDeviceStateSpeaking) {
                        // FIXME: Wait for the speaker to empty the buffer
                        vTaskDelay(pdMS_TO_TICKS(120));
                    }
                    opus_encoder_->ResetState();
#if CONFIG_USE_WAKE_WORD_DETECT || CONFIG_USE_CUSTOM_WAKE_WORD
                    wake_word_detect_.Stop();
#endif
#if CONFIG_USE_AUDIO_PROCESSOR
                    audio_processor_.Start();
#endif
                } else {
                    ESP_LOGW(TAG, "Audio channel not available, skipping SendStartListening");
                    // 保持在聆听状态，不自动回退到idle状态
                    ESP_LOGI(TAG, "🔵 Staying in listening state despite audio channel unavailable");
                }
            }
            break;
        case kDeviceStateSpeaking:
            display->SetStatus(Lang::Strings::SPEAKING);

            if (listening_mode_ != kListeningModeRealtime) {
#if CONFIG_USE_AUDIO_PROCESSOR
                audio_processor_.Stop();
#endif
#if CONFIG_USE_WAKE_WORD_DETECT || CONFIG_USE_CUSTOM_WAKE_WORD
                wake_word_detect_.Start();
#endif
            } else {
                // 在实时模式下，保持audio_processor运行以检测语音打断
#if CONFIG_USE_AUDIO_PROCESSOR
                if (!audio_processor_.IsRunning()) {
                    audio_processor_.Start();
                }
#endif
#if CONFIG_USE_WAKE_WORD_DETECT || CONFIG_USE_CUSTOM_WAKE_WORD
                wake_word_detect_.Stop();
#endif
            }
            ResetDecoder();
            break;
        default:
            // Do nothing
            break;
    }
}

void Application::ResetDecoder() {
    std::lock_guard<std::mutex> lock(mutex_);
    opus_decoder_->ResetState();
    audio_decode_queue_.clear();
    last_output_time_ = std::chrono::steady_clock::now();

    auto codec = Board::GetInstance().GetAudioCodec();
    codec->EnableOutput(true);
}

void Application::SetDecodeSampleRate(int sample_rate, int frame_duration) {
    if (opus_decoder_->sample_rate() == sample_rate && opus_decoder_->duration_ms() == frame_duration) {
        return;
    }

    opus_decoder_.reset();
    opus_decoder_ = std::make_unique<OpusDecoderWrapper>(sample_rate, 1, frame_duration);

    auto codec = Board::GetInstance().GetAudioCodec();
    if (opus_decoder_->sample_rate() != codec->output_sample_rate()) {
        ESP_LOGI(TAG, "Resampling audio from %d to %d", opus_decoder_->sample_rate(), codec->output_sample_rate());
        output_resampler_.Configure(opus_decoder_->sample_rate(), codec->output_sample_rate());
    }
}

void Application::UpdateIotStates() {
    auto& thing_manager = iot::ThingManager::GetInstance();
    std::string states;
    if (thing_manager.GetStatesJson(states, true)) {
        protocol_->SendIotStates(states);
    }
}

void Application::Reboot() {
    ESP_LOGI(TAG, "Rebooting...");
    esp_restart();
}

// 唤醒词触发函数
void Application::WakeWordInvoke(const std::string& wake_word) {
    if (device_state_ == kDeviceStateIdle) {
        ToggleChatState();
        Schedule([this, wake_word]() {
            if (protocol_) {
                protocol_->SendWakeWordDetected(wake_word); 
            }
        }); 
    } else if (device_state_ == kDeviceStateSpeaking) {
        //AbortSpeakingAndReturnToListening();// 使用唤醒词打断时立即切换到聆听状态
        Schedule([this]() {
            AbortSpeaking(kAbortReasonNone);
        });
    } else if (device_state_ == kDeviceStateListening) {   
        Schedule([this]() {
            if (protocol_) {
                protocol_->CloseAudioChannel();
            }
        });
    }
}

bool Application::CanEnterSleepMode() {
    if (device_state_ != kDeviceStateIdle) {
        return false;
    }

    if (protocol_ && protocol_->IsAudioChannelOpened()) {
        return false;
    }

    // Now it is safe to enter sleep mode
    return true;
}
void Application::WaitForAudioPlayback() {
    // 等待 audio_decode_queue_ 清空且音频输出完成
    auto codec = Board::GetInstance().GetAudioCodec();
    int timeout_count = 0;
    const int max_timeout = 150; // 3秒超时 (150 * 20ms = 3000ms)

    while (timeout_count < max_timeout) {
        {
            std::lock_guard<std::mutex> lock(mutex_);
            if (audio_decode_queue_.empty()) {
                // 检查音频输出是否已关闭或静音
                if (!codec->output_enabled() || device_state_ != kDeviceStateSpeaking) {
                    ESP_LOGI(TAG, "Audio playback completed");
                    break;
                }
            }
        }
        vTaskDelay(pdMS_TO_TICKS(20));
        timeout_count++;
    }

    if (timeout_count >= max_timeout) {
        ESP_LOGW(TAG, "WaitForAudioPlayback timeout after 3 seconds");
    }
}

bool Application::IsAudioQueueEmpty() {
    std::lock_guard<std::mutex> lock(mutex_);
    return audio_decode_queue_.empty();
}

void Application::ClearAudioQueue() {
    std::lock_guard<std::mutex> lock(mutex_);
    audio_decode_queue_.clear();
    audio_paused_ = false;  // 清除暂停状态
    // ESP_LOGI(TAG, "🧹 音频播放队列已清空，暂停状态已清除");
    ESP_LOGI(TAG, "🎵 测试模式：音频开始播放，等待播放完成"); // 生产测试打印


    // 重新启用音频编解码器输出，确保后续音频能正常播放
    auto& board = Board::GetInstance();
    auto codec = board.GetAudioCodec();
    if (codec) {
        codec->EnableOutput(true);
        // ESP_LOGI(TAG, "🔧 音频编解码器输出已重新启用");
        ESP_LOGI(TAG, "✅ 测试模式：音频播放完成"); // 生产测试打印
    }
}

// 🔧 检查当前是否可以安全执行操作
bool Application::IsSafeToOperate() {
    // 检查是否正在执行中止操作
    if (is_aborting_.load()) {
        return false;
    }

    // 检查最近是否有操作过于频繁
    auto now = std::chrono::steady_clock::now();
    auto last_op = last_safe_operation_.load();
    auto time_diff = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_op);

    // 如果距离上次操作少于50ms，认为可能存在竞态风险
    if (time_diff.count() < 50) {
        ESP_LOGD(TAG, "Operation too frequent, waiting for safety");
        return false;
    }

    return true;
}

void Application::StopAudioProcessor() {
#if CONFIG_USE_AUDIO_PROCESSOR
    audio_processor_.Stop();
#endif
}

// 🔴 专门处理从说话状态到空闲状态的切换
void Application::AbortSpeakingAndReturnToIdle() {
    ESP_LOGI(TAG, "🔴 AbortSpeakingAndReturnToIdle: Starting transition from speaking to idle state");
    ESP_LOGI(TAG, "📊 当前设备状态: %s", STATE_STRINGS[device_state_]);
    ESP_LOGI(TAG, "🎯 目标状态: idle (空闲状态)");

    // 检查当前状态是否为说话状态
    if (device_state_ != kDeviceStateSpeaking) {
        ESP_LOGW(TAG, "🔴 AbortSpeakingAndReturnToIdle: Device not in speaking state, current state: %s", STATE_STRINGS[device_state_]);
        return;
    }

    ESP_LOGI(TAG, "✅ 状态检查通过，当前处于说话状态");

    // 检查操作安全性
    if (!IsSafeToOperate()) {
        ESP_LOGW(TAG, "🔴 AbortSpeakingAndReturnToIdle: Operation not safe, scheduling retry");
        Schedule([this]() {
            vTaskDelay(pdMS_TO_TICKS(100));
            AbortSpeakingAndReturnToIdle();
        });
        return;
    }

    // 更新安全操作时间戳
    last_safe_operation_.store(std::chrono::steady_clock::now());
    ESP_LOGI(TAG, "⏰ 安全操作时间戳已更新");

    // 立即停止音频处理
    ESP_LOGI(TAG, "🔇 开始停止音频处理");
    {
        std::lock_guard<std::mutex> lock(mutex_);
        if (!audio_decode_queue_.empty()) {
            ESP_LOGI(TAG, "🗑️ 清空音频队列，当前队列大小: %zu", audio_decode_queue_.size());
            audio_decode_queue_.clear();
            current_speaker_volume_ = 0.0f;
#if CONFIG_USE_AUDIO_PROCESSOR
            audio_processor_.SetSpeakerVolume(0.0f);
#endif
            ESP_LOGI(TAG, "✅ 音频队列已清空，音量已重置为0");
        } else {
            ESP_LOGI(TAG, "ℹ️ 音频队列已为空，无需清空");
        }
    }

    ESP_LOGI(TAG, "🔴 AbortSpeakingAndReturnToIdle: Sending abort message to server");

    // 发送中止消息给服务器
    if (protocol_ && protocol_->IsAudioChannelOpened()) {
        ESP_LOGI(TAG, "📡 WebSocket连接正常，发送中止消息");
        try {
            protocol_->SendAbortSpeaking(kAbortReasonNone);
            ESP_LOGI(TAG, "✅ 中止消息发送成功");
        } catch (const std::exception& e) {
            ESP_LOGW(TAG, "❌ 发送中止消息失败: %s", e.what());
        }

        // 延迟100ms后主动关闭连接，确保服务器有时间处理中止消息
        Schedule([this]() {
            vTaskDelay(pdMS_TO_TICKS(100));
            ESP_LOGI(TAG, "⏳ 延迟100ms后开始主动关闭WebSocket连接");
            ESP_LOGI(TAG, "🔌 执行主动断开WebSocket连接");
            if (protocol_) {
                protocol_->CloseAudioChannel();
                ESP_LOGI(TAG, "✅ CloseAudioChannel调用完成");
            } else {
                ESP_LOGW(TAG, "⚠️ protocol_为空，无法关闭音频通道");
            }
        });
    } else {
        ESP_LOGW(TAG, "⚠️ WebSocket连接不可用，强制关闭连接");
        if (protocol_) {
            ESP_LOGI(TAG, "🔌 强制执行WebSocket断开");
            protocol_->CloseAudioChannel();
            ESP_LOGI(TAG, "✅ 强制断开完成");
        } else {
            ESP_LOGW(TAG, "❌ protocol_为空，无法执行断开操作");
        }
    }

    ESP_LOGI(TAG, "🎯 主动断开流程已启动，等待OnAudioChannelClosed回调触发状态转换");
    ESP_LOGI(TAG, "📋 预期流程: WebSocket断开 → 回调触发 → 转换到idle状态 → 播放待机音");
}

// 🔵 专门处理从说话状态到聆听状态的切换
void Application::AbortSpeakingAndReturnToListening() {
    ESP_LOGI(TAG, "🔵 AbortSpeakingAndReturnToListening: Starting transition from speaking to listening state (断开连接方案)");

    // 检查当前状态是否为说话状态或可切换状态
    // =========================================================================================
    if (device_state_ != kDeviceStateSpeaking && device_state_ != kDeviceStateListening && device_state_ != kDeviceStateIdle) {
        ESP_LOGW(TAG, "🔵 AbortSpeakingAndReturnToListening: Device not in valid state for transition, current state: %s", STATE_STRINGS[device_state_]);
        return;
    }
    // 如果已经在listening状态，直接返回避免重复切换
    if (device_state_ == kDeviceStateListening) {
        ESP_LOGI(TAG, "🔵 AbortSpeakingAndReturnToListening: Already in listening state, skipping transition");
        return;
    }
    // 🔧 检查并处理音频播放状态(BOOT按键优化方案)
    if (!audio_paused_ && device_state_ == kDeviceStateSpeaking) {
        ESP_LOGI(TAG, "🔵 检测到播放状态，一次按键完成暂停和状态切换");

        // 第一步：禁用音频输出(立即停止播放)
        auto& board = Board::GetInstance();// 获取音频编解码器
        auto codec = board.GetAudioCodec();// 获取音频编解码器
        if (codec) {
            codec->EnableOutput(false);// 暂停时禁用音频编解码器输出
            ESP_LOGI(TAG, "🔧 暂停时禁用音频编解码器输出");
        }
        // 第二步：切换到暂停状态
        audio_paused_ = true;
        ESP_LOGI(TAG, "✅ 已切换到暂停状态");
        // 第三步：立即执行状态切换逻辑（不返回，继续执行下面的代码）
        ESP_LOGI(TAG, "🔵 继续执行状态切换到聆听状态");
    }

    // 🔧 检查并处理音频暂停状态(BOOT按键优化方案)
    if (audio_paused_) {
        ESP_LOGI(TAG, "🔵 检测到音频暂停状态，应用BOOT按键优化方案");
        audio_paused_ = false;
        ESP_LOGI(TAG, "✅ 音频暂停状态已清除");

        // 🔧 关键优化：清空音频播放队列，避免播放暂停时残留的音频
        std::unique_lock<std::mutex> lock(mutex_);
        audio_decode_queue_.clear();
        lock.unlock();
        ESP_LOGI(TAG, "🧹 已清空音频播放队列，避免播放残留音频");

        // BOOT按键切换时的优化方案：确保音频系统能正常响应状态切换
        auto& board = Board::GetInstance();
        auto codec = board.GetAudioCodec();
        if (codec) {
            codec->EnableOutput(true);
            ESP_LOGI(TAG, "🔧 为状态切换重新启用音频编解码器输出");// 重新启用输出,后续可以播放
        }
        // 🔧 关键修复：强制停止音频处理器，确保后续状态切换时能重新启动
#if CONFIG_USE_AUDIO_PROCESSOR
        if (audio_processor_.IsRunning()) {
            ESP_LOGI(TAG, "🔧 强制停止音频处理器以确保状态切换成功");
            audio_processor_.Stop();
        }
#endif

        // 🔧 音频暂停状态下直接切换，避免复杂的异步处理
        ESP_LOGI(TAG, "🔵 音频暂停状态下直接执行状态切换");

        // 播放提示音
        if (codec && codec->output_enabled()) {
            ESP_LOGI(TAG, "播放提示音：卡卡在呢");
            // PlaySound(Lang::Sounds::P3_KAKAZAINNE);  原有蜡笔小新 音色播报
                if(strcmp(CONFIG_DEVICE_ROLE, "KAKA") == 0){
                    PlaySound(Lang::Sounds::P3_KAKA_ZAINNE);
                }
                else if(strcmp(CONFIG_DEVICE_ROLE, "LALA") == 0){
                    PlaySound(Lang::Sounds::P3_LALA_ZAINNE);
                }


            // 简化等待逻辑
            vTaskDelay(pdMS_TO_TICKS(620)); // 等待音效播放完成
            ESP_LOGI(TAG, "音频播放完成");
        }

        // 直接切换到聆听状态
        SetDeviceState(kDeviceStateListening);
        ESP_LOGI(TAG, "🔵 音频暂停状态下状态切换完成");
        return;
    }
    // =========================================================================================

    // 检查操作安全性
    if (!IsSafeToOperate()) {
        ESP_LOGW(TAG, "🔵 AbortSpeakingAndReturnToListening: Operation not safe, scheduling retry");
        Schedule([this]() {
            vTaskDelay(pdMS_TO_TICKS(100));
            AbortSpeakingAndReturnToListening();
        });
        return;
    }

    // 更新安全操作时间戳
    last_safe_operation_.store(std::chrono::steady_clock::now());

    // 立即停止音频处理器和清空音频队列
#if CONFIG_USE_AUDIO_PROCESSOR
    if (audio_processor_.IsRunning()) {
        ESP_LOGI(TAG, "🔵 停止音频处理器");
        audio_processor_.Stop();
    }

    // 清空音频队列并重置音量
    if (!IsAudioQueueEmpty()) {
        ESP_LOGI(TAG, "🔵 清空音频队列并重置音量");
        while (!IsAudioQueueEmpty()) {
            vTaskDelay(pdMS_TO_TICKS(10));
        }
        current_speaker_volume_ = 0.0f;
        audio_processor_.SetSpeakerVolume(0.0f);
        ESP_LOGI(TAG, "✅ 音频队列已清空，音量已重置为0");
    } else {
        ESP_LOGI(TAG, "ℹ️ 音频队列已为空，无需清空");
    }
#endif

    ESP_LOGI(TAG, "🔵 AbortSpeakingAndReturnToListening: Sending abort message to server");

    // 发送中止消息给服务器
    if (protocol_ && protocol_->IsAudioChannelOpened()) {
        ESP_LOGI(TAG, "📡 WebSocket连接正常，发送中止消息");
        try {
            protocol_->SendAbortSpeaking(kAbortReasonVoiceInterrupt);
            ESP_LOGI(TAG, "✅ 中止消息发送成功");
        } catch (const std::exception& e) {
            ESP_LOGW(TAG, "❌ 发送中止消息失败: %s", e.what());
        }

        // 延迟100ms后播放音效并直接切换到聆听状态，不关闭WebSocket连接
        Schedule([this]() {
            vTaskDelay(pdMS_TO_TICKS(100));
            ESP_LOGI(TAG, "⏳ 延迟100ms后播放音效并切换到聆听状态");

            // 先播放"卡卡在呢"音效
            ESP_LOGI(TAG, "🔵 AbortSpeakingAndReturnToListening: Playing KAKAZAINNE sound");

            // 🔧 修复：强制重新初始化音频输出，确保硬件状态正确
            auto& board = Board::GetInstance();
            auto audio_codec = board.GetAudioCodec();
            ESP_LOGI(TAG, "强制重新初始化音频输出");
            audio_codec->EnableOutput(false);    // 先关闭音频输出
            vTaskDelay(pdMS_TO_TICKS(50)); // 短暂延迟让硬件复位
            audio_codec->EnableOutput(true);     // 再开启，强制硬件重新初始化

            // 🔧 检查音频资源是否可用
            if (audio_codec->output_enabled()) {
                ESP_LOGI(TAG, "播放提示音：卡卡在呢");
                ResetDecoder();     // 🔧 关键修复：重置解码器状态，清除残留

                // 获取当前系统音量并临时设置以确保音效能播放
                float system_volume = audio_codec ? (audio_codec->output_volume() / 100.0f) : 0.7f; // 默认70%
                current_speaker_volume_ = system_volume;
#if CONFIG_USE_AUDIO_PROCESSOR
                audio_processor_.SetSpeakerVolume(system_volume);
                ESP_LOGI(TAG, "✅ 音量设置成功: %.2f", system_volume);
#endif

                // PlaySound(Lang::Sounds::P3_KAKAZAINNE);  原有蜡笔小新 音色播报
                if(strcmp(CONFIG_DEVICE_ROLE, "KAKA") == 0){
                    PlaySound(Lang::Sounds::P3_KAKA_ZAINNE);
                }
                else if(strcmp(CONFIG_DEVICE_ROLE, "LALA") == 0){
                    PlaySound(Lang::Sounds::P3_LALA_ZAINNE);
                }

                // 🔧 修复：使用改进的等待逻辑，确保音频真正播放完成
                ESP_LOGI(TAG, "等待音频播放完成...");
                vTaskDelay(pdMS_TO_TICKS(100));  // 给音频足够的时间开始播放

                // 等待音频队列清空 + 额外缓冲时间确保I2S硬件完成输出
                int timeout_count = 0;
                const int max_timeout = 150; // 3秒超时

                while (timeout_count < max_timeout) {
                    if (IsAudioQueueEmpty()) {
                        // 队列清空后，再等待500ms确保I2S硬件完成输出
                        ESP_LOGI(TAG, "音频队列已清空，等待硬件输出完成...");
                        vTaskDelay(pdMS_TO_TICKS(500));
                        ESP_LOGI(TAG, "音频播放完成");
                        break;
                    }
                    vTaskDelay(pdMS_TO_TICKS(20));
                    timeout_count++;
                }

                if (timeout_count >= max_timeout) {
                    ESP_LOGW(TAG, "等待音频播放超时，继续状态切换");
                }
            } else {
                ESP_LOGW(TAG, "音频输出无法启用，跳过提示音播放");
            }

            // 直接切换到聆听状态，音频播放已在上面完成
            ESP_LOGI(TAG, "🔵 AbortSpeakingAndReturnToListening: Switching to listening state (保持WebSocket连接)");
            SetDeviceState(kDeviceStateListening);
        });
    } else {
        ESP_LOGW(TAG, "⚠️ WebSocket连接不可用，直接切换状态");

        // 直接播放音效并切换状态
        Schedule([this]() {
            vTaskDelay(pdMS_TO_TICKS(100));
            ESP_LOGI(TAG, "🔵 AbortSpeakingAndReturnToListening: Playing KAKAZAINNE sound");

            // 🔧 修复：强制重新初始化音频输出，确保硬件状态正确
            auto& board = Board::GetInstance();
            auto audio_codec = board.GetAudioCodec();
            ESP_LOGI(TAG, "强制重新初始化音频输出");
            audio_codec->EnableOutput(false);    // 先关闭音频输出
            vTaskDelay(pdMS_TO_TICKS(50)); // 短暂延迟让硬件复位
            audio_codec->EnableOutput(true);     // 再开启，强制硬件重新初始化

            // 🔧 检查音频资源是否可用
            if (audio_codec->output_enabled()) {
                ESP_LOGI(TAG, "播放提示音：卡卡在呢");
                ResetDecoder();     // 🔧 关键修复：重置解码器状态，清除残留

                // 获取当前系统音量并临时设置以确保音效能播放
                float system_volume = audio_codec ? (audio_codec->output_volume() / 100.0f) : 0.7f; // 默认70%
                current_speaker_volume_ = system_volume;
#if CONFIG_USE_AUDIO_PROCESSOR
                audio_processor_.SetSpeakerVolume(system_volume);
                ESP_LOGI(TAG, "✅ 音量设置成功: %.2f", system_volume);
#endif

                // PlaySound(Lang::Sounds::P3_KAKAZAINNE);  原有蜡笔小新 音色播报
                if(strcmp(CONFIG_DEVICE_ROLE, "KAKA") == 0){
                    PlaySound(Lang::Sounds::P3_KAKA_ZAINNE);
                }
                else if(strcmp(CONFIG_DEVICE_ROLE, "LALA") == 0){
                    PlaySound(Lang::Sounds::P3_LALA_ZAINNE);
                }

                // 🔧 修复：使用改进的等待逻辑，确保音频真正播放完成
                ESP_LOGI(TAG, "等待音频播放完成...");
                vTaskDelay(pdMS_TO_TICKS(100));  // 给音频足够的时间开始播放

                // 等待音频队列清空 + 额外缓冲时间确保I2S硬件完成输出
                int timeout_count = 0;
                const int max_timeout = 150; // 3秒超时

                while (timeout_count < max_timeout) {
                    if (IsAudioQueueEmpty()) {
                        // 队列清空后，再等待500ms确保I2S硬件完成输出
                        ESP_LOGI(TAG, "音频队列已清空，等待硬件输出完成...");
                        vTaskDelay(pdMS_TO_TICKS(500));
                        ESP_LOGI(TAG, "音频播放完成");
                        break;
                    }
                    vTaskDelay(pdMS_TO_TICKS(20));
                    timeout_count++;
                }

                if (timeout_count >= max_timeout) {
                    ESP_LOGW(TAG, "等待音频播放超时，继续状态切换");
                }
            } else {
                ESP_LOGW(TAG, "音频输出无法启用，跳过提示音播放");
            }

            // 直接切换到聆听状态，音频播放已在上面完成
            ESP_LOGI(TAG, "🔵 AbortSpeakingAndReturnToListening: Switching to listening state");
            SetDeviceState(kDeviceStateListening);
        });
    }

    ESP_LOGI(TAG, "🔵 AbortSpeakingAndReturnToListening: Transition initiated - keeping WebSocket connection and switching to listening");
}

// 姿态传感器接口实现
bool Application::IsImuSensorAvailable() {
    auto& board = Board::GetInstance();
    if (board.GetBoardType() == "movecall-moji-esp32s3") {
        auto& moji_board = static_cast<MovecallMojiESP32S3&>(board);
        return moji_board.IsImuInitialized();
    }
    return false;
}

bool Application::GetImuData(float* acc_x, float* acc_y, float* acc_z, 
                            float* gyro_x, float* gyro_y, float* gyro_z, 
                            float* temperature) {
    auto& board = Board::GetInstance();
    if (board.GetBoardType() == "movecall-moji-esp32s3") {
        auto& moji_board = static_cast<MovecallMojiESP32S3&>(board);
        qmi8658a_data_t imu_data;
        if (moji_board.GetImuData(&imu_data)) {
            if (acc_x) *acc_x = imu_data.acc_x;
            if (acc_y) *acc_y = imu_data.acc_y;
            if (acc_z) *acc_z = imu_data.acc_z;
            if (gyro_x) *gyro_x = imu_data.gyro_x;
            if (gyro_y) *gyro_y = imu_data.gyro_y;
            if (gyro_z) *gyro_z = imu_data.gyro_z;
            if (temperature) *temperature = imu_data.temperature;
            return true;
        }
    }
    return false;
}

void Application::OnMotionDetected() {
    ESP_LOGI(TAG, "Motion detected by IMU sensor");

    // 如果设备处于空闲状态，可以触发一些动作
    if (device_state_ == kDeviceStateIdle) {
        // 例如：显示运动检测提示
        auto& board = Board::GetInstance();
        auto display = board.GetDisplay();
        display->SetChatMessage("system", "检测到运动");

        // 可以在这里添加更多的运动检测处理逻辑
        // 比如：唤醒设备、记录运动数据等
    }
}

void Application::SetLowBatteryTransition(bool value) {
    is_low_battery_transition_.store(value);// 设置低电量过渡状态
}

bool Application::IsLowBatteryTransition() const {
    return is_low_battery_transition_.load();// 获取低电量过渡状态
}
