using AutoMapper;
using EyeSoft.Collections.Generic;
using Newtonsoft.Json;
using OASystem.Domain;
using OASystem.Domain.Dtos.Groups;
using OASystem.Domain.Entities.Groups;
using OASystem.Domain.ViewModels.Groups;
using Org.BouncyCastle.Ocsp;
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 GroupOrderPreInfoRepository : BaseRepository<Grp_OrderPreInfo, OrderPreInfoView>
    {
        private readonly IMapper _mapper;
        private readonly DelegationInfoRepository _groupInfoRep;
        public GroupOrderPreInfoRepository(SqlSugarClient sqlSugar, IMapper mapper, DelegationInfoRepository groupInfoRep) : base(sqlSugar)
        {
            _mapper = mapper;
            _groupInfoRep = groupInfoRep;
        }

        /// <summary>
        /// 获取基础信息
        /// </summary>
        /// <param name="tempId"></param>
        /// <returns></returns>
        public async Task<JsonView> DataInit(int userId)
        {
            var jw = new JsonView() { Code = StatusCodes.Status200OK, Msg = "操作成功!" };

            var groupNames = await _groupInfoRep.GetGroupNameList(new Domain.Dtos.Groups.GroupNameDto() { PortType = 1 });
            var tempDatas = await _sqlSugar.Queryable<Sys_SetData>().Where(x => x.IsDel == 0 && x.STid == 109).Select(x => new { x.Id, x.Name }).ToListAsync();
            var names = await _sqlSugar.Queryable<Grp_OrderPreInfo>().Where(x => x.IsDel == 0 && x.CreateUserId == userId).OrderByDescending(x => x.Id).Select(x => new { x.Id, x.Name }).ToListAsync();
            jw.Data = new
            {
                groupNames = groupNames,
                tempDatas = tempDatas,
                names = names
            };
            return jw;
        }


        /// <summary>
        /// 获取模板信息
        /// </summary>
        /// <param name="tempId"></param>
        /// <returns></returns>
        public async Task<GrpOrderPreItemView[]> TempInfoById(int tempId = 1404)
        {
            var tempInfos = await _sqlSugar.Queryable<Sys_FormTemp, Sys_SetData, Sys_SetData>((ft, sd1, sd2) =>
                new JoinQueryInfos(
                    JoinType.Left, ft.FieldNameId == sd1.Id,
                    JoinType.Left, ft.FieldTypeId == sd2.Id
                    ))
                .Where((ft, sd1, sd2) => ft.IsDel == 0 && ft.TempId == tempId)
                .OrderBy((ft, sd1, sd2) => ft.Index)
                .Select((ft, sd1, sd2) => new GrpOrderPreItemView()
                {
                    FieldTempId = ft.Id,
                    FieldName = sd1.Name,
                    OriginVal = "-",
                   // FieldTypeName = !string.IsNullOrEmpty(ft.Remark) ? sd2.Name +"-"+ ft.Remark : sd2.Name,
                    FieldTypeName =  sd2.Name,
                    IsRequired = ft.IsRequired,
                    IsRemark = ft.IsRemark,
                    Index = ft.Index
                })
                .ToArrayAsync();
            return tempInfos;
        }

        /// <summary>
        /// 获取团组下单前信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<JsonView> InfoAsync(int id, int tempId = 1404)
        {
            var jw = new JsonView() { Code = StatusCodes.Status200OK, Msg = "操作成功!" };
            var view = new GrpOrderPreInfoView();
            var info = await _sqlSugar.Queryable<Grp_OrderPreInfo>().FirstAsync(x => x.IsDel == 0 && x.Id == id);

            var temps = await TempInfoById(tempId);
            if (info == null)
            {
                //view.TempId = tempId;
                view.Items = temps;
                jw.Data = view;
                return jw;
            }
            view.Id = id;
            view.Name = info.Name;
            view.GroupId = info.GroupId;
            var items = await _sqlSugar.Queryable<Sys_FormTemp, Grp_OrderPreItem, Sys_SetData, Sys_SetData>((ft, opi, sd1, sd2) =>
                new JoinQueryInfos(
                    JoinType.Inner, ft.Id == opi.FormTempId,
                    JoinType.Left, ft.FieldNameId == sd1.Id,
                    JoinType.Left, ft.FieldTypeId == sd2.Id
                    ))
                .Where((ft, opi, sd1, sd2) => ft.IsDel == 0 && opi.IsDel == 0 && opi.ParentId == id && ft.TempId == tempId)
                .OrderBy((ft, opi, sd1, sd2) => ft.Index)
                .Select((ft, opi, sd1, sd2) => new GrpOrderPreItemView()
                {
                    Id = opi.Id,
                    ParentId = opi.ParentId,
                    FieldTempId = ft.Id,
                    FieldName = sd1.Name,
                    //FieldTypeName = !string.IsNullOrEmpty(ft.Remark) ? sd2.Name + "-" + ft.Remark : sd2.Name,
                    FieldTypeName = sd2.Name,
                    OriginVal = opi.Value,
                    Remark = opi.Remark,
                    IsRequired = ft.IsRequired,
                    IsRemark = ft.IsRemark,
                    Index = ft.Index
                })
                .ToArrayAsync();

            if (!items.Any()) view.Items = temps;
            else
            {
                if (items.Length != temps.Length)
                {
                    foreach (var item in temps)
                    {
                        if (items.FirstOrDefault(x => x.FieldName.Equals(item.FieldName)) == null)
                        {
                            var arr = new GrpOrderPreItemView[] { item };
                            view.Items.AddRange(arr);
                        }
                    }
                }
                else view.Items = items;

                view.Items = view.Items.Length > 0 ? view.Items.OrderBy(x => x.Index).ToArray() : view.Items;
            }

            jw.Data = view;
            return jw;
        }

        /// <summary>
        /// 获取团组下单前信息 op
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<JsonView> OpAsync(GroupOrderPreInfoOpDto dto)
        {
            var jw = new JsonView() { Code = StatusCodes.Status400BadRequest, Msg = "操作成功!" };
            int currUserId = dto.CurrUserId;
            if (currUserId < 1)
            {
                jw.Msg = MsgTips.UserId;
                return jw;
            }
            if (string.IsNullOrEmpty(dto.Name))
            {
                jw.Msg = $"名称不能为空!";
                return jw;
            }

            var info = new Grp_OrderPreInfo()
            {
                Id = dto.Id,
                Name = dto.Name,
                GroupId = dto.GroupId,
                CreateUserId = currUserId
            };
            var items = new List<Grp_OrderPreItem>();
            foreach (var item in dto.Items)
            {
                var val = "";
                if (item.NewValue is Array obj)
                {
                    val =  JsonConvert.SerializeObject( (string[])item.NewValue);
                }
                else val = item.NewValue.ToString();

                items.Add(new Grp_OrderPreItem()
                {
                    Id = item.Id,
                    ParentId = item.ParentId,
                    FormTempId = item.FieldTempId,
                    Value = val,
                    CreateUserId = currUserId,
                    Remark = item.Remark
                });
            }

            var addItems = items.Where(x => x.Id <= 0).ToArray();
            var updItems = items.Where(x => x.Id > 0).ToArray();

            _sqlSugar.BeginTran();
            if (dto.Id > 0) //修改
            {
                var infoUpd = await _sqlSugar.Updateable(info).UpdateColumns(x => new { x.Name, x.GroupId }).ExecuteCommandAsync();
                if (infoUpd < 1)
                {
                    _sqlSugar.RollbackTran();
                    jw.Msg = $"修改失败!";
                    return jw;
                }

                if (addItems.Any()) await _sqlSugar.Insertable(addItems).ExecuteCommandAsync();

                if (updItems.Any()) await _sqlSugar.Updateable(updItems).UpdateColumns(x => new { x.Value, x.Remark }).ExecuteCommandAsync();
            }
            else if (dto.Id <= 0) //新增
            {
                var isNul = await _sqlSugar.Queryable<Grp_OrderPreInfo>().FirstAsync(x => x.IsDel == 0 && x.Name.Equals(dto.Name));
                if (isNul != null)
                {
                    _sqlSugar.RollbackTran();
                    jw.Msg = $"名称重复!";
                    return jw;
                }

                var addId = await _sqlSugar.Insertable(info).ExecuteReturnIdentityAsync();
                if (addId < 1)
                {
                    _sqlSugar.RollbackTran();
                    jw.Msg = $"新增失败!";
                    return jw;
                }

                foreach (var item in items) item.ParentId = addId;

                if (items.Any()) await _sqlSugar.Insertable(items).ExecuteCommandAsync();
            }

            _sqlSugar.CommitTran();
            jw.Msg = $"操作成功!";
            jw.Code = StatusCodes.Status200OK;
            return jw;
        }
    }
}