using System.Collections.Generic;
using System.Threading.Tasks;
using Datory;
using GxPress.Common.Tools;
using GxPress.Entity.WorkProcessDto;
using ProcessNodeDto = GxPress.Entity.WorkProcessDto.ProcessNodeDto;

namespace GxPress.Service.Implement
{
    public partial class ProcessService
    {
        public async Task<List<ProcessNodeDto>> GetAllAsync(int processId)
        {
            var process=new List<ProcessNodeDto>();
            var processNodes = await _processNodeRepository.GetAllAsync(processId);
            if (processNodes != null)
            {
                foreach (var node in processNodes)
                {
                    var processNode = new ProcessNodeDto
                    {
                        Id = node.Id,
                        Name = node.Name,
                        Type = node.Type,
                        ParentId = node.ParentId,
                        ReadOnlyFields = StringUtils.StringCollectionToIntList(node.ReadOnlyFields),
                        HiddenFields = StringUtils.StringCollectionToIntList(node.HiddenFields),
                        AllowMeeting = node.AllowMeeting,
                        ApprovalType = node.ApprovalType,
                        DefaultApprovalUserId = node.DefaultApprovalUserId,
                        DefaultApprovalUserName = await _userRepository.GetNameAsync(node.DefaultApprovalUserId),
                        CaseLevel = node.CaseLevel
                    };
                    process.Add(processNode);
                }
                return process;
            }
            return new List<ProcessNodeDto>();
        }
            public async Task<ProcessDto> GetAsync(int processId)
            {
                var process = await _processRepository.GetAsync(processId);
                var result = _mapper.Map<ProcessDto>(process);

                //2.���淢������
                result.RequestLimits = new List<RequestLimit>();

                var requestLimits = await _processRequestLimitRepository.GetListAsync(processId);
                foreach (var limit in requestLimits)
                {
                    result.RequestLimits.Add(new RequestLimit
                    {
                        DepartmentId = limit.DepartmentId,
                        DepartmentName = await _departmentRepository.GetNameAsync(limit.DepartmentId),
                        RoleId = limit.RoleId,
                        RoleName = await _roleRepository.GetNameAsync(limit.RoleId),
                        UserId = limit.UserId,
                        UserName = await _userRepository.GetNameAsync(limit.UserId)
                    });
                }

                //3.�����������
                var formFields = await _processFieldRepository.GetListAsync(processId);
                if (formFields != null)
                {
                    result.FormFields = new List<FormField>();
                    foreach (var field in formFields)
                    {
                        result.FormFields.Add(new FormField
                        {
                            Id = field.Id,
                            Label = field.Label,
                            Placeholder = field.Placeholder,
                            Required = field.Required,
                            Sort = field.Sort,
                            Type = field.Type,
                            Unit = field.Unit,
                            Options = StringUtils.StringCollectionToStringList(field.Options)
                        });
                    }
                }

                //4.����ڵ㶨��
                result.ProcessNodes = await GetNodesAsync(processId, 0);

                return result;
            }

            public async Task<List<ProcessNodeDto>> GetNodesAsync(int processId, int parentId)
            {
                var nodes = new List<ProcessNodeDto>();

                var processNodes = await _processNodeRepository.GetListAsync(processId, parentId);
                //4.����ڵ㶨��
                if (processNodes != null)
                {
                    foreach (var node in processNodes)
                    {
                        var processNode = new ProcessNodeDto
                        {
                            Id = node.Id,
                            Name = node.Name,
                            Type = node.Type,
                            ParentId = node.ParentId,
                            ReadOnlyFields = StringUtils.StringCollectionToIntList(node.ReadOnlyFields),
                            HiddenFields = StringUtils.StringCollectionToIntList(node.HiddenFields),
                            AllowMeeting = node.AllowMeeting,
                            ApprovalType = node.ApprovalType,
                            DefaultApprovalUserId = node.DefaultApprovalUserId,
                            DefaultApprovalUserName = await _userRepository.GetNameAsync(node.DefaultApprovalUserId),
                            CaseLevel = node.CaseLevel
                        };

                        var carbonCopies = await _ruleCarbonCopyRepository.GetListAsync(node.Id);
                        if (carbonCopies != null)
                        {
                            processNode.CarbonCopies = new List<CarbonCopy>();
                            foreach (var cc in carbonCopies)
                            {
                                processNode.CarbonCopies.Add(new CarbonCopy
                                {
                                    DepartmentId = cc.DepartmentId,
                                    DepartmentName = await _departmentRepository.GetNameAsync(cc.DepartmentId),
                                    RoleId = cc.RoleId,
                                    RoleName = await _roleRepository.GetNameAsync(cc.RoleId),
                                    UserId = cc.UserId,
                                    UserName = await _userRepository.GetNameAsync(cc.UserId)
                                });
                            }
                        }

                        var approverChecks = await _ruleApproverCheckRepository.GetListAsync(node.Id);
                        if (approverChecks != null)
                        {
                            processNode.ApproverChecks = new List<ApproverCheck>();
                            foreach (var ac in approverChecks)
                            {
                                processNode.ApproverChecks.Add(new ApproverCheck
                                {
                                    DepartmentId = ac.DepartmentId,
                                    DepartmentName = await _departmentRepository.GetNameAsync(ac.DepartmentId),
                                    RoleId = ac.RoleId,
                                    RoleName = await _roleRepository.GetNameAsync(ac.RoleId),
                                    UserId = ac.UserId,
                                    UserName = await _userRepository.GetNameAsync(ac.UserId)
                                });
                            }
                        }

                        var conditions = await _ruleConditionRepository.GetListAsync(node.Id);
                        if (conditions != null)
                        {
                            processNode.Conditions = new List<Condition>();
                            foreach (var condition in conditions)
                            {
                                processNode.Conditions.Add(new Condition
                                {
                                    FieldId = condition.FieldId,
                                    Operator = condition.Operator,
                                    StringValue = condition.StringValue,
                                    StringValues = StringUtils.StringCollectionToStringList(condition.StringValues),
                                    IntValue = condition.IntValue,
                                    Sort = condition.Sort
                                });
                            }
                        }

                        //foreach (var condition in node.ConditionNodes)
                        //{
                        //    await _conditionRuleRepository.InsertAsync(new ConditionRule
                        //    {
                        //        NodeId = nodeId,
                        //        MinValue = condition.MinValue,
                        //        EqualValue = condition.EqualValue,
                        //        MaxValue = condition.MaxValue,
                        //        Sort = condition.Sort
                        //    });
                        //}

                        processNode.Children = await GetNodesAsync(processId, node.Id);

                        nodes.Add(processNode);
                    }
                }

                return nodes;
            }
        }
    }