using DocumentFormat.OpenXml.EMMA;
using DocumentFormat.OpenXml.Math;
using DocumentFormat.OpenXml.Spreadsheet;
using Infrastructure;
using Infrastructure.Cache;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MQTTnet;
using OpenAuth.App.ServiceApp;
using OpenAuth.App.ServiceApp.Response;
using OpenAuth.Repository.Domain;
using StackExchange.Redis;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.PixelFormats;
using Minio;
using Infrastructure.CloudSdk.minio;

namespace OpenAuth.WebApi.Controllers.ServiceControllers
{
    /// <summary>
    /// 机场运维
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class AirportMaintenanceController : ControllerBase
    {
        private readonly AirportMaintenanceApp _app;
        private readonly MqttClientManager _mqttClientManager;
        private readonly MqttMessageCenter _mqttCenter;
        private readonly RedisCacheContext _cache;
        private readonly HttpClient _httpClient;
        private readonly MinioService _minioService;

        public AirportMaintenanceController(AirportMaintenanceApp app, MqttClientManager mqttClientManager,
            MqttMessageCenter mqttCenter, RedisCacheContext cache, HttpClient httpClient, MinioService minioService)
        {
            _app = app;
            _mqttClientManager = mqttClientManager;
            _mqttCenter = mqttCenter;
            _cache = cache;
            _httpClient = httpClient;
            _minioService = minioService;
        }

        /// <summary>
        /// 机场注册 注册码生成
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Obsolete]
        public async Task<Response<LasaDeviceBindingCode>> GetDeviceBindingCode()
        {
            var result = new Response<LasaDeviceBindingCode>();
            try
            {
                result = await _app.GetDeviceBindingCode();
                //发送MQTT消息
                if (result.Code == 200 && result.Result != null)
                {
                    var topicRequest = $"thing/product/{result.Result.DeviceBindingCode}/requests";
                    var requestData = new
                    {
                        bid = Guid.NewGuid().ToString(),
                        method = "airport_organization_bind",
                        tid = Guid.NewGuid().ToString(),
                        timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                        data = new
                        {
                            bind_devices = new[]
                            {
                                new
                                {
                                    device_binding_code = result.Result.DeviceBindingCode,
                                    organization_id = result.Result.OrgId
                                }
                            }
                        }
                    };
                    string payload = JsonSerializer.Serialize(requestData);
                    await _mqttClientManager.PublishAsync(topicRequest, payload);
                    //在这个地方在接收一下？
                }
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 机场注册 注册码生成
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<LasaGateway>> GetGateway()
        {
            var result = new Response<LasaGateway>();
            try
            {
                result = await _app.GetGateway();
                //自动更新主题  
                string sn = result.Result.GatewaySn;
                var topics = new List<string>();
                topics.AddRange(new[]
                {
                    $"thing/product/{sn}/osd",
                    $"thing/product/{sn}/events",
                    $"thing/product/{sn}/requests",
                    $"thing/product/{sn}/services"
                });
                await _mqttCenter.SubscribeAsync(topics.ToArray());
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 获取网关列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Response<PageInfo<List<LasaGateway>>>> GetGatewayList(int page, int limit)
        {
            var result = new Response<PageInfo<List<LasaGateway>>>();
            try
            {
                result = await _app.GetPageList(page, limit);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        #region 固件版本管理

        /// <summary>
        /// 添加固件版本
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public async Task<Response<bool>> AddFirmware(LasaFirmware info)
        {
            var result = new Response<bool>();
            try
            {
                result = await _app.AddFirmware(info);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 修改无人机或机场版本
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public async Task<Response<bool>> UpdateFirmware(string id, string version, int type)
        {
            var result = new Response<bool>();
            try
            {
                result = await _app.UpdateFirmware(id, version, type);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 上传固件文件
        /// </summary>
        /// <param name="xmlFile"></param>
        /// <returns></returns>
        [HttpPost("upload")]
        [AllowAnonymous]
        public async Task<IActionResult> UploadFirmwareFile(IFormFile xmlFile)
        {
            if (xmlFile == null || xmlFile.Length == 0)
                return BadRequest("文件为空");
            var path = await _app.UploadFile(xmlFile);
            return Ok(new { message = "上传成功", path });
        }

        #endregion

        /// <summary>
        /// 切换相机
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<int>> ExchangeCamera(Zhibo zhiboReq)
        {
            Response<int> response = new Response<int>();
            try
            {
                var videoids = zhiboReq.videoId.Split("/");
                var topicRequest = $"thing/product/" + videoids[0] + "/services";
                var requestData = new
                {
                    bid = Guid.NewGuid().ToString(),
                    method = "live_camera_change",
                    tid = Guid.NewGuid().ToString(),
                    timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                    data = new
                    {
                        camera_position = zhiboReq.position,
                        video_id = zhiboReq.videoId
                    }
                };
                string payload = JsonSerializer.Serialize(requestData);
                await _mqttClientManager.PublishAsync(topicRequest, payload);

                var topicRequest1 = $"thing/product/" + videoids[0] + "/services_reply";

                await _mqttClientManager.SubscribeAsync(topicRequest1, async (args) =>
                {
                    var payload = args.ApplicationMessage.Payload;
                    var message = Encoding.UTF8.GetString(payload);
                    Console.WriteLine($"收到主题 [{args.ApplicationMessage.Topic}] 的消息: {message}");
                    await Task.CompletedTask;
                });
                response.Result = 0;
            }
            catch (Exception ex)
            {
                response.Code = 500;
                response.Message = ex.Message;
            }

            return response;
            ;
        }


        /// <summary>
        /// 设置直播镜头
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<int>> SetCamera(Zhibo zhiboReq)
        {
            Response<int> response = new Response<int>();
            try
            {
                var videoids = zhiboReq.videoId.Split("/");
                var topicRequest = $"thing/product/" + videoids[0] + "/services";
                var requestData = new
                {
                    bid = Guid.NewGuid().ToString(),
                    method = "live_lens_change",
                    tid = Guid.NewGuid().ToString(),
                    timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                    data = new
                    {
                        video_type = zhiboReq.cameraType,
                        video_id = zhiboReq.videoId
                    }
                };
                string payload = JsonSerializer.Serialize(requestData);
                await _mqttClientManager.PublishAsync(topicRequest, payload);

                var topicRequest1 = $"thing/product/" + videoids[0] + "/services_reply";

                await _mqttClientManager.SubscribeAsync(topicRequest1, async (args) =>
                {
                    var payload = args.ApplicationMessage.Payload;
                    var message = Encoding.UTF8.GetString(payload);
                    Console.WriteLine($"收到主题 [{args.ApplicationMessage.Topic}] 的消息: {message}");
                    await Task.CompletedTask;
                });

                response.Result = 0;
            }
            catch (Exception ex)
            {
                response.Code = 500;
                response.Message = ex.Message;
            }

            return response;
        }


        /// <summary>
        /// 设置直播清晰度
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<int>> SetCameraVideo(Zhibo zhiboReq)
        {
            Response<int> response = new Response<int>();
            try
            {
                var videoids = zhiboReq.videoId.Split("/");
                var topicRequest = $"thing/product/" + videoids[0] + "/services";
                var requestData = new
                {
                    bid = Guid.NewGuid().ToString(),
                    method = "live_set_quality",
                    tid = Guid.NewGuid().ToString(),
                    timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                    data = new
                    {
                        video_quality = zhiboReq.videoQuality,
                        video_id = zhiboReq.videoId
                    }
                };
                string payload = JsonSerializer.Serialize(requestData);
                await _mqttClientManager.PublishAsync(topicRequest, payload);

                var topicRequest1 = $"thing/product/" + videoids[0] + "/services_reply";

                await _mqttClientManager.SubscribeAsync(topicRequest1, async (args) =>
                {
                    var payload = args.ApplicationMessage.Payload;
                    var message = Encoding.UTF8.GetString(payload);
                    Console.WriteLine($"收到主题 [{args.ApplicationMessage.Topic}] 的消息: {message}");
                    await Task.CompletedTask;
                });

                response.Result = 0;
            }
            catch (Exception ex)
            {
                response.Code = 500;
                response.Message = ex.Message;
            }

            return response;
        }


        /// <summary>
        /// 停止直播
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<int>> EndLive(Zhibo zhiboReq)
        {
            Response<int> response = new Response<int>();
            try
            {
                var videoids = zhiboReq.videoId.Split("/");
                var topicRequest = $"thing/product/" + videoids[0] + "/services";
                var requestData = new
                {
                    bid = Guid.NewGuid().ToString(),
                    method = "live_stop_push",
                    tid = Guid.NewGuid().ToString(),
                    timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                    data = new
                    {
                        video_id = zhiboReq.videoId
                    }
                };
                string payload = JsonSerializer.Serialize(requestData);
                await _mqttClientManager.PublishAsync(topicRequest, payload);

                var topicRequest1 = $"thing/product/" + videoids[0] + "/services_reply";

                await _mqttClientManager.SubscribeAsync(topicRequest1, async (args) =>
                {
                    var payload = args.ApplicationMessage.Payload;
                    var message = Encoding.UTF8.GetString(payload);
                    Console.WriteLine($"收到主题 [{args.ApplicationMessage.Topic}] 的消息: {message}");
                    await Task.CompletedTask;
                });

                response.Result = 0;
            }
            catch (Exception ex)
            {
                response.Code = 500;
                response.Message = ex.Message;
            }

            return response;
        }


        /// <summary>
        /// 关联minio
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<int>> RefMinio(Zhibo zhiboReq)
        {
            Response<int> response = new Response<int>();
            try
            {
                var videoids = zhiboReq.videoId.Split("/");
                var topicRequest = $"thing/product/" + videoids[0] + "/requests_reply";
                var requestData = new
                {
                    bid = Guid.NewGuid().ToString(),
                    method = "storage_config_get",
                    tid = Guid.NewGuid().ToString(),
                    timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                    data = new
                    {
                        output = new
                        {
                            bucket = "test",
                            credentials = new
                            {
                                access_key_id = "minioadmin",
                                access_key_secret = "minioadmin",
                                expire = 3600,
                                security_token = "security_token"
                            },
                            endpoint = "175.27.168.120:6013",
                            object_key_prefix = "",
                            provider = "ali",
                            region = "hz"
                        },
                        result = 0
                    }
                };


                response.Result = 0;
            }
            catch (Exception ex)
            {
                response.Code = 500;
                response.Message = ex.Message;
            }

            return response;
        }


        /// <summary>
        /// 开始直播
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<int>> StartLive(Zhibo zhiboReq)
        {
            Response<int> response = new Response<int>();
            try
            {
                var videoids = zhiboReq.videoId.Split("/");
                var topicRequest = $"thing/product/" + videoids[0] + "/services";
                var requestData = new
                {
                    bid = Guid.NewGuid().ToString(),
                    method = "live_start_push",
                    tid = Guid.NewGuid().ToString(),
                    timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                    data = new
                    {
                        url_type = zhiboReq.urlType,
                        url = zhiboReq.url,
                        video_quality = zhiboReq.videoQuality,
                        video_id = zhiboReq.videoId
                    }
                };
                string payload = JsonSerializer.Serialize(requestData);
                await _mqttClientManager.PublishAsync(topicRequest, payload);

                var topicRequest1 = $"thing/product/" + videoids[0] + "/services_reply";
                await _mqttClientManager.SubscribeAsync(topicRequest1, async (args) =>
                {
                    var payload1 = args.ApplicationMessage.Payload;
                    var message = Encoding.UTF8.GetString(payload1);
                    Console.WriteLine($"收到主题 [{args.ApplicationMessage.Topic}] 的消息: {message}");
                    await Task.CompletedTask;
                });

                response.Result = 0;
            }
            catch (Exception ex)
            {
                response.Code = 500;
                response.Message = ex.Message;
            }

            return response;
        }


        #region redis 多用户控制

        /// <summary>
        /// 添加修改mqtt客户端信息
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Response<bool>> AddOrUpdateRedisUser(MqttClientResp info)
        {
            var result = new Response<bool>();
            try
            {
                var clientKey = $"client:{info.UserId}";
                string lockSetKey = "locked_users";

                // 查询所有锁定用户
                var existingLocked = await _cache.SetMembersAsync(lockSetKey);

                // 如果有锁定用户，并且锁定的用户不是当前用户，则拒绝
                if (existingLocked.Length > 0 && info.IsLock == true)
                {
                    bool isCurrentUserLocked = existingLocked.Any(u => u == info.UserId);
                    if (!isCurrentUserLocked)
                    {
                        result.Code = 400;
                        result.Message = "已有其他用户处于锁定状态，不能添加新的锁定用户。";
                        result.Result = false;
                        return result;
                    }
                }

                // 存客户端信息
                _cache.HashSetAsync(clientKey, new HashEntry[]
                {
                    new("ClientId", info.ClientId),
                    new("UserId", info.UserId),
                    new("UserName", info.UserName),
                    new("ConnectTime", info.ConnectTime.ToString("O")),
                    new("IsLock", info.IsLock ? "true" : "false")
                });

                if (info.IsLock)
                {
                    await _cache.SetAddAsync(lockSetKey, info.UserId);
                }
                else
                {
                    await _cache.SetRemoveAsync(lockSetKey, info.UserId);
                }

                result.Result = true;
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 获取当前用户mqtt客户端信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Response<MqttClientResp>> GetRedisUser(string id)
        {
            var result = new Response<MqttClientResp>();
            try
            {
                result.Result = ParseClient(await _cache.HashGetAllAsync($"client:{id}"));
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        private MqttClientResp ParseClient(HashEntry[] entries)
        {
            if (entries == null || entries.Length == 0)
                return null;
            var dict = entries.ToDictionary(e => e.Name.ToString(), e => e.Value.ToString());
            return new MqttClientResp
            {
                ClientId = dict["ClientId"],
                UserId = dict["UserId"],
                UserName = dict["UserName"],
                ConnectTime = DateTime.Parse(dict["ConnectTime"]),
                IsLock = bool.Parse(dict["IsLock"])
            };
        }

        /// <summary>
        /// 获取所有锁定的用户客户端信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<MqttClientResp>> GetLockedClients()
        {
            var userIds = await _cache.SetMembersAsync("locked_users");

            var result = new List<MqttClientResp>();

            foreach (var userId in userIds)
            {
                var entries = await _cache.HashGetAllAsync($"client:{userId}");
                if (entries.Length > 0)
                    result.Add(ParseClient(entries));
            }

            return result;
        }

        #endregion

        #region 获取告警信息

        /// <summary>
        /// 获取告警信息
        /// </summary>
        /// <param name="level">告警等级，0-全部，1-注意，2-告警</param>
        /// <param name="model">设备，0-全部，1-设备管理，2-媒体管理，3-HMS告警</param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Response<PageInfo<List<LasaManageDeviceHms>>>> GetManageDeviceHmsList(int level, int model,
            DateTime startTime, DateTime endTime, int page, int limit, string message, string getway)
        {
            var result = new Response<PageInfo<List<LasaManageDeviceHms>>>();
            try
            {
                result = await _app.GetManageDeviceHmsList(level, model, startTime, endTime, page, limit, message,
                    getway);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        #endregion

        #region 日志信息

        /// <summary>
        /// 根据设备sn读取实时数据
        /// </summary>
        /// <param name="sn">设备sn</param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<Response<PageInfo<List<LasaLog>>>> GetLogList(string sn, DateTime startTime, DateTime endTime,
            int page, int limit)
        {
            var result = new Response<PageInfo<List<LasaLog>>>();
            try
            {
                result = await _app.GetLogList(sn, startTime, endTime, page, limit);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        #endregion


        [HttpGet]
        public async Task<Response<PageInfo<List<LasaMediaFile>>>> GetMediaFile(string taskId, string airId,
            string device, int? type, string picname, DateTime startTime, DateTime endTime, int page, int limit,
            string parentKey, int? objectKeyExist)
        {
            var result = new Response<PageInfo<List<LasaMediaFile>>>();
            try
            {
                result = await _app.GetMediaFile(taskId, airId, device,type, picname, startTime, endTime, page, limit,
                    parentKey, objectKeyExist);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }


        [HttpGet]
        [AllowAnonymous]
        public async Task<Response<string>> UpdatePicStatus(string id, int showOnMap, int display, string fileTags,
            string graffitiJson)
        {
            var result = new Response<string>();
            try
            {
                result = await _app.UpdatePicStatus(id, showOnMap, display, fileTags, graffitiJson);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        [HttpGet]
        [AllowAnonymous]
        public async Task<Response<string>> deletepic(string ids)
        {
            var result = new Response<string>();
            try
            {
                result = await _app.deletepic(ids);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        [HttpGet]
        [AllowAnonymous]
        public async Task<Response<string>> UpdatePicName(string id, string name)
        {
            var result = new Response<string>();
            try
            {
                result = await _app.UpdatePicName(id, name);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }


        [HttpGet]
        [AllowAnonymous]
        public async Task<Response<string>> UpdatePicParentKey(string id, string ParentKey)
        {
            var result = new Response<string>();
            try
            {
                result = await _app.UpdatePicParentKey(id, ParentKey);
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }

        [HttpGet]
        [AllowAnonymous]
        public async Task<Response<string>> getMiniPic()
        {
            var result = new Response<string>();
            try
            {
                // string presignedUrl = "http://175.27.168.120:6014/test/44fc8b4b-9448-4e79-a71d-536d094b8598/ad854032-d4b7-42dc-8ac0-d1faef0ebc1e/DJI_202507231000_002_ad854032-d4b7-42dc-8ac0-d1faef0ebc1e/DJI_20250723100110_0001_V.jpeg";
                var imageStream = _minioService.GetObjectAsStream("test",
                    "44fc8b4b-9448-4e79-a71d-536d094b8598/ad854032-d4b7-42dc-8ac0-d1faef0ebc1e/DJI_202507231000_002_ad854032-d4b7-42dc-8ac0-d1faef0ebc1e/DJI_20250723100110_0001_V.jpeg");
                // var imageStream = await _httpClient.GetStreamAsync(presignedUrl);

                using (var image = Image.Load(imageStream.Result))
                {
                    var width = image.Width;
                    var height = image.Height;
                    var thumbnailSize = 100; // 缩略图大小，可以根据需要调整
                    var thumbnail = image.Clone(ctx => ctx.Resize(new ResizeOptions
                    {
                        Size = new Size(thumbnailSize, thumbnailSize),
                        Mode = ResizeMode.Crop // 根据需要选择裁剪或填充模式
                    }));

                    // 将缩略图保存到内存流中（为了上传）
                    using (var memoryStream = new MemoryStream())
                    {
                        thumbnail.SaveAsJpeg(memoryStream); // 可以根据需要选择不同的格式，如Png, Bmp等。
                        memoryStream.Position = 0; // 重置流的位置到开始处

                        // 上传缩略图到MinIO
                        await _minioService.PutObjectAsync("test", "suolue_DJI_20250723100110_0001_V.jpeg",
                            "abc/suolue_DJI_20250723100110_0001_V.jpeg", memoryStream); // 根据实际格式修改Content-Type
                    }
                }
            }
            catch (Exception ex)
            {
                result.Code = 500;
                result.Message = ex.Message;
            }

            return result;
        }
    }
}