using Microsoft.Extensions.Hosting;
using Newtonsoft.Json.Linq;
using XiaoZhiSharp;
using XiaoZhiSharp.Kernels.Gis;
using XiaoZhiSharp.Models;
using XiaoZhiSharp.Utils;
using XiaoZhiSharp_ConsoleApp.Core;
using XiaoZhiSharp_ConsoleApp.Services;

class Program
{
    private static XiaoZhiAgent _agent;
    private static McpService _mcpService;
    private static string _audioMode = "";
    static async Task Main(string[] args)
    {
        Console.WriteLine("按任意键退出...");
        SharpGISNmeaParser.PlaybackLogAsFastAsPossible();
        Console.ReadKey(); // 等待用户按键
        Console.WriteLine("程序已退出。");
        return;
        //await SystemMonitorTest.RunTest(args);

        var builder = Host.CreateApplicationBuilder(args);
        Console.ForegroundColor = ConsoleColor.Green;
        Console.Title = "小智XiaoZhiSharp客户端";
        string logoAndCopyright = @"
========================================================================
欢迎使用“小智XiaoZhiSharp客户端” ！

当前功能：
1. 语音消息 输入回车：开始录音；再次输入回车：结束录音
   注意：Windows系统下，CapsLock键也可以控制录音状态，按下CapsLock开始录音，再次按下结束录音
   录音结束后会自动发送语音消息到服务器，服务器会返回语音识别结果
2. 文字消息 可以随意输入文字对话
3. 全量往返协议输出，方便调试

要是你在使用中有啥想法或者遇到问题，别犹豫，找我们哟：
微信：狼行拂晓       电子邮箱：123456789@qq.com
有任何动态请大家关注 https://www.baidu.com
========================================================================";
        Console.WriteLine(logoAndCopyright);
        Console.ForegroundColor = ConsoleColor.White;

        XiaoZhiSharp.Global.IsDebug = true;
        XiaoZhiSharp.Global.IsMcp = true;

        _mcpService = new McpService();

        string appsettingJson = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "Configs", "AppSettingConfig.json"));
        // 快速从json文件中获取配置信息
        var appsetting = Newtonsoft.Json.JsonConvert.DeserializeObject<JObject>(appsettingJson);

        _agent = new XiaoZhiAgent();
        //XiaoZhiSharp.Global.SampleRate_WaveOut = 24000;
        //_agent.WsUrl = "wss://coze.nbee.net/xiaozhi/v1/"; 
        //_agent.WsUrl = "ws://192.168.110.113:4530/xiaozhi/v1/";
        //_agent.OtaUrl = "http://192.168.110.214:48080/admin-api/pfa/ota/xiaozhi/receive";
        //_agent.OtaUrl = "https://192.168.110.113:4530/xiaozhi/ota/";
        //_agent.Token = "test-token";

        _agent.OtaUrl = appsetting?["Server"]?["OtaUrl"]?.ToString();
        LogConsole.InfoLine($"初始OTA URL: {_agent.OtaUrl}");
        _agent.WsUrl = appsetting?["Server"]?["WsUrl"]?.ToString();
        LogConsole.InfoLine($"初始WebSocket URL: {_agent.WsUrl}");

        //_agent.AudioService = new 
        //_agent.OnAudioPcmEvent =
        _agent.OnMessageEvent += Agent_OnMessageEvent;
        _agent.OnOtaEvent += Agent_OnOtaEvent;

        LogConsole.InfoLine($"设备ID: {_agent.DeviceId}");
        LogConsole.InfoLine($"客户端ID: {_agent.ClientId}");
        LogConsole.InfoLine($"User-Agent: {_agent.UserAgent}");

        /*登录测试......*/
        var loginJson = appsetting?["Server"]?["Login"]?.ToString();
        if (string.IsNullOrWhiteSpace(loginJson))
        {
            LogConsole.InfoLine($"没有配置登录服务器的地址...");
            return;
        }
        var loginMdl = Newtonsoft.Json.JsonConvert.DeserializeObject<LoginModel>(loginJson);
        if (loginMdl == null)
        {
            LogConsole.InfoLine($"登录服务器的地址配置错误...");
            return;
        }
        LogConsole.InfoLine($"初始登录服务器Url: {loginMdl.Url}");
        while (true)
        {
            var loginRlt = await _agent.Login(loginMdl);
            if (loginRlt == null || loginRlt.Code != 0)
            {
                Thread.Sleep(1000);
                LogConsole.InfoLine($"登录失败，重新登录...");
                continue;
            }
            break;
        }
        LogConsole.InfoLine($"登录服务器成功，开始启动 小智XiaoZhiSharp客户端...");

        await _agent.Start();

        TickTimer.TT.RunTimer(_agent);

        _ = Task.Run(async () =>
        {
            while (true)
            {
                if (_agent.ConnectState != System.Net.WebSockets.WebSocketState.Open)
                {
                    await _agent.Restart();
                    LogConsole.InfoLine("服务器重连...");
                    await Task.Delay(3000);
                }

                if (OperatingSystem.IsWindows())
                {
                    bool isCapsLockOn = Console.CapsLock;//Console.CapsLock只支持Windows平台
                    //Console.WriteLine($"当前 Caps Lock 状态: {(isCapsLockOn ? "开启" : "关闭")}");
                    if (isCapsLockOn)
                    {
                        if (_agent.IsRecording == false)
                        {
                            _audioMode = "manual";
                            LogConsole.InfoLine("开始录音... 再次按Caps键结束录音");
                            await _agent.StartRecording("manual");
                            continue;
                        }
                    }
                    if (!isCapsLockOn)
                    {
                        if (_agent.IsRecording == true)
                        {
                            if (_audioMode == "manual")
                            {
                                await _agent.StopRecording();
                                LogConsole.InfoLine("结束录音");
                                continue;
                            }
                        }
                    }
                }

                await Task.Delay(100); // 避免过于频繁的检查
            }
        });

        while (true)
        {
            string? input = Console.ReadLine();
            if (!string.IsNullOrEmpty(input))
            {
                if (input.ToLower() == "restart")
                {
                    await _agent.Restart();
                }
                else
                {
                    await _agent.ChatMessage(input);
                }
            }
            else
            {
                if (!_agent.IsRecording)
                {
                    //Console.Title = "开始录音...";
                    //LogConsole.InfoLine("开始录音... 再次回车结束录音");
                    _audioMode = "auto";
                    LogConsole.InfoLine("开始录音... Auto");
                    await _agent.StartRecording("auto");
                }
                else
                {
                    //await _agent.StopRecording();//auto模式下当检测到静音会自动结束录音
                    //Console.Title = "小智XiaoZhiSharp客户端";
                    LogConsole.InfoLine("结束录音");
                }
            }
        }
    }

    private static async Task Agent_OnOtaEvent(OtaResponse? otaResponse)
    {
        if (otaResponse != null)
        {
            LogConsole.InfoLine("=== OTA检查结果 ===");

            if (otaResponse.Activation != null)
            {
                LogConsole.InfoLine($"设备激活码: {otaResponse.Activation.Code}");
                LogConsole.InfoLine($"激活消息: {otaResponse.Activation.Message}");
            }

            if (otaResponse.Firmware != null && !string.IsNullOrEmpty(otaResponse.Firmware.Url))
            {
                LogConsole.InfoLine($"发现固件更新: {otaResponse.Firmware.Version}");
                LogConsole.InfoLine($"下载地址: {otaResponse.Firmware.Url}");
            }

            if (otaResponse.WebSocket != null)
            {
                LogConsole.InfoLine($"WebSocket服务器: {otaResponse.WebSocket.Url}");
            }

            if (otaResponse.Mqtt != null)
            {
                LogConsole.InfoLine($"MQTT服务器: {otaResponse.Mqtt.Endpoint}");
            }

            LogConsole.InfoLine("=== OTA检查完成 ===");
        }
        else
        {
            LogConsole.InfoLine("OTA检查失败，将使用默认配置");
        }
    }

    private static async Task Agent_OnMessageEvent(string type, string message)
    {
        switch (type.ToLower())
        {
            case "question":
                LogConsole.WriteLine(MessageType.Send, $"[{type}] {message}");
                break;
            case "answer":
                LogConsole.WriteLine(MessageType.Recv, $"[{type}] {message}");
                break;
            case "mcp":
                string resultMessage = await _mcpService.McpMessageHandle(message);
                if (!string.IsNullOrEmpty(resultMessage))
                    await _agent.McpMessage(resultMessage);
                break;
            default:
                LogConsole.InfoLine($"[{type}] {message}");
                break;
        }
    }
}
