using DocumentFormat.OpenXml.Bibliography;
using Infrastructure;
using Infrastructure.Cache;
using Infrastructure.CloudSdk.minio;
using Infrastructure.Helpers;
using Microsoft.DotNet.InternalAbstractions;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using OpenAuth.App.BaseApp.Base;
using OpenAuth.App.BasicQueryService;
using OpenAuth.App.Interface;
using OpenAuth.App.ServiceApp.Algo;
using OpenAuth.App.ServiceApp.Algo.Request;
using OpenAuth.App.ServiceApp.Response;
using OpenAuth.Repository;
using OpenAuth.Repository.Domain;
using OpenAuth.WebApi;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OpenAuth.App.ServiceApp
{
    /// <summary>
    /// 消息推送模块
    /// </summary>
    public class LasaPlatformPushApp : SqlSugarBaseApp<LasaPlatform, SugarDbContext>
    {
        private readonly ILogger<LasaPlatformPushApp> _logger;
        public LasaPlatformPushApp(ILogger<LasaPlatformPushApp> logger, ISugarUnitOfWork<SugarDbContext> unitWork, ISimpleClient<LasaPlatform> repository, IAuth auth) : base(unitWork, repository, auth)
        {
            _logger = logger;
        }
        /// <summary>
        /// 获取推送平台
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<Response<PageInfo<List<LasaPlatform>>>> GetPlatformList(int page, int limit, string key)
        {
            RefAsync<int> totalCount = 0;
            using (var db = UnitWork.CreateContext())
            {
                var list = await db.LasaPlatform.AsQueryable()
                    .Where((a) => a.IsDelete == false)
                    .WhereIF(!string.IsNullOrEmpty(key), (a) => a.PlatformName.Contains(key))
                    .ToPageListAsync(page, limit, totalCount);
                return new Response<PageInfo<List<LasaPlatform>>>
                {
                    Result = new PageInfo<List<LasaPlatform>> { Items = list, Total = totalCount }
                };
            }
        }
        /// <summary>
        /// 添加平台信息
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<Response<bool>> AddPlatform(LasaPlatform info)
        {
            using (var db = UnitWork.CreateContext())
            {
                info.Id = Guid.NewGuid().ToString();
                info.IsDelete = false;
                await db.LasaPlatform.InsertAsync(info);
                if (db.Commit())
                    return new Response<bool>
                    {
                        Result = true,
                        Message = "添加成功"
                    };
                else
                    return new Response<bool>
                    {
                        Result = false,
                        Message = "添加失败"
                    };
            }
        }
        //修改平台信息
        public async Task<Response<bool>> UpdatePlatform(LasaPlatform info)
        {
            using (var db = UnitWork.CreateContext())
            {
                // 编辑
                await db.LasaPlatform.UpdateAsync(u => new LasaPlatform
                {
                    Url = info.Url,
                    PlatformName = info.PlatformName,
                    RoutingKey = info.RoutingKey,
                    Exchange = info.Exchange,
                    Topic = info.Topic
                }, u => u.Id == info.Id);
                // 提交事务
                if (db.Commit())
                {
                    return new Response<bool>
                    {
                        Result = true,
                        Message = "修改成功"
                    };
                }
                else
                {
                    return new Response<bool>
                    {
                        Result = false,
                        Message = "修改失败"
                    };
                }
            }
        }
        //删除平台信息
        public async Task<Response<bool>> DeletePlatform(string id)
        {
            using (var db = UnitWork.CreateContext())
            {
                // 编辑
                await db.LasaPlatform.UpdateAsync(u => new LasaPlatform
                {
                    IsDelete = true,
                }, u => u.Id == id);
                //await db.LasaPlatform.DeleteByIdAsync(id);
                if (db.Commit())
                    return new Response<bool>
                    {
                        Result = true,
                        Message = "删除成功"
                    };
                else
                    return new Response<bool>
                    {
                        Result = false,
                        Message = "删除失败"
                    };
            }
        }

        /// <summary>
        /// 添加ai算法任务信息
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<Response<bool>> AddTaskAi(LasaTaskAi info)
        {
            using (var db = UnitWork.CreateContext())
            {
                if (string.IsNullOrEmpty(info.Id))
                    info.Id = Guid.NewGuid().ToString();
                await db.LasaTaskAi.InsertAsync(info);
                if (db.Commit())
                    return new Response<bool>
                    {
                        Result = true,
                        Message = "添加成功"
                    };
                else
                    return new Response<bool>
                    {
                        Result = false,
                        Message = "添加失败"
                    };
            }
        }
        /// <summary>
        /// 添加ai算法推送log
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<Response<bool>> AddTaskAiLog(LasaTaskAiLog info)
        {
            using (var db = UnitWork.CreateContext())
            {
                if (string.IsNullOrEmpty(info.Id))
                    info.Id = Guid.NewGuid().ToString();
                await db.LasaTaskAiLog.InsertAsync(info);
                if (db.Commit())
                    return new Response<bool>
                    {
                        Result = true,
                        Message = "添加成功"
                    };
                else
                    return new Response<bool>
                    {
                        Result = false,
                        Message = "添加失败"
                    };
            }
        }

        /// <summary>
        /// 获取推送记录
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<Response<PageInfo<List<LasaTaskAiLogResp>>>> GetAiLogList(int page, int limit, string key)
        {
            RefAsync<int> totalCount = 0;
            using (var db = UnitWork.CreateContext())
            {
                var list = await db.LasaTaskAiLog.AsQueryable()
                    .LeftJoin<LasaTaskAi>((a, b) => a.AiTaskId == b.Id)
                    .WhereIF(!string.IsNullOrEmpty(key), (a, b) => a.Data.Contains(key))
                    .Select((a, b) => new LasaTaskAiLogResp()
                    {
                        AiTaskId = a.AiTaskId,
                        State = a.State,
                        CreateTime = a.CreateTime,
                        Data = a.Data,
                        Platform = b.Platform,
                    })
                    .ToPageListAsync(page, limit, totalCount);
                return new Response<PageInfo<List<LasaTaskAiLogResp>>>
                {
                    Result = new PageInfo<List<LasaTaskAiLogResp>> { Items = list, Total = totalCount }
                };
            }
        }


        public async Task<Response<bool>> AddImgTopic(string payload)
        {
            using var db = UnitWork.CreateContext();

            var aiinfo = JsonConvert.DeserializeObject<AiImgReq>(payload);
            if (aiinfo == null)
            {
                return new Response<bool>
                {
                    Result = false,
                    Message = "添加失败"
                };
            }

            _logger.LogInformation("标签信息：{tag}", JsonConvert.SerializeObject(aiinfo.tag));
            _logger.LogInformation("aiid：{aiid}", aiinfo.aiid);

            var config = ConfigHelper.GetConfigRoot();
            var imageBaseUrl = $"http://{config["Minio:Endpoint"]}/{config["Minio:BucketName"]}/";

            var (lat, lng) = GetDroneLocation(aiinfo);

            // 一次性加载模型标签
            var modelDict = (await db.LasaModelLabel.AsQueryable().Where(r => r.PId == aiinfo.aiid).ToListAsync())
                                               .ToDictionary(x => x.EnumValue, x => x.Name);

            foreach (var tag in aiinfo.tag)
            {
                if (tag.confidence < 0.3)
                    continue;

                var tagKey = tag.class_id.ToString();
                var achievement = await db.LasaAiAchievement
                    .GetFirstAsync(r => r.TaskId == aiinfo.taskid && r.Tag == tagKey);
                if (achievement == null)
                {
                    await db.LasaAiAchievement.InsertAsync(new LasaAiAchievement
                    {
                        Id = Guid.NewGuid().ToString(),
                        CreateTime = DateTime.Now,
                        TaskId = aiinfo.taskid,
                        AlgoId = aiinfo.aiid,
                        AiModel = "yolo12x",
                        Tag = tag.class_id.ToString(),
                        Title = modelDict.TryGetValue(tag.class_id, out var name) ? name : string.Empty,
                        ConfidenceLevel = (float)Math.Round(tag.confidence, 2) * 100,
                        Cover = imageBaseUrl + aiinfo.path,
                        Lat = (float)lat,
                        Lng = (float)lng
                    });
                }
                await db.LasaAiAchievementDetail.InsertAsync(new LasaAiAchievementDetail
                {
                    Id = Guid.NewGuid().ToString(),
                    AiAchievementId = achievement.Id,
                    Image = imageBaseUrl + aiinfo.path,
                    Lat = lat,
                    Lng = lng
                });
            }

            if (db.Commit())
                return new Response<bool>
                {
                    Result = true,
                    Message = "添加成功"
                };
            else
                return new Response<bool>
                {
                    Result = false,
                    Message = "添加失败"
                };
        }
        private static (double lat, double lng) GetDroneLocation(AiImgReq aiinfo)
        {
            if (aiinfo.drone_info?.data == null)
                return (0.0, 0.0);

            return (
                aiinfo.drone_info.data.latitude ?? 0.0,
                aiinfo.drone_info.data.longitude ?? 0.0
            );
        }

        #region 推送统计

        public async Task<Response<List<PlatformDashboardResp>>> TaskAiStatistics()
        {
            var today = DateTime.Today;
            var tomorrow = today.AddDays(1);
            using (var db = UnitWork.CreateContext())
            {
                var list = await db.LasaTaskAi.AsQueryable()
                    .LeftJoin<LasaTaskAiLog>((t, p) => t.AiTaskId == p.Id)
                    .Where((t, p) => p.CreateTime >= today && p.CreateTime < tomorrow)
                    .GroupBy((t, p) => new { t.Platform, t.State })
                    .Select((t, p) => new
                    {
                        Platform = t.Platform,
                        ConnectState = t.State,
                        TodayPushCount = SqlFunc.AggregateCount(p.Id),
                        TodaySuccessCount = SqlFunc.AggregateSum(
                        SqlFunc.IIF(p.State == true, 1, 0)
                    )
                    }).ToListAsync();

                // 计算成功率
                var result = list.Select(x => new PlatformDashboardResp
                {
                    Platform = x.Platform,
                    ConnectState = x.ConnectState,
                    TodayPushCount = x.TodayPushCount,
                    TodaySuccessCount = x.TodaySuccessCount,
                    SuccessRate = x.TodayPushCount == 0 ? 0 : Math.Round((decimal)x.TodaySuccessCount / x.TodayPushCount * 100, 2)
                }).ToList();


                return new Response<List<PlatformDashboardResp>>
                {
                    Result = result,
                    Message = "获取数据成功"
                };
            }
        }
        public async Task<Response<List<WeekPushChartResp>>> GetWeekPushChart()
        {
            // 本周一 00:00
            var weekStart = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + 1);
            // 下周一 00:00
            var weekEnd = weekStart.AddDays(7);
            using (var db = UnitWork.CreateContext())
            {

                var list = await db.LasaTaskAi.AsQueryable()
                    .InnerJoin<LasaTaskAiLog>((t, p) => t.AiTaskId == p.AiTaskId)
                    .Where((t, p) => p.CreateTime >= weekStart && p.CreateTime < weekEnd)
                    .GroupBy((t, p) => new
                    {
                        Year = SqlFunc.DateValue(p.CreateTime, DateType.Year),
                        Month = SqlFunc.DateValue(p.CreateTime, DateType.Month),
                        Day = SqlFunc.DateValue(p.CreateTime, DateType.Day),
                        t.Platform
                    })
                    .Select((t, p) => new WeekPushChartResp
                    {
                        Year = SqlFunc.DateValue(p.CreateTime, DateType.Year),
                        Month = SqlFunc.DateValue(p.CreateTime, DateType.Month),
                        Day = SqlFunc.DateValue(p.CreateTime, DateType.Day),
                        Platform = t.Platform,
                        PushCount = SqlFunc.AggregateCount(p.Id)
                    }).MergeTable()
                    .OrderBy(it => it.Year)
                    .OrderBy(it => it.Month)
                    .OrderBy(it => it.Day)
                    .ToListAsync();
                return new Response<List<WeekPushChartResp>>
                {
                    Result = list,
                    Message = "获取数据成功"
                };
            }

        }


        #endregion
    }
}
