using Hotline.Application.Knowledge;
using Hotline.KnowledgeBase;
using Hotline.Settings;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.Knowledge;
using Hotline.Share.Enums.KnowledgeBase;
using Hotline.Users;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using XF.Domain.Authentications;
using XF.Domain.Exceptions;
using XF.Domain.Repository;
using XF.Utility.EnumExtensions;

namespace Hotline.Api.Controllers
{
    /// <summary>
    /// 
    /// </summary>
    public class KnowledgeApplyController : BaseController
    {
        #region 注入
        private readonly IRepositoryWorkflow<Knowledge> _knowledgeRepository;
        private readonly IRepository<KnowledgeApply> _knowledgeApplyRepository;
        private readonly ISessionContext _sessionContext;
        private readonly IMapper _mapper;
        private readonly IKnowApplication _knowApplication;
        private readonly IRepository<User> _userRepository;
        private readonly ISystemOrganizeRepository _systemOrganizeRepository;
        private readonly IKnowledgeDomainService _knowledgeDomainService;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="knowledgeRepository"></param>
        /// <param name="knowledgeApplyRepository"></param>
        /// <param name="sessionContext"></param>
        /// <param name="mapper"></param>
        /// <param name="knowApplication"></param>
        /// <param name="userRepository"></param>
        /// <param name="systemOrganizeRepository"></param>
        /// <param name="knowledgeDomainService"></param>
        public KnowledgeApplyController(IRepositoryWorkflow<Knowledge> knowledgeRepository,
            IRepository<KnowledgeApply> knowledgeApplyRepository,
            ISessionContext sessionContext
            , IMapper mapper,
            IKnowApplication knowApplication,
            IRepository<User> userRepository,
            ISystemOrganizeRepository systemOrganizeRepository,
            IKnowledgeDomainService knowledgeDomainService)
        {
            _knowledgeRepository = knowledgeRepository;
            _knowledgeApplyRepository = knowledgeApplyRepository;
            _sessionContext = sessionContext;
            _mapper = mapper;
            _knowApplication = knowApplication;
            _userRepository = userRepository;
            _systemOrganizeRepository = systemOrganizeRepository;
            _knowledgeDomainService = knowledgeDomainService;
        }
        #endregion

        #region 知识申请基础

        /// <summary>
        /// 知识申请-发起申请
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task<string> AddApply([FromBody] KnowledgeApplyDto dto)
        {
            var ka = _mapper.Map<KnowledgeApply>(dto);
            ka.Status = EKnowledgeApplyStatus.Handling;
            return await _knowledgeApplyRepository.AddAsync(ka, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 知识申请-修改申请
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPut("update")]
        public async Task UpdateApply([FromBody] UpdateKnowledgeApplyDto dto)
        {
            var ka = _mapper.Map<KnowledgeApply>(dto);
            ka.Status = EKnowledgeApplyStatus.Handling;
            await _knowledgeApplyRepository.UpdateAsync(ka, HttpContext.RequestAborted);
        }

        /// <summary>
        ///知识申请-信息办理
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPut("handle")]
        public async Task HandleApply([FromBody] KnowledgeApplyHandleDto dto)
        {
            //查询申请信息
            var handle = await _knowledgeApplyRepository.GetAsync(dto.Id, HttpContext.RequestAborted);

            if (handle is null || handle.Status != EKnowledgeApplyStatus.Handling)
                throw UserFriendlyException.SameMessage("办理失败");
            if (string.IsNullOrEmpty(dto.Code))
            {
                var know = await _knowledgeRepository.GetAsync(dto.KnowledgeId, HttpContext.RequestAborted);
                dto.Code = know?.Code;
            }
            handle.Status = EKnowledgeApplyStatus.Succeed;
            handle.HandleTime = DateTime.Now;
            handle.KnowledgeId = dto.KnowledgeId;
            handle.Code = dto.Code;
            handle.Opinion = dto.Opinion;
            handle.Processor = _sessionContext.UserName;
            handle.ProcessorId = _sessionContext.RequiredUserId;
            //修改办理信息
            await _knowledgeApplyRepository.UpdateAsync(handle, HttpContext.RequestAborted);
        }

        /// <summary>
        ///知识申请- 撤销操作
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpPut("apply-handle/{Id}")]
        public async Task RevokeApply(string Id)
        {
            var handle = await _knowledgeApplyRepository.GetAsync(Id, HttpContext.RequestAborted);
            if (handle is null)
                throw UserFriendlyException.SameMessage("申请信息撤销失败");
            if (handle.Status != EKnowledgeApplyStatus.Handling)
                throw UserFriendlyException.SameMessage("只能撤销办理中的申请");
            handle.Status = EKnowledgeApplyStatus.Revert;
            handle.RevokeTime = DateTime.Now;
            await _knowledgeApplyRepository.UpdateAsync(handle, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 知识申请-退回操作
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPut("return")]
        public async Task ReturnApply([FromBody] KnowledgeApplyReturnDto dto)
        {
            //查询申请信息
            var handle = await _knowledgeApplyRepository.GetAsync(dto.Id, HttpContext.RequestAborted);
            if (handle is null)
                throw UserFriendlyException.SameMessage("退回失败");
            if (handle.Status != EKnowledgeApplyStatus.Handling)
                throw UserFriendlyException.SameMessage("只能退回办理中的申请");
            if (string.IsNullOrEmpty(dto.Opinion))
                throw UserFriendlyException.SameMessage("退回原因不能为空");
            handle.Status = EKnowledgeApplyStatus.Failed;
            handle.ReturnTime = DateTime.Now;
            handle.HandleTime = DateTime.Now;
            handle.Opinion = dto.Opinion;
            await _knowledgeApplyRepository.UpdateAsync(handle, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 删除申请
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpDelete("remove")]
        public async Task RemoveApply(string Id)
        {
            var handle = await _knowledgeApplyRepository.GetAsync(Id, HttpContext.RequestAborted);
            if (handle is null)
                throw UserFriendlyException.SameMessage("申请不存在");
            if (handle.Status != EKnowledgeApplyStatus.Revert && handle.Status != EKnowledgeApplyStatus.Failed)
                throw UserFriendlyException.SameMessage("只能删除已退回或者撤回的知识申请");
            await _knowledgeApplyRepository.RemoveAsync(handle, false, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 知识申请-查询详情
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpGet("info/{Id}")]
        public async Task<DataKnowledgeApplyDto> GetApply(string Id)
        {
            var handle = await _knowledgeApplyRepository.GetAsync(Id, HttpContext.RequestAborted);
            if (handle is null)
                throw UserFriendlyException.SameMessage("申请信息查询失败");
            DataKnowledgeApplyDto dataKnowledgeApplyDto = new();
            _mapper.Map(handle, dataKnowledgeApplyDto);

            var user = await _userRepository.GetAsync(handle.CreatorId, HttpContext.RequestAborted);
            if (user != null)
                dataKnowledgeApplyDto.CreationName = user.Name;

            var organize = await _systemOrganizeRepository.GetAsync(handle.CreatorOrgId, HttpContext.RequestAborted);
            if (organize != null)
                dataKnowledgeApplyDto.CreationBMName = organize.Name;

            //审批中，更新审批查询最新的审批通过数据
            if (handle.Status == EKnowledgeApplyStatus.Handling && handle.KnowledgeApplyType == EApplyType.Update)
            {
                //查询当前数据的Code
                var know = await _knowledgeDomainService.KnowledgeInfo(handle.KnowledgeId, HttpContext.RequestAborted);
                if (know != null)
                {
                    //根据Code查询最新数据
                    var knowledge = await _knowledgeRepository
                    .Queryable()
                    .Where(p => p.Code == know.Code && (p.Status == EKnowledgeStatus.OnShelf || p.Status == EKnowledgeStatus.OffShelf))
                    .OrderByDescending(p => p.Version)
                    .Take(1)
                    .FirstAsync();
                    if (knowledge != null)
                    {
                        dataKnowledgeApplyDto.KBID = knowledge.Id;
                        dataKnowledgeApplyDto.KBTitle = knowledge.Title;
                        dataKnowledgeApplyDto.KnowledgeId = knowledge.Id;
                    }
                }
            }//审批通过的查询对应版本的数据
            else if (handle.Status == EKnowledgeApplyStatus.Succeed)
            {
                //这里查询对应的版本
                var knowledge = await _knowledgeDomainService.KnowledgeInfo(handle.KnowledgeId, HttpContext.RequestAborted);
                if (knowledge != null)
                {
                    dataKnowledgeApplyDto.KBID = knowledge.Id;
                    dataKnowledgeApplyDto.KBTitle = knowledge.Title;
                }
            }

            return dataKnowledgeApplyDto;
        }

        #endregion

        #region 我的知识申请
        /// <summary>
        /// 知识申请页面枚举值
        /// </summary>
        /// <returns></returns>
        [HttpGet("apply-base-data")]
        public async Task<object> ApplyBaseData()
        {
            return new
            {
                EKnowledgeApplyStatus = EnumExts.GetDescriptions<EKnowledgeApplyStatus>(),
                EKnowledgeApplyType = EnumExts.GetDescriptions<EApplyType>()
            };
        }

        /// <summary>
        /// 我的知识申请--全部
        /// </summary>
        /// <returns></returns>
        [HttpGet()]
        public async Task<PagedDto<KnowledgeApplyHandlePageDto>> GetApplyList([FromQuery] KnowledgeApplyPagedDto dto)
        {
            return await _knowApplication.GetApplyList(dto, HttpContext.RequestAborted);
        }

        #endregion

        #region 知识申请处理查询
        /// <summary>
        /// 申请处理查询
        /// </summary>
        /// <returns></returns>
        [HttpGet("handlelist")]
        public async Task<PagedDto<KnowledgeApplyHandlePageDto>> AllHandle([FromQuery] KnowledgeHandlePagedDto dto)
        {
            return await _knowApplication.GetApplyHandleList(dto, HttpContext.RequestAborted);
        }

        #endregion


    }
}
