using AutoMapper;
using EyeSoft.Collections.Generic;
using OASystem.Domain;
using OASystem.Domain.Dtos.Groups;
using OASystem.Domain.Entities.Groups;
using OASystem.Domain.ViewModels.Groups;
using OASystem.Infrastructure.Tools;
using Org.BouncyCastle.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OASystem.Infrastructure.Repositories.Groups
{
    /// <summary>
    /// 团组-出入境费用报价表 仓储
    /// </summary>
    public class EnterExitCostQuoteRepository : BaseRepository<Grp_EnterExitCostQuoteItem, EnterExitCostQuoteView>
    {
        private readonly IMapper _mapper;

        public EnterExitCostQuoteRepository(SqlSugarClient sqlSugar, IMapper mapper) : base(sqlSugar)
        {
            _mapper = mapper;
        }

        /// <summary>
        /// 初始化基础项
        /// </summary>
        /// <param name="removeNl">是否移除换行符</param>
        /// <returns></returns>
        public async Task<List<InitBasicItemView>> InitBasicItemAsync(bool removeNl)
        {
            var origList = await _sqlSugar.Queryable<Sys_SetData>()
                .Where(x => x.IsDel == 0 && x.STid == 105)
                .Select(x => new
                {
                    Id = x.Id,
                    Name = x.Name,
                    Index = x.Remark ?? "-1"
                }).ToListAsync();

            var newList = origList.Select(x => new InitBasicItemView
            {
                Id = x.Id,
                Name = removeNl ? x.Name.Replace("\\r\\n", "") : x.Name,
                Index = int.TryParse(x.Index, out int index) ? index : -1
            })
                .OrderBy(x => x.Index)
                .ToList();
            return newList;
        }

        /// <summary>
        /// 获取报价名称列表
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<JsonView> QuoteNameListAsync(EnterExitCostQuoteNameListDto dto)
        {
            int pageIndex = dto.PageIndex, pageSize = dto.PageSize;
            string name = dto.Name;

            if (pageIndex < 1 || pageSize < 1)
            {
                var noPageList = await _sqlSugar.Queryable<Grp_EnterExitCostQuote>()
                .Where(x => x.IsDel == 0 && !string.IsNullOrEmpty(x.Name))
                .WhereIF(!string.IsNullOrEmpty(name), x => x.Name.Contains(name))
                .Select(x => new EnterExitCostQuoteNameView
                {
                    Id = x.Id,
                    Name = x.Name
                }).ToListAsync();

                return new JsonView
                {
                    Code = StatusCodes.Status200OK,
                    Msg = "获取成功",
                    Count = noPageList.Count,
                    Data = noPageList
                };
            }

            RefAsync<int> total = 0;
            var pageList = await _sqlSugar.Queryable<Grp_EnterExitCostQuote>()
                .Where(x => x.IsDel == 0 && !string.IsNullOrEmpty(x.Name))
                .WhereIF(!string.IsNullOrEmpty(name), x => x.Name.Contains(name))
                .Select(x => new EnterExitCostQuoteNameView
                {
                    Id = x.Id,
                    Name = x.Name
                }).ToPageListAsync(pageIndex, pageSize, total);

            return new JsonView
            {
                Code = StatusCodes.Status200OK,
                Msg = "获取成功",
                Count = total,
                Data = pageList
            };
        }

        /// <summary>
        /// 获取团组名称列表
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<JsonView> GroupNameListAsync(EnterExitCostQuoteGroupNameListDto dto)
        {
            int pageIndex = dto.PageIndex, pageSize = dto.PageSize;
            string name = dto.Name;

            if (pageIndex < 1 || pageSize < 1)
            {
                var noPageList = await _sqlSugar.Queryable<Grp_DelegationInfo>()
                .Where(x => x.IsDel == 0 && !string.IsNullOrEmpty(x.TeamName))
                .WhereIF(!string.IsNullOrEmpty(name), x => x.TeamName.Contains(name))
                .OrderByDescending(x => x.CreateTime)
                .Select(x => new EnterExitCostQuoteGroupNameView
                {
                    Id = x.Id,
                    Name = x.TeamName
                }).ToListAsync();

                return new JsonView
                {
                    Code = StatusCodes.Status200OK,
                    Msg = "获取成功",
                    Count = noPageList.Count,
                    Data = noPageList
                };
            }

            RefAsync<int> total = 0;
            var pageList = await _sqlSugar.Queryable<Grp_DelegationInfo>()
                .Where(x => x.IsDel == 0 && !string.IsNullOrEmpty(x.TeamName))
                .WhereIF(!string.IsNullOrEmpty(name), x => x.TeamName.Contains(name))
                .OrderByDescending(x => x.CreateTime)
                .Select(x => new EnterExitCostQuoteGroupNameView
                {
                    Id = x.Id,
                    Name = x.TeamName
                }).ToPageListAsync(pageIndex, pageSize, total);

            return new JsonView
            {
                Code = StatusCodes.Status200OK,
                Msg = "获取成功",
                Count = total,
                Data = pageList
            };
        }

        /// <summary>
        /// 获取报价详情
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<EnterExitCostQuoteInfoView> InfoAsync(EnterExitCostQuoteInfoDto dto)
        {
            var viewInfo = new EnterExitCostQuoteInfoView();
            viewInfo.Id = dto.Id;
            var basicItems = await InitBasicItemAsync(true);

            if (basicItems.Any())
            {
                viewInfo.FeeItems = basicItems.Select(x => new QuoteItemInfo { ItemId = x.Id, ItemName = x.Name, Index = x.Index }).OrderBy(x => x.Index).ToArray();
            }

            var quoteInfo = await _sqlSugar.Queryable<Grp_EnterExitCostQuote>()
                 .Where(x => x.IsDel == 0 && x.Id == x.Id)
                 .FirstAsync();
            if (quoteInfo != null)
            {
                viewInfo.Name = quoteInfo.Name;
                viewInfo.GroupId = quoteInfo.GroupId;
                viewInfo.Rates = CommonFun.GetCurrencyChinaToList(quoteInfo.CurrencyRemark).ToArray();

                var quoteItems = await _sqlSugar.Queryable<Grp_EnterExitCostQuoteItem>()
                    .Where(x => x.IsDel == 0 && x.QuoteId == quoteInfo.Id)
                    .Select(x => new QuoteSubItemInfo
                    {
                        Id = x.Id,
                        ItemId = x.ItemId,
                        FeeName = x.FeeName,
                        UnitPrice = x.UnitPrice,
                        Quantity = x.Quantity,
                        PplNum = x.PplNum,
                        Currency = x.Currency,
                        TotalAmt = x.TotalAmt,
                        Index = x.Index
                    }).ToListAsync();

                if (quoteItems.Any())
                {
                    viewInfo.FeeItems = viewInfo.FeeItems.Select(x => new QuoteItemInfo { Index = x.Index, QuoteId = dto.Id, ItemId = x.ItemId, ItemName = x.ItemName, Infos = quoteItems.Where(y => y.ItemId == x.ItemId).OrderBy(y => y.Index).ToArray() }).ToArray();
                }
            }

            return viewInfo;
        }

        /// <summary>
        /// Add Or Edit
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<JsonView> OpAsync(EnterExitCostQuoteOpDto dto)
        {
            var jw = new JsonView() { Code = StatusCodes.Status400BadRequest };
            string quoteName = dto.Name;
            int quoteId = dto.Id;
            if (string.IsNullOrEmpty(dto.Name))
            {
                jw.Msg = "报价名称不能为空";
                return jw;
            }

            var quoteInfo = new Grp_EnterExitCostQuote
            {
                Id = quoteId,
                Name = quoteName,
                GroupId = dto.GroupId,
                CurrencyRemark = CommonFun.GetCurrencyChinaToString(dto.Rates.ToList()),
                CreateUserId = dto.CurrUserId
            };
            var quoteItemInfos = new List<Grp_EnterExitCostQuoteItem>();
            if (dto.FeeItems.Any())
            {
                foreach (var item in dto.FeeItems)
                {
                    if (item.Infos.Any())
                    {
                        quoteItemInfos.AddRange(item.Infos.Select(x => new Grp_EnterExitCostQuoteItem
                        {
                            Id = x.Id,
                            QuoteId = quoteId,
                            ItemId = x.ItemId,
                            Index = x.Index,
                            FeeName = x.FeeName,
                            UnitPrice = x.UnitPrice,
                            Currency = x.Currency,
                            Quantity = x.Quantity,
                            PplNum = x.PplNum,
                            TotalAmt = x.TotalAmt,
                            Remark = x.Remark,
                            CreateUserId = dto.CurrUserId
                        }));
                    }
                }
            }

            var isNull = await _sqlSugar.Queryable<Grp_EnterExitCostQuote>().FirstAsync(x => x.IsDel == 0 && x.Name.Equals(quoteName)) == null ? true : false;

            _sqlSugar.BeginTran();

            if (isNull) //新增
            {
                quoteId = await _sqlSugar.Insertable(quoteInfo).ExecuteReturnIdentityAsync();
                if (quoteId < 1)
                {
                    jw.Msg = "新增失败!";
                    _sqlSugar.RollbackTran();
                    return jw;
                }

                quoteItemInfos.ForEach(x => x.QuoteId = quoteId);
                var quoteItemIds = await _sqlSugar.Insertable(quoteItemInfos).ExecuteReturnIdentityAsync();
                if (quoteItemIds < 1)
                {
                    jw.Msg = "新增失败";
                    _sqlSugar.RollbackTran();
                    return jw;
                }
                jw.Msg = "新增成功!";
            }
            else if (!isNull) //编辑
            {
                var quoteUpd = await _sqlSugar.Updateable(quoteInfo).IgnoreColumns(x => new { x.CreateUserId, x.CreateTime, x.IsDel }).ExecuteCommandAsync();
                if (quoteUpd < 1)
                {
                    jw.Msg = "编辑失败!";
                    _sqlSugar.RollbackTran();
                    return jw;
                }

                var addItems = quoteItemInfos.Where(x => x.Id < 1).ToList();
                var updItems = quoteItemInfos.Where(x => x.Id > 0).ToList();
                if (addItems.Any())
                {
                    var addItem = await _sqlSugar.Insertable(addItems).ExecuteCommandAsync();
                    if (addItem < 1)
                    {
                        jw.Msg = "编辑失败!";
                        _sqlSugar.RollbackTran();
                        return jw;
                    }
                }

                if (updItems.Any())
                {
                    var updItem = await _sqlSugar.Updateable(updItems).IgnoreColumns(x => new { x.CreateUserId, x.CreateTime, x.IsDel }).ExecuteCommandAsync();
                    if (updItem < 1)
                    {
                        jw.Msg = "编辑失败!";
                        _sqlSugar.RollbackTran();
                        return jw;
                    }
                }
                jw.Msg = "编辑成功!";
            }

            _sqlSugar.CommitTran();
            jw.Code = StatusCodes.Status200OK;
            jw.Data = quoteId;
            return jw;
        }

        /// <summary>
        /// ItemDel
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<JsonView> ItemDelAsync(EnterExitCostQuoteItemDelDto dto)
        {
            var jw = new JsonView() { Code = StatusCodes.Status400BadRequest };
            int currUserId = dto.CurrUserId,
                id = dto.Id;

            if (currUserId < 1)
            {
                jw.Msg = MsgTips.UserId;
                return jw;
            }
            if (id < 1)
            {
                jw.Msg = MsgTips.Id;
                return jw;
            }
            var info = await _sqlSugar.Queryable<Grp_EnterExitCostQuoteItem>().FirstAsync(x => x.IsDel == 0 && x.Id == id);
            if (info == null)
            {
                jw.Msg = $"操作成功!";
                jw.Code = StatusCodes.Status200OK;
                return jw;
            }
            var itemInfos = await _sqlSugar.Queryable<Grp_EnterExitCostQuoteItem>().Where(x => x.IsDel == 0 && x.QuoteId == info.QuoteId && x.ItemId == info.ItemId).ToListAsync();

            _sqlSugar.BeginTran();

            var delInfo = new Grp_EnterExitCostQuoteItem { DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), DeleteUserId = currUserId, IsDel = 1 };
            var del = await _sqlSugar.Updateable(delInfo)
                .UpdateColumns(x => new { x.DeleteTime, x.DeleteUserId, x.IsDel })
                .Where(x => x.Id == id)
                .ExecuteCommandAsync();
            if (del < 1)
            {
                jw.Msg = $"删除失败!";
                _sqlSugar.RollbackTran();
                return jw;
            }

            if (itemInfos.Any())
            {
                // 更新剩余项的索引
                var itemsToUpdate = itemInfos.Where(i => i.Index > itemInfos.First(i => i.Id == id).Index).ToList();

                foreach (var item in itemsToUpdate)
                {
                    item.Index -= 1;
                }

                await _sqlSugar.Updateable(itemsToUpdate).ExecuteCommandAsync();
            }
            _sqlSugar.CommitTran();
            jw.Msg = "操作成功!";
            jw.Code = StatusCodes.Status200OK;

            return jw;
        }
    }
}