#include <cJSON.h>
#include <esp_log.h>
#include <sdkconfig.h>

#include <cstring>

#include "application.h"
#include "board.h"
#include "config.h"
#include "mcp_server.h"
#include "sdkconfig.h"
#include "settings.h"
#include "display.h"

#define TAG "MCPController"

namespace {
constexpr bool kDefaultFatigueEnabled =
#if defined(CONFIG_FATIGUE_DETECTION_MODE_OFF)
    false;
#else
    true;
#endif

constexpr bool kDefaultFatigueCameraEnabled =
#if defined(CONFIG_FATIGUE_DETECTION_MODE_CAMERA) || defined(CONFIG_FATIGUE_DETECTION_MODE_BOTH)
    true;
#else
    false;
#endif

constexpr bool kDefaultFatigueSilenceEnabled =
#if defined(CONFIG_FATIGUE_DETECTION_MODE_SILENCE) || defined(CONFIG_FATIGUE_DETECTION_MODE_BOTH)
    true;
#else
    false;
#endif

constexpr bool kDefaultFatigueCameraDebugPreview =
#if defined(CONFIG_FATIGUE_CAMERA_DEBUG_PREVIEW_DEFAULT)
    true;
#else
    false;
#endif

std::string GetFatigueDetectionMode(bool enabled, bool camera_enabled, bool silence_enabled) {
    if (!enabled) {
        return "off";
    }
    if (camera_enabled && silence_enabled) {
        return "both";
    }
    if (camera_enabled) {
        return "camera";
    }
    if (silence_enabled) {
        return "silence";
    }
    return "off";
}
}  // namespace

class MCPController {
public:
    MCPController() {
        RegisterMcpTools();
        ESP_LOGI(TAG, "注册MCP工具");
    }

	void RegisterMcpTools() {
        auto& mcp_server = McpServer::GetInstance();
		ESP_LOGI(TAG, "开始注册MCP工具...");

	mcp_server.AddTool(
        "self.AEC.set_mode", 
        "设置AEC对话打断模式。当用户意图切换对话打断模式时或者用户觉得ai对话容易被打断时或者用户觉得无法实现对话打断时都使用此工具。\n"
        "参数：\n"
        "   `mode`: 对话打断模式，可选值只有`kAecOff`(关闭）和`kAecOnDeviceSide`（开启）\n"
        "返回值：\n"
        "   反馈状态信息，不需要确认，立即播报相关数据\n",
        PropertyList({
            Property("mode", kPropertyTypeString)
        }), 
        [](const PropertyList& properties) -> ReturnValue {
            auto mode = properties["mode"].value<std::string>();
            auto& app = Application::GetInstance();
            vTaskDelay(pdMS_TO_TICKS(2000));
            if (mode == "kAecOff") {
                app.SetAecMode(kAecOff);
                return "{\"success\": true, \"message\": \"AEC对话打断模式已关闭\"}";
            }else {
                app.SetAecMode(kAecOnDeviceSide);
                
                return "{\"success\": true, \"message\": \"AEC对话打断模式已开启\"}";
            }
        }
    );

    mcp_server.AddTool(
        "self.AEC.get_mode",
        "获取AEC对话打断模式状态。当用户意图获取对话打断模式状态时使用此工具。\n"
        "返回值：\n"
        "   反馈状态信息，不需要确认，立即播报相关数据\n",
        PropertyList(),  
        [](const PropertyList&) -> ReturnValue {
            auto& app = Application::GetInstance();
            const bool is_currently_off = (app.GetAecMode() == kAecOff);
           if (is_currently_off) {
                return "{\"success\": true, \"message\": \"AEC对话打断模式处于关闭状态\"}";
            }else {
                return "{\"success\": true, \"message\": \"AEC对话打断模式处于开启状态\"}";
            }
        }
    );
	
    mcp_server.AddTool(
        "self.res.esp_restart",
        "重启设备。当用户意图重启设备时使用此工具。\n",
        PropertyList(),  
        [](const PropertyList&) -> ReturnValue {
            vTaskDelay(pdMS_TO_TICKS(1000));
            // Reboot the device
            esp_restart();
            return true;
        }
    );

    mcp_server.AddTool(
        "self.fatigue.set_detection_mode",
        "切换疲劳提醒检测模式。当用户想切换打瞌睡检测、眨眼检测、不讲话检测、关闭疲劳提醒或查看摄像头取样画面时使用此工具。\n"
        "参数：\n"
        "   `mode`: 检测模式，可选值只有 `camera`(只用摄像头眨眼/闭眼检测)、`silence`(只用不讲话/静默检测)、`both`(两个都开)、`off`(关闭疲劳提醒)\n"
        "   `debug_preview`: 是否显示摄像头调试预览。默认 false；只有用户明确想看摄像头拍到什么时才设为 true\n"
        "返回值：\n"
        "   反馈当前疲劳检测模式，不需要确认，立即播报相关数据\n",
        PropertyList({
            Property("mode", kPropertyTypeString),
            Property("debug_preview", kPropertyTypeBoolean, false),
        }),
        [](const PropertyList& properties) -> ReturnValue {
            auto mode = properties["mode"].value<std::string>();
            bool debug_preview = properties["debug_preview"].value<bool>();

            bool enabled = true;
            bool camera_enabled = false;
            bool silence_enabled = false;
            std::string message;

            if (mode == "camera") {
                camera_enabled = true;
                message = "已切换为摄像头眨眼检测模式";
            } else if (mode == "silence") {
                silence_enabled = true;
                message = "已切换为不讲话静默检测模式";
            } else if (mode == "both") {
                camera_enabled = true;
                silence_enabled = true;
                message = "已切换为摄像头加静默双检测模式";
            } else if (mode == "off") {
                enabled = false;
                message = "疲劳提醒检测已关闭";
            } else {
                return "{\"success\": false, \"message\": \"检测模式无效，只能使用 camera、silence、both 或 off\"}";
            }

            Settings settings("fatigue", true);
            settings.SetBool("enabled", enabled);
            settings.SetBool("camera_enabled", camera_enabled);
            settings.SetBool("silence_enabled", silence_enabled);
            settings.SetBool("camera_debug_preview", debug_preview);

            return std::string("{\"success\": true, \"mode\": \"") + mode +
                   "\", \"debug_preview\": " + (debug_preview ? "true" : "false") +
                   ", \"message\": \"" + message + "\"}";
        }
    );

    mcp_server.AddTool(
        "self.fatigue.get_detection_mode",
        "获取当前疲劳提醒检测模式。当用户询问现在使用哪种打瞌睡检测模式时使用此工具。\n"
        "返回值：\n"
        "   当前检测模式和摄像头预览状态\n",
        PropertyList(),
        [](const PropertyList&) -> ReturnValue {
            Settings settings("fatigue", false);
            bool enabled = settings.GetBool("enabled", kDefaultFatigueEnabled);
            bool camera_enabled = settings.GetBool("camera_enabled", kDefaultFatigueCameraEnabled);
            bool silence_enabled =
                settings.GetBool("silence_enabled", kDefaultFatigueSilenceEnabled);
            bool debug_preview =
                settings.GetBool("camera_debug_preview", kDefaultFatigueCameraDebugPreview);
            auto mode = GetFatigueDetectionMode(enabled, camera_enabled, silence_enabled);

            return std::string("{\"success\": true, \"mode\": \"") + mode +
                   "\", \"camera_enabled\": " + (camera_enabled ? "true" : "false") +
                   ", \"silence_enabled\": " + (silence_enabled ? "true" : "false") +
                   ", \"debug_preview\": " + (debug_preview ? "true" : "false") + "}";
        }
    );

        ESP_LOGI(TAG, "MCP工具注册完成");
    }

};

static MCPController* g_mcp_controller = nullptr;

void InitializeMCPController() {
    if (g_mcp_controller == nullptr) {
        g_mcp_controller = new MCPController();
        ESP_LOGI(TAG, "注册MCP工具");
    }
}
