using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon;
using Siger.Middlelayer.Common.FieldEnum;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.EsopRepository.Repositories.Interface;
using Siger.Middlelayer.EsopRepository.Request;
using Siger.Middlelayer.EsopRepository.Response;
using Siger.Middlelayer.Repository;
using Siger.ApiCommon.Filters;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Repository.Response;

namespace Siger.ApiEsop.Controllers
{
    public class EsopProcessController : BaseController
    {
        private readonly IEsopProcessRepository _esopProcessRepository;
        private readonly IEsopDocumentSetRepository _documentSetRepository;
        private readonly IEsopDocumentCreateRepository _documentCreateRepository;
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerProjectUserRepository _userRepository;

        public EsopProcessController(IEsopProcessRepository esopProcessRepository, IEsopDocumentSetRepository documentSetRepository,
            IEsopDocumentCreateRepository documentCreateRepository, IUnitOfWork unitOfWork ,ISigerProjectUserRepository userRepository)
        {
            _esopProcessRepository = esopProcessRepository;
            _documentSetRepository = documentSetRepository;
            _documentCreateRepository = documentCreateRepository;
            _unitOfWork = unitOfWork;
            _userRepository = userRepository;
        }

        [HttpGet]
        public IActionResult GetProcessPagedList(int page = 1, int pagesize = 10)
        {
            var data = _esopProcessRepository.GetPagedList(ProjectId, page, pagesize);

            return new PagedObjectResult(data.Data,data.Total, page, pagesize);
        }

        [HttpPost]
        public IActionResult AddProcess([FromBody]RequestAddProcess request)
        {
            if (request.groups == null || !request.groups.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            var isExist = _esopProcessRepository.Get(q => q.name == request.name && q.project_id == ProjectId && q.status==(int)RowState.Valid);
            if (isExist != null)
            {
                throw new BadRequestException(RequestEnum.NameHasExist);
            }

            if (_esopProcessRepository.AddProcess(request, UserId, ProjectId))
            {
                return new ObjectResult(CommonEnum.Succefull);
            }

            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetProcessItem(int id)
        {
            var entity = _esopProcessRepository.Get(id);
            if (entity == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var response = new ResponseGetEsopProcessItem
            {
                name = entity.name,
                description = entity.description,
                section_id = entity.section_id,
            };
            var sets = _esopProcessRepository.GetEsopProcessSets(id);
            if (sets.Any())
            {
                foreach (var processSet in sets)
                {
                    response.groups.Add(new ApprovalUserGroup
                    {
                        approval_usertype = processSet.approval_usertype,
                        approval_usergroupid = processSet.approval_usergroupid,
                        approval_type = processSet.approval_type,
                        step_number = processSet.step_number
                    });
                }
            }

            return new ObjectResult(response);
        }

        [HttpPost]
        public IActionResult UpdateProcess([FromBody]RequestUpdateProcess request)
        {
            var entity = _esopProcessRepository.Get(request.id);
            if (entity == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var isExist = _esopProcessRepository.Get(q => q.name == request.name && q.project_id == ProjectId && q.id != request.id && q.status == (int)RowState.Valid);
            if (isExist != null)
            {
                throw new BadRequestException(RequestEnum.NameHasExist);
            }
            var types = _documentSetRepository.GetList(q => q.process_id == entity.id && q.project_id == ProjectId && q.status == (int)RowState.Valid)
                .Select(m => m.id).ToList();
            if (types.Any())
            {
                var documents = _documentCreateRepository.Get(q => types.Contains(q.type_id) && q.project_id == ProjectId && q.status == (int)RowState.Valid && q.approval_status==DocumentApprovalStatus.InProcess);
                if (documents != null)
                {
                    throw new BadRequestException(CommonEnum.UpdateFaild);
                }
            }
            entity.name = request.name;
            entity.description = request.description;
            entity.section_id = request.section_id;
            _esopProcessRepository.Update(entity);
            if (_unitOfWork.Commit() < 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }

            _esopProcessRepository.UpdateEsopProcessSets(entity.id, request.groups);
            return new ObjectResult(CommonEnum.Succefull);
        }

        [HttpPost]
        public IActionResult DeleteProcess(int id)
        {
            var entity = _esopProcessRepository.Get(id);
            if (entity == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var types = _documentSetRepository.GetList(q => q.process_id == entity.id && q.project_id == ProjectId && q.status == (int) RowState.Valid)
                .Select(m => m.id).ToList();
            if (types.Any())
            {
                throw new BadRequestException(RequestEnum.CannotDelete);
                //var documents = _documentCreateRepository.Get(q => types.Contains(q.type_id) && q.project_id == ProjectId && q.status == (int) RowState.Valid);
                //if (documents != null)
                //{
                //    throw new BadRequestException(RequestEnum.CannotDelete);
                //}
            }
            entity.status = (int) RowState.Invalid;
            _esopProcessRepository.Update(entity);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult UpdateProcessStatus(int id, int status)
        {
            var entity = _esopProcessRepository.Get(id);
            if (entity == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            entity.isvalid = status;
            _esopProcessRepository.Update(entity);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetAllProcess()
        {
            var process = _esopProcessRepository.GetList(q => q.project_id == ProjectId && q.status == (int) RowState.Valid && q.isvalid == 1)
                    .Select(m => new
                    {
                        m.id,
                        title = m.name
                    })
                .ToList();

            return new ObjectResult(process);
        }

        /// <summary>
        /// 获取审批流程
        /// </summary>
        /// <param name="type_id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetProcessFlow(int type_id)
        {
            var type = _documentSetRepository.Get(type_id);
            if (type == null || type.status != (int) RowState.Valid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var flows = _esopProcessRepository.GetProcessFlows(type.process_id);

            return new ObjectResult(flows);
        }

        /// <summary>
        /// 获取审批流程
        /// </summary>
        /// <param name="document_id"></param>
        /// <param name="process_id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetProcessApprovalHistory(int document_id, int process_id)
        {
            var flows = _esopProcessRepository.GetResponseApprovalHistories(document_id, process_id);

            return new ObjectResult(flows);
        }
        /// <summary>
        /// 根据流程ID/step_number获取当前层用户
        /// </summary>
        /// <param name="processId"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        [NoTokenValidateFilter]
        [HttpGet]
        public IActionResult GetMidsByLevel(int processId, int level)
        {
            var ret = new List<int>();
            var detail = _esopProcessRepository.GetEsopProcessSets(processId).FirstOrDefault(f => f.status != 0 && f.step_number == level);
            if (detail==null)
            {
                return new ObjectResult(ret);
            }
            var temp = detail.approval_usergroupid.Split(',', System.StringSplitOptions.RemoveEmptyEntries).ToList();
            if (detail.approval_usertype == 2)
            {
                temp.ForEach(item => { ret.Add(item.ToInt()); });
            }
            else if (detail.approval_usertype == 1)
            {
                temp.ForEach(item => {
                    ret.AddRange(_userRepository.GetList(f => f.usergroupid == item && f.status != 0).Select(s => s.mid).ToList());
                    });
            }
            return new ObjectResult(ret.Distinct());
        }
        /// <summary>
        /// 更具用户MID获取其所有的processId
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        [NoTokenValidateFilter]
        [HttpGet]
        public IActionResult GetProcessidsByMid(int mid)
        {
            var ret = new List<ResultEsopObject>();
            var usergroupid = _userRepository.Get(f => f.mid == mid && f.status != 0)?.usergroupid ?? "0";
            ret.AddRange(_esopProcessRepository.GetAllEsopProcessSets().Where(f => f.approval_usertype == 1 && f.ids.Contains(usergroupid)).Select(s=>new ResultEsopObject { mid=new List<string> { mid.ToStr()},processid=s.process_id,step=s.step_number }).ToList());
            ret.AddRange(_esopProcessRepository.GetAllEsopProcessSets().Where(f => f.approval_usertype == 2 && f.ids.Contains(mid.ToStr())).Select(s => new ResultEsopObject { mid = s.ids, processid = s.process_id, step = s.step_number }).ToList());
            return new ObjectResult(ret.Distinct());
        }
    }
}