using DocumentFormat.OpenXml.Office2021.DocumentTasks;
using DocumentFormat.OpenXml.Spreadsheet;
using Infrastructure;
using Infrastructure.Extensions;
using Microsoft.Extensions.Configuration;
using NPOI.SS.Formula.Functions;
using OpenAuth.App.BaseApp;
using OpenAuth.App.BaseApp.Base;
using OpenAuth.App.Interface;
using OpenAuth.App.ServiceApp.Request;
using OpenAuth.App.ServiceApp.Response;
using OpenAuth.Repository;
using OpenAuth.Repository.Domain;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OpenAuth.App.ServiceApp
{
    public class AdminTaskManageApp : SqlSugarBaseApp<InsTask, SugarDbContext>
    {
        private readonly IConfiguration _configuration;
        private readonly ISqlSugarClient client;
        private ImMsgApp _immsgApp;
        public AdminTaskManageApp(ISugarUnitOfWork<SugarDbContext> unitWork, ISimpleClient<InsTask> repository, IAuth auth, ISqlSugarClient sqlSugarClient, IConfiguration configuration, ImMsgApp immsgApp) : base(unitWork, repository, auth)
        {
            _configuration = configuration;
            this.client = sqlSugarClient;
            _immsgApp = immsgApp;
        }
        private static string[] chineseNumbers = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
        /// <summary>
        /// 添加任务
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<Response<string>> AddTask(InsTaskReq req)
        {
            using (var db = base.UnitWork.CreateContext())
            {
                var user = _auth.GetCurrentUser().User;
                // 获取ai解译成果
                var aishp = await db.InsAishp.GetFirstAsync(r => r.Id == req.ShpId);

                var insTaskInfo = req.MapTo<InsTask>();
                insTaskInfo.Id = Guid.NewGuid().ToString();
                insTaskInfo.CreateTime = DateTime.Now;
                insTaskInfo.CreateUser = user == null ? "" : user.Id.ToString();
                insTaskInfo.UpdateTime = DateTime.Now;
                insTaskInfo.UpdateUser = user == null ? "" : user.Id.ToString();
                insTaskInfo.State = 0;
                insTaskInfo.IsCompleted = false;
                insTaskInfo.CreateUserName = user == null ? "" : user.Name;
                insTaskInfo.UpdateUserName = user == null ? "" : user.Name;
                // 拆分图斑数
                int groupNum = (int)Math.Ceiling((double)aishp.ShpCount / 1000);

                List<InsTaskgroup> insTaskGroup = new List<InsTaskgroup>();
                int lastGroupRemaining = (int)aishp.ShpCount;

                for (var i = 1; i <= groupNum; i++)
                {
                    int everyNum = 1000;
                    string chineseGroupName = $"{ConvertToChineseNumber(i)}组";
                    // 如果是最后一组，并且剩余的少于1000，将剩余的任务加到上一组
                    if (i == groupNum && lastGroupRemaining < 1000)
                    {
                        //everyNum = lastGroupRemaining;
                        //if (i > 1)
                        //{
                        //    // 更新上一组的 EndNum
                        //    var lastGroup = insTaskGroup.Last();
                        //    lastGroup.EndNum += everyNum - i + 2;
                        //}
                        var lastGroup = insTaskGroup.Last();
                        lastGroup.EndNum = (int)aishp.ShpCount;
                        break;  // 最后一组处理完毕，退出循环
                    }

                    // 计算每组的起始和结束数字
                    int beginNum = i == 1 ? 1 : (i - 1) * 1000 + 1;
                    int endNum = beginNum == 1 ? 1000 : beginNum + 999;

                    insTaskGroup.Add(new InsTaskgroup
                    {
                        Id = Guid.NewGuid().ToString(),
                        GroupName = chineseGroupName,
                        Sort = i,
                        BeginNum = beginNum,
                        EndNum = endNum,
                        TaskId = insTaskInfo.Id,
                        IsComplate = false,
                        CreateTime = DateTime.Now,
                    });

                    lastGroupRemaining -= everyNum;  // 更新剩余的任务数
                }
                //添加前后时相
                List<InsTasktif> insTasktifList = new List<InsTasktif>();
                foreach (var item in req.PreviousPhase)
                {
                    insTasktifList.Add(new InsTasktif
                    {
                        TaskId = insTaskInfo.Id,
                        TifId = item,
                        TifType = 0
                    }); ;

                }
                foreach (var item in req.LaterPhase)
                {
                    insTasktifList.Add(new InsTasktif
                    {
                        TaskId = insTaskInfo.Id,
                        TifId = item,
                        TifType = 1
                    }); ;

                }
                // 插入任务和任务组以及前后时相
                await db.InsTask.InsertAsync(insTaskInfo);
                await db.InsTaskgroup.InsertRangeAsync(insTaskGroup);
                await db.InsTasktif.InsertRangeAsync(insTasktifList);
                // 提交事务
                if (db.Commit())
                {
                    var content = new
                    {
                        queryid = insTaskInfo.Id,
                        message = "有新创建的任务"
                    };
                    var contents = Json.ToJson(content);
                    try
                    {
                        await _immsgApp.SendMsgAll("InsTask", contents, insTaskInfo.Id);
                        return new Response<string>
                        {
                            Result = "添加成功",
                            Message = "添加成功"
                        };
                    }
                    catch
                    {
                        return new Response<string>
                        {
                            Result = "添加成功",
                            Message = "数据存储成功，推送失败"
                        };
                    }
                }
                else
                {
                    throw new Exception("添加失败");
                }
            }
        }

        /// <summary>
        /// 任务列表
        /// </summary>
        /// <returns></returns>
        public async Task<Response<PageInfo<List<InsTaskForAdminResp>>>> GteTaskListForAdmin(string taskName, int page, int limit)
        {
            using (var db = base.UnitWork.CreateContext())
            {
                RefAsync<int> totalCount = 0;
                var tsakList = await db.InsTask.AsQueryable()
                    .LeftJoin<InsAishp>((a, b) => a.ShpId == b.Id)
                    .WhereIF(!string.IsNullOrEmpty(taskName), r => r.TaskName.Contains(taskName))
                    .Select((a, b) => new InsTaskForAdminResp()
                    {
                        Id = a.Id.SelectAll(),
                        ShpCount = b.ShpCount,
                        ReceiveShpCount = SqlFunc.Subqueryable<InsTaskgroup>().Where(r => r.TaskId == a.Id && !string.IsNullOrEmpty(r.ReciveUserId)).Sum(r =>
                            (r.EndNum - r.BeginNum + 1)
                         ),
                        NoReceiveShpCount = SqlFunc.Subqueryable<InsTaskgroup>().Where(r => r.TaskId == a.Id && string.IsNullOrEmpty(r.ReciveUserId)).Sum(r =>
                           (r.EndNum - r.BeginNum + 1)),
                    }).OrderByDescending((a)=>a.CreateTime).ToPageListAsync(page, limit, totalCount);

                return new Response<PageInfo<List<InsTaskForAdminResp>>>
                {
                    Result = new PageInfo<List<InsTaskForAdminResp>>
                    {
                        Items = tsakList,
                        Total = totalCount
                    }
                };

            }
        }
        // 定义一个方法来将数字转为中文大写数字
        string ConvertToChineseNumber(int num)
        {
            // 中文数字映射
            string[] chineseNumbers = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };

            if (num < 1) return string.Empty;

            if (num < 10)
            {
                return chineseNumbers[num];  // 1到9直接映射
            }

            string result = string.Empty;

            // 处理十位及以上的数字
            int tens = num / 10;  // 十位
            int ones = num % 10;  // 个位

            if (tens > 1)
            {
                result += chineseNumbers[tens];  // 处理十位数大于1的情况
            }

            if (tens >= 1)  // 如果十位是1，应该只显示"十"而不是"一十"
            {
                result += "十";
            }

            // 个位数字处理
            if (ones > 0)
            {
                result += chineseNumbers[ones];  // 个位不为零，正常显示
            }

            // 特殊处理：如果是20、30、40等，个位是零，不需要显示“零”
            if (ones == 0 && tens > 1)
            {
                result = result.TrimEnd('零');  // 移除尾部的"零"
            }

            return result;
        }
        /// <summary>
        /// 删除任务
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<Response<string>> DeleteTask(string id)
        {
            using (var db = base.UnitWork.CreateContext())
            {
                var taskInfo = await db.InsTask.GetFirstAsync(r => r.Id == id);
                //判断是否存在或者是否已被领取
                if (taskInfo == null || taskInfo.State != 0)
                    throw new Exception("任务已被领取，无法删除");

                //删除任务表，任务分组表，任务前后时相表
                await db.InsTask.DeleteAsync(taskInfo);
                await db.InsTaskgroup.DeleteAsync(r => r.TaskId == id);
                await db.InsTasktif.DeleteAsync(r => r.TaskId == id);
                // 提交事务
                if (db.Commit())
                {
                    return new Response<string>
                    {
                        Result = "删除成功",
                        Message = "删除成功"
                    };
                }
                else
                {
                    throw new Exception("删除失败");
                }
            }
        }
        /// <summary>
        /// 修改任务
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<Response<string>> EditTask(InsTaskReq req)
        {
            using (var db = base.UnitWork.CreateContext())
            {
                var insTaskInfo = await db.InsTask.GetFirstAsync(r => r.Id == req.Id);
                //判断是否存在或者是否已被领取
                if (insTaskInfo == null || insTaskInfo.State != 0)
                    throw new Exception("任务已被领取，无法修改");
                var user = _auth.GetCurrentUser().User;
                //删除任务分组表，任务前后时相表 
                await db.InsTaskgroup.DeleteAsync(r => r.TaskId == req.Id);
                await db.InsTasktif.DeleteAsync(r => r.TaskId == req.Id);


                // 获取ai解译成果
                var aishp = await db.InsAishp.GetFirstAsync(r => r.Id == req.ShpId);

                insTaskInfo.TaskName = req.TaskName;
                insTaskInfo.Remark = req.Remark;
                insTaskInfo.ShpId = req.ShpId;
                insTaskInfo.UpdateTime = DateTime.Now;
                insTaskInfo.UpdateUser = user == null ? "" : user.Id.ToString();
                insTaskInfo.UpdateUserName = user == null ? "" : user.Name;
                // 拆分图斑数
                int groupNum = (int)Math.Ceiling((double)aishp.ShpCount / 1000);

                List<InsTaskgroup> insTaskGroup = new List<InsTaskgroup>();
                int lastGroupRemaining = (int)aishp.ShpCount;

                for (var i = 1; i <= groupNum; i++)
                {
                    int everyNum = 1000;
                    string chineseGroupName = $"{ConvertToChineseNumber(i)}组";
                    // 如果是最后一组，并且剩余的少于1000，将剩余的任务加到上一组
                    if (i == groupNum && lastGroupRemaining < 1000)
                    {
                        everyNum = lastGroupRemaining;
                        if (i > 1)
                        {
                            // 更新上一组的 EndNum
                            var lastGroup = insTaskGroup.Last();
                            lastGroup.EndNum += everyNum;
                        }
                        break;  // 最后一组处理完毕，退出循环
                    }

                    // 计算每组的起始和结束数字
                    int beginNum = (i - 1) * 1000 + 1;
                    int endNum = beginNum + everyNum - 1;

                    insTaskGroup.Add(new InsTaskgroup
                    {
                        Id = Guid.NewGuid().ToString(),
                        GroupName = chineseGroupName,
                        Sort = i,
                        BeginNum = beginNum,
                        EndNum = endNum,
                        TaskId = insTaskInfo.Id,
                        IsComplate = false,
                        CreateTime = DateTime.Now,
                    });

                    lastGroupRemaining -= everyNum;  // 更新剩余的任务数
                }
                //添加前后时相
                List<InsTasktif> insTasktifList = new List<InsTasktif>();
                foreach (var item in req.PreviousPhase)
                {
                    insTasktifList.Add(new InsTasktif
                    {
                        TaskId = insTaskInfo.Id,
                        TifId = item,
                        TifType = 0
                    }); ;

                }
                foreach (var item in req.LaterPhase)
                {
                    insTasktifList.Add(new InsTasktif
                    {
                        TaskId = insTaskInfo.Id,
                        TifId = item,
                        TifType = 1
                    }); ;

                }
                // 插入任务和任务组以及前后时相
                await db.InsTask.UpdateAsync(insTaskInfo);
                await db.InsTaskgroup.InsertRangeAsync(insTaskGroup);
                await db.InsTasktif.InsertRangeAsync(insTasktifList);
                // 提交事务
                if (db.Commit())
                {
                    return new Response<string>
                    {
                        Result = "修改成功",
                        Message = "修改成功"
                    };
                }
                else
                {
                    throw new Exception("修改失败");
                }
            }
        }
        /// <summary>
        /// 获取单个任务信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<Response<InsTaskReq>> GteTaskById(string id)
        {
            using (var db = base.UnitWork.CreateContext())
            {
                var taskInfo = await db.InsTask.GetFirstAsync(r => r.Id == id);
                //判断是否存在或者是否已被领取
                if (taskInfo == null)
                    throw new Exception("获取数据失败");
                InsTaskReq insTaskReq = new InsTaskReq();
                insTaskReq.Id = taskInfo.Id;
                insTaskReq.TaskName = taskInfo.TaskName;
                insTaskReq.ShpId = taskInfo.ShpId;
                insTaskReq.Remark = taskInfo.Remark;
                insTaskReq.PreviousPhase = db.InsTasktif.AsQueryable().Where(r => r.TaskId == taskInfo.Id && r.TifType == 0).Select(r => r.TifId).ToList();
                insTaskReq.LaterPhase = db.InsTasktif.AsQueryable().Where(r => r.TaskId == taskInfo.Id && r.TifType == 1).Select(r => r.TifId).ToList();
                return new Response<InsTaskReq>
                {
                    Result = insTaskReq,
                    Message = "获取数据成功"
                };

            }
        }
        /// <summary>
        /// 选择AI解译成果
        /// </summary>
        /// <returns></returns>
        public async Task<Response<List<AiShpForTaskResp>>> GteAiShp()
        {
            using (var db = base.UnitWork.CreateContext())
            {
                var aiShp = await db.InsAishp.AsQueryable()
                    .LeftJoin<InsTask>((r, b) => r.Id == b.ShpId)
                    .Where((r, b) => b.ShpId == null)
                    .Select(r => new AiShpForTaskResp()
                    {
                        Id = r.Id,
                        ShpName = r.ShpName
                    }).ToListAsync();

                return new Response<List<AiShpForTaskResp>>
                {
                    Result = aiShp,
                    Message = "获取数据成功"
                };

            }
        }
        /// <summary>
        /// 选择前后时相
        /// </summary>
        /// <returns></returns>
        public async Task<Response<List<AreaGroup>>> GteTif()
        {
            using (var db = base.UnitWork.CreateContext())
            {
                var tif = await db.InsTif.AsQueryable().ToListAsync();
                // 构建树形结构
                var areaGroups = tif
                    .GroupBy(x => x.AreaName) // 按 AreaName 分组
                    .Select(areaGroup => new AreaGroup
                    {
                        AreaName = areaGroup.Key,
                        TifDateGroups = areaGroup
                            .GroupBy(x => x.TifDate) // 按 TifDate 分组
                            .Select(tifDateGroup => new TifDateGroup
                            {
                                TifDate = tifDateGroup.Key.ToString("yyyy-MM-dd"),
                                TifDatas = tifDateGroup.Select(x => new TifData
                                {
                                    Id = x.Id,
                                    TifName = x.TifName,
                                }).ToList()
                            })
                            .ToList()
                    })
                    .ToList();
                return new Response<List<AreaGroup>>
                {
                    Result = areaGroups,
                    Message = "获取数据成功"
                };

            }
        }
    }
}
