using AutoMapper;
using OASystem.Domain.Dtos.Groups;
using OASystem.Domain.Dtos.System;
using OASystem.Domain.Entities.Groups;

namespace OASystem.Infrastructure.Repositories.System
{
    /// <summary>
    /// 审核流程 仓储
    /// </summary>
    public class ApprovalProcessRepository : BaseRepository<Sys_AuditFlow, Sys_AuditFlow>
    {
        private readonly IMapper _mapper;
        public ApprovalProcessRepository(SqlSugarClient sqlSugar, IMapper mapper) : base(sqlSugar)
        {
            _mapper = mapper;
        }

        /// <summary>
        /// 创建审核流程模板
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<bool> CreateAuditTemplateAsync(ApprovalProcessDto dto)
        {
            var currUserId = dto.CurrUserId;
            var auditTemp = new Sys_AuditTemplate()
            {
                TemplateName = dto.TemplateName,
                TemplateCode = dto.TemplateCode,
                BusinessType = dto.BusinessType,
                Status = dto.Status,
            };

            _sqlSugar.BeginTran();

            var tempId = await _sqlSugar.Insertable(auditTemp).ExecuteReturnIdentityAsync();
            if (tempId < 1)
            {
                _sqlSugar.RollbackTran();
                return false;
            }

            foreach (var item in dto.TempNodes)
            {
                var auditTempNodes = _mapper.Map<Sys_AuditTemplateNode>(item);
                auditTempNodes.TemplateId = tempId;
                auditTempNodes.CreateUserId = currUserId;

                var nodeId = await _sqlSugar.Insertable(auditTempNodes).ExecuteReturnIdentityAsync();
                if (nodeId < 1)
                {
                    _sqlSugar.RollbackTran();
                    return false;
                }

                var nodeUsers = _mapper.Map<List<Sys_AuditTemplateNodeUser>>(item.NodeUsers);
                nodeUsers.ForEach(x =>
                {
                    x.NodeId = nodeId;
                    x.CreateUserId = currUserId;
                });
                if (nodeUsers.Any())
                {
                    var nodeUsersStatus = await _sqlSugar.Insertable(nodeUsers).ExecuteCommandAsync();
                    if (nodeUsersStatus < 1)
                    {
                        _sqlSugar.RollbackTran();
                        return false;
                    }
                }
            }
            _sqlSugar.CommitTran();
            return true;
        }

        /// <summary>
        /// 获取审核流程模板
        /// </summary>
        /// <param name="auditTempId"></param>
        /// <returns></returns>
        public async Task<ApprovalProcessView> GetTemplateByBusinessTypeAsync(int auditTempId)
        {
            var tempInfo = new ApprovalProcessView();

            var auditTempInfo = await _sqlSugar.Queryable<Sys_AuditTemplate>()
                .FirstAsync(x => x.Id == auditTempId && x.IsDel == 0);
            if (auditTempInfo == null) return tempInfo;
            tempInfo.Id = auditTempInfo.Id;
            tempInfo.TemplateName = auditTempInfo.TemplateName;
            tempInfo.BusinessType = auditTempInfo.BusinessType;
            tempInfo.Status = auditTempInfo.Status;

            var nodes = await _sqlSugar.Queryable<Sys_AuditTemplateNode>()
                .Where(x => x.TemplateId == auditTempId && x.IsDel == 0)
                .Select(x => new AuditTemplateNodeView()
                {
                    Id = x.Id,
                    TemplateId = x.TemplateId,
                    NodeName = x.NodeName,
                    NodeOrder = x.NodeOrder,
                    ApproveType = x.ApproveType,
                    IsRequired = x.IsRequired
                })
                .OrderBy(x => x.NodeOrder)
                .ToListAsync();
            foreach (var node in nodes)
            {
                node.NodeUsers = await _sqlSugar.Queryable<Sys_AuditTemplateNodeUser>()
                    .Where(x => x.NodeId == node.Id && x.IsDel == 0)
                    .Select(x => new AuditTemplateNodeUserView()
                    {
                        Id = x.Id,
                        NodeId = x.NodeId,
                        UserId = x.UserId,
                        UserName = x.UserName
                    })
                    .ToListAsync();
            }
            tempInfo.TempNodes = nodes;
            return tempInfo;
        }

        /// <summary>
        /// 获取审核流程
        /// </summary>
        /// <param name="auditTempId"></param>
        /// <returns></returns>
        public async Task<Sys_AuditFlow> GetFlowByBusinessAsync(int businessId, int businessType)
        {
            return await _sqlSugar.Queryable<Sys_AuditFlow>()
                .FirstAsync(x => x.IsDel == 0 && x.BusinessId == businessId && x.BusinessType == businessType);
        }
        
        /// <summary>
        /// 获取审核模板节点
        /// </summary>
        /// <param name="auditTempId"></param>
        /// <returns></returns>
        public async Task<List<Sys_AuditTemplateNode>> GetTemplateNodesAsync(int templateId)
        {
            return await _sqlSugar.Queryable<Sys_AuditTemplateNode>()
                .Where(x => x.TemplateId == templateId)
                .OrderBy(x => x.NodeOrder)
                .ToListAsync();
        }

        /// <summary>
        /// 获取审核模板节点用户
        /// </summary>
        /// <param name="nodeId"></param>
        /// <returns></returns>
        public async Task<List<Sys_AuditTemplateNodeUser>> GetTemplateNodeUsersAsync(int nodeId)
        {
            return await _sqlSugar.Queryable<Sys_AuditTemplateNodeUser>()
                .Where(x => x.NodeId == nodeId)
                .ToListAsync();
        }
    }
}