using Hotline.KnowledgeBase;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Settings;
using Hotline.Settings.Hotspots;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.Knowledge;
using Hotline.Share.Enums.KnowledgeBase;
using Hotline.Users;
using MapsterMapper;
using SqlSugar;
using XF.Domain.Authentications;
using XF.Domain.Dependency;
using XF.Domain.Repository;

namespace Hotline.Application.Knowledge
{
	public class KnowApplication : IKnowApplication, IScopeDependency
	{
		private readonly IKnowledgeRepository _knowledgeRepository;
		private readonly IRepository<KnowledgeApply> _knowledgeApplyRepository;
		private readonly ISessionContext _sessionContext;
		private readonly IMapper _mapper;

		/// <summary>
		/// 
		/// </summary>
		/// <param name="knowledgeRepository"></param>
		/// <param name="knowledgeApplyRepository"></param>
		/// <param name="sessionContext"></param>
		/// <param name="knowledgeDomainService"></param>
		/// <param name="mapper"></param>
		public KnowApplication(IKnowledgeRepository knowledgeRepository, IRepository<KnowledgeApply> knowledgeApplyRepository, ISessionContext sessionContext, IMapper mapper)
		{
			_knowledgeRepository = knowledgeRepository;
			_knowledgeApplyRepository = knowledgeApplyRepository;
			_sessionContext = sessionContext;
			_mapper = mapper;
		}

		/// <summary>
		/// 知识库查询
		/// </summary>
		/// <param name="pagedDto"></param>
		/// <returns></returns>
		public async Task<PagedDto<KnowledgeDataDto>> GetKnowList(KnowPagedListDto pagedDto)
		{
			RefAsync<int> total = 0;
			var temp = await _knowledgeRepository
			   .Queryable()
			   .InnerJoin<User>((o, cus) => o.CreatorId == cus.Id)
			   .InnerJoin<SystemOrganize>((o, cus, sys) => o.CreatorOrgId == sys.Id)
			   .LeftJoin<Hotspot>((o, cus, sys, hst) => o.HotspotId == hst.Id)
			   .Where((o, cus, sys, hst) => o.IsDeleted == false && o.Status != EKnowledgeStatus.Revert && o.Status != EKnowledgeStatus.Drafts)
			   //关键词查询标题、创建人、创建部门
			   .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), (o, cus, sys,  hst) => o.Title.Contains(pagedDto.Keyword!) || cus.Name.Contains(pagedDto.Keyword!) || sys.Name.Contains(pagedDto.Keyword!))
			   //分类
			   //.WhereIF(!string.IsNullOrEmpty(pagedDto.KnowledgeTypeId), (o, cus, sys,  hst) => SqlFunc.JsonListObjectAny(o.KnowledgeType,"Key", pagedDto.KnowledgeTypeId))
			   .WhereIF(!string.IsNullOrEmpty(pagedDto.KnowledgeTypeId), (o, cus, sys, hst) => o.KnowledgeType.Any(t=>t.KnowledgeTypeId == pagedDto.KnowledgeTypeId))
			   //热点
			   .WhereIF(!string.IsNullOrEmpty(pagedDto.HotspotId), (o, cus, sys,  hst) => o.HotspotId == pagedDto.HotspotId)
			   //部门
			   .WhereIF(!string.IsNullOrEmpty(pagedDto.CreateOrgId), (o, cus, sys,  hst) => o.CreatorOrgId == pagedDto.CreateOrgId)
			  //状态
			  // .WhereIF(pagedDto.Status.HasValue, (o, cus, sys, kn, hst) => o.Status == pagedDto.Status)
			  //创建时间
			  //.WhereIF(pagedDto.CreationStartTime.HasValue, (o, cus, sys, kn, hst) => o.CreationTime >= pagedDto.CreationStartTime)
			  //.WhereIF(pagedDto.CreationEndTime.HasValue, (o, cus, sys, kn, hst) => o.CreationTime <= pagedDto.CreationEndTime)
			  // //上架时间
			  // .WhereIF(pagedDto.StartOnShelfTime.HasValue, (o, cus, sys, kn, hst) => o.OnShelfTime >= pagedDto.StartOnShelfTime)
			  //.WhereIF(pagedDto.EndOnShelfTime.HasValue, (o, cus, sys, kn, hst) => o.OnShelfTime <= pagedDto.EndOnShelfTime)
			  // //下架时间
			  // .WhereIF(pagedDto.StartOffShelfTime.HasValue, (o, cus, sys, kn, hst) => o.OffShelfTime >= pagedDto.StartOffShelfTime)
			  //.WhereIF(pagedDto.EndOffShelfTime.HasValue, (o, cus, sys, kn, hst) => o.OffShelfTime <= pagedDto.EndOffShelfTime)
			   //重新构建数据
			   .Select((o, cus, sys,  hst) => new
			   {
				   index = SqlFunc.RowNumber($"{o.Version} desc ", $"{o.Code}"),
				   CreationName = cus.Name,
				   CreationBMName = sys.Name,
				   HotspotName = hst.HotSpotFullName,
				   o.Id,
				   o.Code,
				   o.Title,
				   o.Version,
				   //o.KnowledgeType,
				   o.KnowledgeType,
				   o.IsDeleted,
				   o.HotspotId,
				   o.OnShelfTime,
				   o.CreationTime,
				   o.PageView,
				   o.Status,
				   o.OffShelfTime,
				   o.LastModificationTime,
				   o.WorkflowId,
				   o.ExpiredTime,
				   CreatorOrgId = o.CreatorOrgId,

			   })
		   //将结果合并成一个表
		   .MergeTable()
		   //取第一条数据
		   .Where(d => d.index == 1)
			.WhereIF(pagedDto.Status.HasValue, o => o.Status == pagedDto.Status)
		   .OrderByDescending(d => d.CreationTime)
		  //转分页数据
		  .ToPageListAsync(pagedDto.PageIndex, pagedDto.PageSize, total);
			//返回数据
			return new PagedDto<KnowledgeDataDto>(total.Value, _mapper.Map<IReadOnlyList<KnowledgeDataDto>>(temp));
		}

		/// <summary>
		/// 知识申请查询
		/// </summary>
		/// <param name="pagedDto"></param>
		/// <param name="cancellationToken"></param>
		/// <returns></returns>
		public async Task<PagedDto<KnowledgeApplyHandlePageDto>> GetApplyList(KnowledgeApplyPagedDto pagedDto, CancellationToken cancellationToken)
		{
			var (total, items) = await _knowledgeApplyRepository
			   .Queryable()
			   .Includes(it => it.User)
			   .Includes(it => it.SystemOrganize)
			   .Where(d => d.CreatorId == _sessionContext.RequiredUserId)
			   .WhereIF(pagedDto.Status.HasValue, d => d.Status == pagedDto.Status)
			   .WhereIF(pagedDto.ApplyType.HasValue, d => d.KnowledgeApplyType == pagedDto.ApplyType)
			   .WhereIF(!string.IsNullOrEmpty(pagedDto.IsOvertime) && pagedDto.IsOvertime == "0", d => d.IsOvertime == true)
			   .WhereIF(!string.IsNullOrEmpty(pagedDto.IsOvertime) && pagedDto.IsOvertime == "1", d => d.IsOvertime == false)
			   .WhereIF(pagedDto.StartTime.HasValue, d => d.CreationTime >= pagedDto.StartTime)
			   .WhereIF(pagedDto.EndTime.HasValue, d => d.CreationTime <= pagedDto.EndTime)
			   .OrderByDescending(p => p.CreationTime)
			   .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, cancellationToken);

			return new PagedDto<KnowledgeApplyHandlePageDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApplyHandlePageDto>>(items));
		}

		/// <summary>
		/// 申请处理查询
		/// </summary>
		/// <param name="pagedDto"></param>
		/// <param name="cancellationToken"></param>
		/// <returns></returns>
		public async Task<PagedDto<KnowledgeApplyHandlePageDto>> GetApplyHandleList(KnowledgeHandlePagedDto pagedDto, CancellationToken cancellationToken)
		{
			var (total, items) = await _knowledgeApplyRepository
				 .Queryable()
				 .Includes(it => it.User)
				 .Includes(it => it.SystemOrganize)
				 .Where(p => p.DepartmentId == _sessionContext.RequiredOrgId)
				 .WhereIF(pagedDto.Status.HasValue, d => d.Status == pagedDto.Status)
				 .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.User.Name.Contains(pagedDto.Keyword!) || d.SystemOrganize.Name.Contains(pagedDto.Keyword!))
				 .WhereIF(pagedDto.ApplyType.HasValue, d => d.KnowledgeApplyType == pagedDto.ApplyType)
				 .WhereIF(!string.IsNullOrEmpty(pagedDto.IsOvertime) && pagedDto.IsOvertime == "0", d => d.IsOvertime == true)
				 .WhereIF(!string.IsNullOrEmpty(pagedDto.IsOvertime) && pagedDto.IsOvertime == "1", d => d.IsOvertime == false)

				 .WhereIF(pagedDto.StartTime.HasValue && pagedDto.Status != EKnowledgeApplyStatus.Failed && pagedDto.Status != EKnowledgeApplyStatus.Succeed, d => d.CreationTime >= pagedDto.StartTime)
				 .WhereIF(pagedDto.EndTime.HasValue && pagedDto.Status != EKnowledgeApplyStatus.Failed && pagedDto.Status != EKnowledgeApplyStatus.Succeed, d => d.CreationTime <= pagedDto.EndTime)
				 .WhereIF(pagedDto.StartTime.HasValue && pagedDto.Status == EKnowledgeApplyStatus.Failed, d => d.ReturnTime >= pagedDto.StartTime)
				 .WhereIF(pagedDto.EndTime.HasValue && pagedDto.Status == EKnowledgeApplyStatus.Failed, d => d.ReturnTime <= pagedDto.EndTime)
				  .WhereIF(pagedDto.StartTime.HasValue && pagedDto.Status == EKnowledgeApplyStatus.Succeed, d => d.HandleTime >= pagedDto.StartTime)
				 .WhereIF(pagedDto.EndTime.HasValue && pagedDto.Status == EKnowledgeApplyStatus.Succeed, d => d.HandleTime <= pagedDto.EndTime)

				 .OrderByDescending(p => p.CreationTime)
				 .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, cancellationToken);

			return new PagedDto<KnowledgeApplyHandlePageDto>(total, _mapper.Map<IReadOnlyList<KnowledgeApplyHandlePageDto>>(items));
		}
	}
}
