using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon;
using Siger.ApiCommon.Exceptions;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.FieldEnum;
using Siger.Middlelayer.EsopRepository.Entities;
using Siger.Middlelayer.EsopRepository.Repositories.Interface;
using Siger.Middlelayer.EsopRepository.Request;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Repositories.Interface;

namespace Siger.ApiEsop.Controllers
{
    public class EsopDocumentBindingController : BaseController
    {

        private readonly IEsopDocumentBindingRepository _documentBindingRepository;
        private readonly IEsopDocumentCreateRepository _documentRepository;
        private readonly IEsopDocumentSetRepository _documentSetRepository;
        private readonly ISigerProjectLevelSectionMachineRepository _levelMachineRepository;
        private readonly ISigerProjectUserRepository _userRepository;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly IUnitOfWork _unitOfWork;

        public EsopDocumentBindingController(IEsopDocumentBindingRepository documentBindingRepository,
            IEsopDocumentCreateRepository documentRepository, ISigerProjectLevelSectionMachineRepository machineRepository,
            IEsopDocumentSetRepository documentSetRepository, ISigerProjectUserRepository userRepository,
            ISigerProjectMachineRepository sigerMachineRepository, IUnitOfWork unitOfWork)
        {
            _documentBindingRepository = documentBindingRepository;
            _documentRepository = documentRepository;
            _documentSetRepository = documentSetRepository;
            _levelMachineRepository = machineRepository;
            _userRepository = userRepository;
            _machineRepository = sigerMachineRepository;
            _unitOfWork = unitOfWork;
        }

        [HttpGet]
        public IActionResult GetDocumentBindingList(int product_id, int level_id, int page = 1, int pagesize = 10)
        {
            var data = _documentBindingRepository.GetDocumentBindingList(product_id, level_id, page, pagesize, ProjectId);

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

        [HttpGet]
        public IActionResult GetUnBindDocuments(int route_id, int machine_id)
        {
            var hasBindIds = _documentBindingRepository.GetList(q =>q.project_id == ProjectId && q.status == (int) RowState.Valid )
                                           .Select(m => m.document_id).ToList();

            var unBindDocumentIds = _documentRepository.GetList(q => !hasBindIds.Contains(q.id) && q.project_id == ProjectId
                                           && q.status == (int) RowState.Valid &&
                                           q.approval_status == DocumentApprovalStatus.ApprovalPass).Select(m => m.id).ToList();

            var docs = _documentRepository.GetDocuments(unBindDocumentIds);
            return new ObjectResult(docs);
        }

        /// <summary>
        /// 一键下发
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UpdateDocumentStatus([FromBody] RequestUpdateDocumentStatus request)
        {
            if (!request.documents.Any())
            {
                throw new BadRequestException(RequestEnum.NoDocumentsForOperate);
            }

            foreach (var update in request.documents)
            {
                var hasBinds = _documentBindingRepository.GetList(q => q.project_id == ProjectId && q.route_id == update.route_id
                                                                                                 && q.machine_id == update.machine_id 
                                                                                                 && q.status == (int) RowState.Valid).ToList();
                if (hasBinds.Any())
                {
                    //先删除，再重新下发
                    foreach (var detail in hasBinds)
                    {
                        _documentBindingRepository.Delete(detail);
                    }

                    if (_unitOfWork.Commit() < 0)
                    {
                        throw new BadRequestException(CommonEnum.Fail);
                    }
                }
            }

            //添加新的绑定
            var result = _documentBindingRepository.AddBindDetail(request, ProjectId, UserId);
            if (!result)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }

            return new ObjectResult(CommonEnum.Succefull);
        }

        /// <summary>
        /// 一键回收
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult RecoverDocuments(int product_id, int level_id)
        {
            var bindIds = _documentBindingRepository.GetBindIds(product_id, level_id, ProjectId).ToList();
            if (!bindIds.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var hasBinds = _documentBindingRepository.GetList(q => bindIds.Contains(q.id)).ToList();
            foreach (var detail in hasBinds)
            {
                detail.document_status = DocumentSignStatus.HasRecover;
                detail.recover_mid = UserId;
                detail.recover_time = DateTime.Now;
                _documentBindingRepository.Update(detail);
            }
            if (_unitOfWork.Commit() < 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        /// <summary>
        /// 按设备查询文档下发情况
        /// </summary>
        /// <param name="section_id"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetMachinePagedBindings(int section_id, int page, int pagesize)
        {
            var machineIds = _machineRepository.GetNCLevelSectionMachineIds(section_id, ProjectId);

            var data = _documentBindingRepository.GetMachinePagedBinding(ProjectId, machineIds, page, pagesize);

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

        /// <summary>
        /// 按设备和文档下发
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult RequestUpdateOneDocument([FromBody] RequestUpdateOneDocument request)
        {
            //必须选择设备
            var machine = _levelMachineRepository.GetNCSectionMachine(ProjectId, request.section_id);
            if (machine == null)
            {
                throw new BadRequestException(RequestEnum.MachineNotFound);
            }

            if (request.document_id == 0)
            {
                throw new BadRequestException(CommonEnum.RequestInValid);
            }
            //是否已上传
            var bind = _documentBindingRepository.Get(q =>
                q.machine_id == machine.id && q.document_id == request.document_id
                                           && q.project_id == ProjectId && q.status == (int) RowState.Valid
                                           && q.document_status != DocumentSignStatus.Saved &&
                                           q.document_status != DocumentSignStatus.HasRecover);
            if (bind != null)
            {
                throw new BadRequestException(RequestEnum.CannotBindingAgain);
            }
            var document = _documentRepository.Get(q => q.id == request.document_id && q.project_id == ProjectId);
            if (document == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            //没有审核的文档不能下发
            if (document.approval_status != DocumentApprovalStatus.ApprovalPass)
            {
                throw new BadRequestException(RequestEnum.CannotBindThisDocument);
            }

            var type = _documentSetRepository.Get(q => q.id == document.type_id);
            if (type == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var status = DocumentSignStatus.Signed;
            if (type.sign_usergroup_id > 0)
            {
                status = DocumentSignStatus.Binding;
            }
            var detail = new siger_project_esop_document_binding
            {
                create_time = DateTime.Now,
                creator_mid = UserId,
                document_id = request.document_id,
                project_id = ProjectId,
                remark = request.remark,
                route_id = 0,
                machine_id = machine.id,
                document_status = status
            };
            _documentBindingRepository.Insert(detail);

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult RecoverDocument(int id)
        {
            //是否已上传
            var bind = _documentBindingRepository.Get(q =>
                q.id == id && q.project_id == ProjectId && q.status == (int)RowState.Valid
                                           && q.document_status != DocumentSignStatus.Saved &&
                                           q.document_status != DocumentSignStatus.HasRecover);
            if (bind == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            bind.document_status = DocumentSignStatus.HasRecover;
            bind.recover_mid = UserId;
            bind.recover_time = DateTime.Now;
            _documentBindingRepository.Update(bind);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 按工艺查询文档下发情况
        /// </summary>
        /// <param name="level_id"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <param name="product_id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetMachineRoutePagedBindings(string starttime, string endtime, int product_id, int level_id,
            int page = 1, int pagesize = 10)
        {
            var data = _documentBindingRepository.GetRouteDocumentBindingList(starttime, endtime, product_id, level_id, ProjectId, page, pagesize);

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

        /// <summary>
        /// 文档签收状态
        /// </summary>
        /// <param name="section_id"></param>
        /// <param name="status"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetDocumentSignPagedList(int section_id, int status, int page = 1, int pagesize = 10)
        {
            //只获取待签收和已签收的
            var machineIds = _machineRepository.GetNCLevelSectionMachineIds(section_id, ProjectId);

            var data = _documentBindingRepository.GetDocumentSignList(machineIds, status, ProjectId, UserId, page, pagesize);

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

        /// <summary>
        /// 文档签收
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SignDocument([FromBody]RequestSignDocument request)
        {
            var bind = _documentBindingRepository.Get(q => q.id == request.id && q.status == (int) RowState.Valid);
            if (bind == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            if (bind.document_status != DocumentSignStatus.Binding)
            {
                throw new BadRequestException(RequestEnum.CannotSignThisDocument);
            }
            
            //只有签收部门的人可以签收
            var user = _userRepository.GetUserInfo(UserId);
            if (user == null)
            {
                throw new BadRequestException(RequestEnum.UserNotFound);
            }

            var document = _documentRepository.Get(q => q.id == bind.document_id && q.status == (int) RowState.Valid);
            if (document == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var set = _documentSetRepository.Get(q => q.id == document.type_id && q.status == (int) RowState.Valid);
            if (set == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            if (set.sign_usergroup_id > 0 && set.sign_usergroup_id != user.usergroupid)
            {
                throw new BadRequestException(RequestEnum.NoAuthoritySign);
            }

            //是否培训
            if (set.need_train == 1)
            {
                if (request.has_train == 0)
                {
                    throw new BadRequestException(RequestEnum.TrainFirst);
                }
            }

            bind.document_status = DocumentSignStatus.Signed;
            bind.has_train = request.has_train;
            bind.train_record = request.train_record;
            bind.sign_mid = UserId;
            bind.sign_time = DateTime.Now;
            _documentBindingRepository.Update(bind);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        
    }
}