//--------------------------------------------------------------------
//     此代码由T4模板自动生成  byzhouhang 20210918
//	   生成时间 2022-01-05 09:17:03 
//     对此文件的更改可能会导致不正确的行为，并且如果重新生成代码，这些更改将会丢失。
//--------------------------------------------------------------------

using Microsoft.AspNetCore.Mvc;

using IRaCIS.Core.Application.Contracts;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;

namespace IRaCIS.Core.Application.Services
{
    /// <summary>
    /// TrialDocumentService
    /// </summary>	
    [ApiExplorerSettings(GroupName = "Trial")]
    public class TrialDocumentService : BaseService, ITrialDocumentService
    {


        private readonly IRepository<TrialDocument> _trialDocumentRepository;
        private readonly IRepository<TrialDocConfirmedUser> _trialDocUserTypeConfirmedUserRepository;
        private readonly IRepository<Trial> _trialRepository;
        private readonly IRepository<SystemDocConfirmedUser> _systemDocConfirmedUserRepository;
        private readonly IRepository<SystemDocument> _systemDocumentRepository;
        private readonly IRepository<TrialCriterionAdditionalAssessmentType> _trialCriterionAdditionalAssessmentTypeRepository;
        private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;


        public TrialDocumentService(IRepository<TrialDocument> trialDocumentRepository,
             IRepository<TrialDocConfirmedUser> trialDocUserTypeConfirmedUserRepository,
                  IRepository<Trial> trialRepository,
            IRepository<SystemDocConfirmedUser> systemDocConfirmedUserRepository,
             IRepository<TrialCriterionAdditionalAssessmentType> trialCriterionAdditionalAssessmentTypeRepository,
            IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository
            , IRepository<SystemDocument> systemDocumentRepository)
        {
            _trialDocumentRepository = trialDocumentRepository;
            this._trialDocUserTypeConfirmedUserRepository = trialDocUserTypeConfirmedUserRepository;
            this._trialRepository = trialRepository;
            this._systemDocConfirmedUserRepository = systemDocConfirmedUserRepository;
            _systemDocumentRepository = systemDocumentRepository;
            _readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
            _trialCriterionAdditionalAssessmentTypeRepository = trialCriterionAdditionalAssessmentTypeRepository;
        }

        /// <summary>
        /// Setting 界面的  项目所有文档列表
        /// </summary>
        /// <param name="queryTrialDocument"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<TrialDocumentView>> GetTrialDocumentList(TrialDocumentQuery queryTrialDocument)
        {

            var trialDocumentQueryable = _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == queryTrialDocument.TrialId)
            .WhereIf(!string.IsNullOrEmpty(queryTrialDocument.Name), t => t.Name.Contains(queryTrialDocument.Name))
            .WhereIf(queryTrialDocument.FileTypeId != null, t => t.FileTypeId == queryTrialDocument.FileTypeId)
            .ProjectTo<TrialDocumentView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken });

            return await trialDocumentQueryable.ToPagedListAsync(queryTrialDocument.PageIndex, queryTrialDocument.PageSize, queryTrialDocument.SortField, queryTrialDocument.Asc);
        }



        /// <summary>
        ///  具体用户看到的 系统文件列表 + 项目类型文档
        /// </summary>
        /// <param name="querySystemDocument"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task< IResponseOutput<PageOutput<UnionDocumentWithConfirmInfoView>>  > GetUserDocumentList(TrialUserDocUnionQuery querySystemDocument)
        {
            #region https://github.com/dotnet/efcore/issues/16243  操作不行
            ////系统文档查询
            //var systemDocumentQueryable = _systemDocumentRepository
            // .WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
            // .WhereIf(!_userInfo.IsAdmin, t => t.IsAbandon == false || (t.IsAbandon == true && t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
            //.ProjectTo<UnionDocumentView>(_mapper.ConfigurationProvider, new { userId = _userInfo.Id, token = _userInfo.UserToken });

            ////项目文档查询
            //var trialDocQueryable = _trialDocumentRepository.Where(t => t.TrialId == querySystemDocument.TrialId)
            //   .WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
            //   .WhereIf(!_userInfo.IsAdmin, t => t.IsAbandon == false || (t.IsAbandon == true && t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
            //   .ProjectTo<UnionDocumentView>(_mapper.ConfigurationProvider, new { userId = _userInfo.Id, token = _userInfo.UserToken });

            //var unionQuery = systemDocumentQueryable.Union(trialDocQueryable);
            //     .WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
            //     .WhereIf(!string.IsNullOrEmpty(querySystemDocument.Type), t => t.Type.Contains(querySystemDocument.Type));
            #endregion

            #region 仅仅文档信息

            ////系统文档查询
            //var systemDocumentQueryable = _systemDocumentRepository
            // .WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
            // .WhereIf(!_userInfo.IsAdmin, t => t.IsAbandon == false || (t.IsAbandon == true && t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
            // .Select(t => new UnionDocumentView()
            // {
            //     Id = t.Id,
            //     IsSystemDoc = true,
            //     CreateTime = t.CreateTime,
            //     FullFilePath = t.Path + "?access_token=" + _userInfo.UserToken,
            //     IsAbandon = t.IsAbandon,
            //     Name = t.Name,
            //     Path = t.Path,
            //     Type = t.Type,
            //     UpdateTime = t.UpdateTime,
            //     SignViewMinimumMinutes = t.SignViewMinimumMinutes,

            // });

            ////项目文档查询
            //var trialDocQueryable = _trialDocumentRepository.Where(t => t.TrialId == querySystemDocument.TrialId)
            //   .WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
            //   .WhereIf(!_userInfo.IsAdmin, t => t.IsAbandon == false || (t.IsAbandon == true && t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))
            //    .Select(t => new UnionDocumentView()
            //    {
            //        Id = t.Id,
            //        IsSystemDoc = false,
            //        CreateTime = t.CreateTime,
            //        FullFilePath = t.Path + "?access_token=" + _userInfo.UserToken,
            //        IsAbandon = t.IsAbandon,
            //        Name = t.Name,
            //        Path = t.Path,
            //        Type = t.Type,
            //        UpdateTime = t.UpdateTime,
            //        SignViewMinimumMinutes = t.SignViewMinimumMinutes,

            //    });

            #endregion

            var trialId = querySystemDocument.TrialId;

            var trialInfo = await (_repository.Where<Trial>(t => t.Id == querySystemDocument.TrialId).Select(t => new { t.TrialFinishedTime,t.TrialStatusStr } ).FirstOrDefaultAsync());

            //系统文档查询
            var systemDocumentQueryable = from needConfirmedUserType in _repository.Where<SystemDocNeedConfirmedUserType>(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId)
                                               //.Where(u => u.UserTypeRole.UserList.SelectMany(cc => cc.UserTrials.Where(t => t.TrialId == querySystemDocument.TrialId)).Any(e => e.Trial.TrialFinishedTime < u.SystemDocument.CreateTime))
                                               .WhereIf(trialInfo.TrialFinishedTime != null, u => u.SystemDocument.CreateTime < trialInfo.TrialFinishedTime)
                                               .WhereIf(!_userInfo.IsAdmin, t => t.SystemDocument.IsDeleted == false || (t.SystemDocument.IsDeleted == true && t.SystemDocument.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))

                                          join trialUser in _repository.Where<TrialUser>(t => t.TrialId == querySystemDocument.TrialId && t.UserId == _userInfo.Id)
                                                                          on needConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId
                                          join confirm in _repository.GetQueryable<SystemDocConfirmedUser>() on new { ConfirmUserId = trialUser.UserId, SystemDocumentId = needConfirmedUserType.SystemDocumentId } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
                                          from confirm in cc.DefaultIfEmpty()
                                          select new UnionDocumentWithConfirmInfoView()
                                          {
                                              IsSystemDoc = true,

                                              Id = needConfirmedUserType.SystemDocument.Id,
                                              CreateTime = needConfirmedUserType.SystemDocument.CreateTime,
                                              IsDeleted = needConfirmedUserType.SystemDocument.IsDeleted,
                                              SignViewMinimumMinutes = needConfirmedUserType.SystemDocument.SignViewMinimumMinutes,
                                              Name = needConfirmedUserType.SystemDocument.Name,
                                              Path = needConfirmedUserType.SystemDocument.Path,
                                              FileTypeId = needConfirmedUserType.SystemDocument.FileTypeId,
                                              FileType = needConfirmedUserType.SystemDocument.FileType.MappedValue,
                                              UpdateTime = needConfirmedUserType.SystemDocument.UpdateTime,

                                              FullFilePath = needConfirmedUserType.SystemDocument.Path ,

                                              ConfirmUserId = confirm.ConfirmUserId,
                                              ConfirmTime = confirm.ConfirmTime,
                                              RealName = trialUser.User.FullName,
                                              UserName = trialUser.User.UserName,
                                              UserTypeId = trialUser.User.UserTypeId,
                                              UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName
                                          };

            //项目文档查询
            var trialDocQueryable = from trialDoc in _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId == querySystemDocument.TrialId)
               .WhereIf(!_userInfo.IsAdmin, t => t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == _userInfo.UserTypeId))
               .WhereIf(!_userInfo.IsAdmin, t => t.IsDeleted == false || (t.IsDeleted == true && t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id)))

                                    join trialUser in _repository.Where<TrialUser>(t => t.TrialId == querySystemDocument.TrialId && t.UserId == _userInfo.Id) on trialDoc.TrialId equals trialUser.TrialId
                                    join confirm in _repository.Where<TrialDocConfirmedUser>(t => t.TrialDocument.TrialId == querySystemDocument.TrialId) on
                                    new { trialUser.UserId, TrialDocumentId = trialDoc.Id } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
                                    from confirm in cc.DefaultIfEmpty()
                                    select new UnionDocumentWithConfirmInfoView()
                                    {
                                        Id = trialDoc.Id,
                                        IsSystemDoc = false,
                                        CreateTime = trialDoc.CreateTime,
                                        FullFilePath = trialDoc.Path ,
                                        IsDeleted = trialDoc.IsDeleted,
                                        Name = trialDoc.Name,
                                        Path = trialDoc.Path,
                                        FileTypeId = trialDoc.FileTypeId,
                                        FileType = trialDoc.FileType.MappedValue,
                                        UpdateTime = trialDoc.UpdateTime,
                                        SignViewMinimumMinutes = trialDoc.SignViewMinimumMinutes,

                                        ConfirmUserId = confirm.ConfirmUserId,
                                        ConfirmTime = confirm.ConfirmTime,
                                        RealName = trialUser.User.FullName,
                                        UserName = trialUser.User.UserName,
                                        UserTypeId = trialUser.User.UserTypeId,
                                        UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName

                                    };


            var unionQuery = systemDocumentQueryable.Union(trialDocQueryable)
                 .WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
                 .WhereIf(querySystemDocument.FileTypeId != null, t => t.FileTypeId == querySystemDocument.FileTypeId)
                 .WhereIf(querySystemDocument.IsSign == true, t => t.ConfirmTime != null)
                 .WhereIf(querySystemDocument.IsSign == false, t => t.ConfirmTime == null);

            var result = await unionQuery.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);

            var needSignTrialDocCount = await _trialDocumentRepository.AsQueryable(true).Where(t => t.TrialId== querySystemDocument.TrialId && t.Trial.TrialStatusStr != StaticData.TrialState.TrialStopped)
                       .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
                       .Where(t => t.IsDeleted == false && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id && t.ConfirmTime!=null) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
                       .CountAsync();


            var needSignSystemDocCount = await _systemDocumentRepository
                      .Where(t => t.IsDeleted == false && !t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id && t.ConfirmTime != null) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
                      .CountAsync();

            var trialTaskConfig = _trialRepository.Where(t => t.Id == querySystemDocument.TrialId).ProjectTo<TrialConfigTabDto>(_mapper.ConfigurationProvider).FirstOrDefault();


            //var trialCriterionAdditionalAssessmentTypeList = _trialCriterionAdditionalAssessmentTypeRepository
            //    .Where(t => t.TrialReadingCriterion.TrialId == trialId && t.IsSelected == true && t.TrialReadingCriterion.IsSigned).Select(t=>new { t.CriterionType,t.AdditionalAssessmentType}).ToList();


            var isManualGenerateTask= _readingQuestionCriterionTrialRepository.Where(t=>t.TrialId==trialId && t.IsSigned && t.IsAutoCreate==false).Any();
            var isAdditionalAssessment = _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsSigned && t.IsAdditionalAssessment == true 
            &&t.TrialCriterionAdditionalAssessmentTypeList.Any(c=>/*c.AdditionalAssessmentType==Domain.Share.Reading.AdditionalAssessmentType.BrainMetastasis &&*/ c.IsSelected==true)).Any();


            var isAllOnlySRReading = _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsSigned).All(t => t.ReadingDivisionEnum == ReadingDivisionEnum.OnlySR);

            return ResponseOutput.Ok<PageOutput<UnionDocumentWithConfirmInfoView>>( result, new {
                NeedSignCount = needSignTrialDocCount + needSignSystemDocCount,
                NeedSignTrialDocCount = needSignTrialDocCount, 
                NeedSignSystemDocCount = needSignSystemDocCount,
                IsAllOnlySRReading= isAllOnlySRReading,
                IsAdditionalAssessment = isAdditionalAssessment && isManualGenerateTask,
                TrialStatusStr = trialInfo.TrialStatusStr,
                TrialConfig= trialTaskConfig });
        }




        /// <summary>
        /// 获取确认列表情况  项目文档+系统文档+具体的人
        /// </summary>
        /// <param name="querySystemDocument"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(PageOutput<UnionDocumentWithConfirmInfoView>,object)> GetDocumentConfirmList(DocumentTrialUnionQuery querySystemDocument)
        {


            #region linq join 方式
            //var trialDocQuery = from trialDocumentNeedConfirmedUserType in _trialDocumentNeedConfirmedUserTypeRepository.Where(t => t.TrialDocument.TrialId == querySystemDocument.TrialId)
            //                    join trialUser in _trialUserRepository.Where(t => t.TrialId == querySystemDocument.TrialId)
            //                                                  .WhereIf(querySystemDocument.UserId != null, t => t.UserId == querySystemDocument.UserId)
            //                    on trialDocumentNeedConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId

            //                    join confirm in _trialDocuserConfrimedRepository.AsQueryable() on trialUser.UserId equals confirm.ConfirmUserId into cc
            //                    from confirm in cc.DefaultIfEmpty()
            //                    select new UnionDocumentConfirmListView()
            //                    {
            //                        Id = trialDocumentNeedConfirmedUserType.TrialDocument.Id,
            //                        CreateTime = trialDocumentNeedConfirmedUserType.TrialDocument.CreateTime,
            //                        IsAbandon = trialDocumentNeedConfirmedUserType.TrialDocument.IsAbandon,
            //                        SignViewMinimumMinutes = trialDocumentNeedConfirmedUserType.TrialDocument.SignViewMinimumMinutes,
            //                        Name = trialDocumentNeedConfirmedUserType.TrialDocument.Name,
            //                        Path = trialDocumentNeedConfirmedUserType.TrialDocument.Path,
            //                        Type = trialDocumentNeedConfirmedUserType.TrialDocument.Type,
            //                        UpdateTime = trialDocumentNeedConfirmedUserType.TrialDocument.UpdateTime,

            //                        UserConfirmInfo = /*confirm == null ? null : */new UnionDocumentUserConfirmView()
            //                        {

            //                            ConfirmUserId = confirm.ConfirmUserId,
            //                            ConfirmTime = confirm.ConfirmTime,
            //                            RealName = trialUser.User.LastName + " / " + trialUser.User.LastName,
            //                            UserName = trialUser.User.UserName,
            //                        },

            //                        FullFilePath = trialDocumentNeedConfirmedUserType.TrialDocument.Path + "?access_token=" + _userInfo.UserToken
            //                    };

            #endregion

            var trialInfo = (await _repository.Where<Trial>(t => t.Id == querySystemDocument.TrialId).Select(t => new { t.TrialFinishedTime, t.TrialStatusStr }).FirstOrDefaultAsync());

            var trialDocQuery = from trialDocumentNeedConfirmedUserType in _repository.Where<TrialDocNeedConfirmedUserType>(t => t.TrialDocument.TrialId == querySystemDocument.TrialId)
                                join trialUser in _repository.Where<TrialUser>(t => t.TrialId == querySystemDocument.TrialId)
                                                                              .WhereIf(querySystemDocument.UserId != null, t => t.UserId == querySystemDocument.UserId)
                                                                              .WhereIf(querySystemDocument.UserTypeId != null, t => t.User.UserTypeId == querySystemDocument.UserTypeId)
                                                on trialDocumentNeedConfirmedUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId

                                join confirm in _repository.Where<TrialDocConfirmedUser>(t => t.TrialDocument.TrialId == querySystemDocument.TrialId) on
                                 new { trialUser.UserId, TrialDocumentId = trialDocumentNeedConfirmedUserType.TrialDocumentId } equals new { UserId = confirm.ConfirmUserId, confirm.TrialDocumentId } into cc
                                from confirm in cc.DefaultIfEmpty()
                                select new UnionDocumentWithConfirmInfoView()
                                {
                                    IsSystemDoc = false,

                                    Id = trialDocumentNeedConfirmedUserType.TrialDocument.Id,
                                    CreateTime = trialDocumentNeedConfirmedUserType.TrialDocument.CreateTime,
                                    IsDeleted = trialDocumentNeedConfirmedUserType.TrialDocument.IsDeleted,
                                    SignViewMinimumMinutes = trialDocumentNeedConfirmedUserType.TrialDocument.SignViewMinimumMinutes,
                                    Name = trialDocumentNeedConfirmedUserType.TrialDocument.Name,
                                    Path = trialDocumentNeedConfirmedUserType.TrialDocument.Path,
                                    FileTypeId = trialDocumentNeedConfirmedUserType.TrialDocument.FileTypeId,
                                    FileType = trialDocumentNeedConfirmedUserType.TrialDocument.FileType.MappedValue,
                                    UpdateTime = trialDocumentNeedConfirmedUserType.TrialDocument.UpdateTime,



                                    ConfirmUserId = confirm.ConfirmUserId,
                                    ConfirmTime = confirm.ConfirmTime,
                                    RealName = trialUser.User.FullName,
                                    UserName = trialUser.User.UserName,
                                    UserTypeId = trialUser.User.UserTypeId,
                                    UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName,

                                    FullFilePath = trialDocumentNeedConfirmedUserType.TrialDocument.Path 
                                };



            var systemDocQuery = from needConfirmEdUserType in _repository.WhereIf<SystemDocNeedConfirmedUserType>(trialInfo.TrialFinishedTime != null, u => u.SystemDocument.CreateTime < trialInfo.TrialFinishedTime)

                                 join trialUser in _repository.Where<TrialUser>(t => t.TrialId == querySystemDocument.TrialId)
                                                                       .WhereIf(querySystemDocument.UserId != null, t => t.UserId == querySystemDocument.UserId)
                                       on needConfirmEdUserType.NeedConfirmUserTypeId equals trialUser.User.UserTypeId
                                 join confirm in _repository.GetQueryable<SystemDocConfirmedUser>() on new { ConfirmUserId = trialUser.UserId, SystemDocumentId = needConfirmEdUserType.SystemDocumentId } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc
                                 from confirm in cc.DefaultIfEmpty()
                                 select new UnionDocumentWithConfirmInfoView()
                                 {
                                     IsSystemDoc = true,

                                     Id = needConfirmEdUserType.SystemDocument.Id,
                                     CreateTime = needConfirmEdUserType.SystemDocument.CreateTime,
                                     IsDeleted = needConfirmEdUserType.SystemDocument.IsDeleted,
                                     SignViewMinimumMinutes = needConfirmEdUserType.SystemDocument.SignViewMinimumMinutes,
                                     Name = needConfirmEdUserType.SystemDocument.Name,
                                     Path = needConfirmEdUserType.SystemDocument.Path,
                                     FileType = needConfirmEdUserType.SystemDocument.FileType.MappedValue,
                                     FileTypeId = needConfirmEdUserType.SystemDocument.FileTypeId,
                                     UpdateTime = needConfirmEdUserType.SystemDocument.UpdateTime,


                                     ConfirmUserId = confirm.ConfirmUserId,
                                     ConfirmTime = confirm.ConfirmTime,
                                     RealName = trialUser.User.FullName,
                                     UserName = trialUser.User.UserName,
                                     UserTypeId = trialUser.User.UserTypeId,
                                     UserTypeShortName = trialUser.User.UserTypeRole.UserTypeShortName,

                                     FullFilePath = needConfirmEdUserType.SystemDocument.Path
                                 };

            var unionQuery = trialDocQuery.Union(systemDocQuery)
                .WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
                .WhereIf(querySystemDocument.FileTypeId != null, t => t.FileTypeId == querySystemDocument.FileTypeId)
                .WhereIf(querySystemDocument.UserTypeId != null, t => t.UserTypeId == querySystemDocument.UserTypeId);

            var result = await unionQuery.ToPagedListAsync(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);

            var needSignTrialDocCount = await _trialDocumentRepository.AsQueryable(true)
                    .Where(t => t.Trial.TrialUserList.Any(t => t.UserId == _userInfo.Id))
                    .Where(t => t.IsDeleted == false && !t.TrialDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
                    .CountAsync();


            var needSignSystemDocCount = await _systemDocumentRepository
                      .Where(t => t.IsDeleted == false && !t.SystemDocConfirmedUserList.Any(t => t.ConfirmUserId == _userInfo.Id) && t.NeedConfirmedUserTypeList.Any(u => u.NeedConfirmUserTypeId == _userInfo.UserTypeId))
                      .CountAsync();


            return (result, new { NeedSignCount = needSignTrialDocCount + needSignSystemDocCount, NeedSignTrialDocCount = needSignTrialDocCount, NeedSignSystemDocCount = needSignSystemDocCount,TrialStatusStr = trialInfo.TrialStatusStr });
        }


        /// <summary>
        /// 项目下面的参与用户下拉
        /// </summary>
        /// <param name="trialId"></param>
        /// <returns></returns>
        [HttpGet("{trialId:guid}")]
        public async Task<List<TrialUserDto>> GetTrialUserSelect(Guid trialId)
        {
            return await _repository.Where<TrialUser>(t => t.TrialId == trialId)
                .Select(t => new TrialUserDto() { UserId = t.UserId, RealName = t.User.FullName, UserName = t.User.UserName })
                   .ToListAsync();
        }


        /// <summary>
        /// 项目+系统的文档类型 下拉
        /// </summary>
        /// <param name="trialId"></param>
        /// <returns></returns>
        [HttpGet("{trialId:guid}")]
        public async Task<IResponseOutput> GetTrialDocAndSystemDocType(Guid trialId)
        {
            var result = await _trialDocumentRepository.Where(t => t.TrialId == trialId).Select(t => new { FileType = _userInfo.IsEn_Us? t.FileType.Value :t.FileType.ValueCN, t.FileTypeId })
                   .Union(_systemDocumentRepository.Select(t => new { FileType = _userInfo.IsEn_Us ? t.FileType.Value : t.FileType.ValueCN, t.FileTypeId }))
                   .ToListAsync();

            return ResponseOutput.Ok(result);
        }

        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt",  "AfterStopCannNotOpt" })]
        //[Authorize(Policy = IRaCISPolicy.PM)]
        public async Task<IResponseOutput> AddOrUpdateTrialDocument(AddOrEditTrialDocument addOrEditTrialDocument)
        {
            if (addOrEditTrialDocument.Id == null)
            {
                var entity = _mapper.Map<TrialDocument>(addOrEditTrialDocument);


                if (await _trialDocumentRepository.AnyAsync(t => t.FileTypeId == addOrEditTrialDocument.FileTypeId && t.Name == addOrEditTrialDocument.Name && t.TrialId == addOrEditTrialDocument.TrialId, true))
                {
                //---该项目中已经存在同类型的同名文件。
                    return ResponseOutput.NotOk(_localizer["TrialD_DuplicateFileInProject"]);
                }

                //entity.Id = NewId.NextGuid();
                await _trialDocumentRepository.AddAsync(entity, true);
                return ResponseOutput.Ok(entity.Id.ToString());
            }
            else
            {
                if (await _trialDocumentRepository.AnyAsync(t => t.FileTypeId == addOrEditTrialDocument.FileTypeId && t.Name == addOrEditTrialDocument.Name && t.Id != addOrEditTrialDocument.Id && t.TrialId == addOrEditTrialDocument.TrialId, true))
                {
                //---该项目中已经存在同类型的同名文件。
                    return ResponseOutput.NotOk(_localizer["TrialD_DuplicateFileInProject"]);
                }

                var document = (await _trialDocumentRepository.Where(t => t.Id == addOrEditTrialDocument.Id, true).Include(t => t.NeedConfirmedUserTypeList).FirstOrDefaultAsync()).IfNullThrowException();



                _mapper.Map(addOrEditTrialDocument, document);

                #region 不区分路径了

                //if (document.FileTypeId != addOrEditTrialDocument.FileTypeId)
                //{


                //    var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).IfNullThrowException().FullName;
                //    var beforeFilePath = Path.Combine(rootPath, document.Path);

                //    document.Path = document.Path.Replace(document.FileTypeId.ToString(), addOrEditTrialDocument.FileTypeId.ToString());

                //    var nowPath = Path.Combine(rootPath, document.Path);

                //    if (File.Exists(beforeFilePath))
                //    {
                //        File.Move(beforeFilePath, nowPath, true);
                //        File.Delete(beforeFilePath);
                //    }

                //}

                #endregion


                var success = await _trialDocumentRepository.SaveChangesAsync();

                return ResponseOutput.Ok(document.Id.ToString());
            }
        }


        /// <summary>
        /// 已签名的文档 不允许删除
        /// </summary>
        /// <param name="trialDocumentId"></param>
        /// <param name="trialId"></param>
        /// <returns></returns>
        [HttpDelete("{trialId:guid}/{trialDocumentId:guid}")]
        //[Authorize(Policy = IRaCISPolicy.PM)]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt",  "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> DeleteTrialDocument(Guid trialDocumentId, Guid trialId)
        {
            if (await _trialDocumentRepository.AsQueryable(true).Where(t => t.Id == trialDocumentId).AnyAsync(t => t.TrialDocConfirmedUserList.Any()))
            {
                //---已有用户阅读该文档，并签名，不允许删除。
                return ResponseOutput.NotOk(_localizer["TrialD_DocumentHasAlready"]);
            }

            var success = await _trialDocumentRepository.BatchDeleteNoTrackingAsync(t => t.Id == trialDocumentId);

            return ResponseOutput.Result(success);
        }


        /// <summary>
        /// 浏览文档说明时调用，记录第一次看的时间
        /// </summary>
        /// <param name="documentId"></param>
        /// <param name="isSystemDoc"></param>
        /// <returns></returns>
        [HttpPut("{trialId:guid}/{documentId:guid}/{isSystemDoc:bool}")]
        [UnitOfWork]
        public async Task<IResponseOutput> SetFirstViewDocumentTime(Guid documentId, bool isSystemDoc)
        {

            var success = false;
            if (isSystemDoc)
            {
                if(!await _systemDocConfirmedUserRepository.AnyAsync(t=>t.SystemDocumentId==documentId && t.ConfirmUserId == _userInfo.Id))
                {
                    await _repository.AddAsync(new SystemDocConfirmedUser() { SystemDocumentId = documentId, ConfirmUserId = _userInfo.Id, SignFirstViewTime = DateTime.Now });

                }

            }
            else
            {

                if (!await _trialDocUserTypeConfirmedUserRepository.AnyAsync(t => t.TrialDocumentId == documentId && t.ConfirmUserId == _userInfo.Id))
                {

                    await _repository.AddAsync(new TrialDocConfirmedUser() { TrialDocumentId = documentId, ConfirmUserId = _userInfo.Id, SignFirstViewTime = DateTime.Now });

                }


            }

            success = await _repository.SaveChangesAsync();

            return ResponseOutput.Ok(success);
        }

        [HttpPut("{documentId:guid}")]
        public async Task<IResponseOutput> SetSystemDocFirstViewTime(Guid documentId)
        {
            if (!await _systemDocConfirmedUserRepository.AnyAsync(t => t.SystemDocumentId == documentId && t.ConfirmUserId == _userInfo.Id))
            {
                await _repository.AddAsync(new SystemDocConfirmedUser() { SystemDocumentId = documentId, ConfirmUserId = _userInfo.Id, SignFirstViewTime = DateTime.Now });

            }

            var success = await _repository.SaveChangesAsync();

            return ResponseOutput.Ok(success);
        }

        [HttpPut("{trialId:guid}/{documentId:guid}")]
        public async Task<IResponseOutput> SetTrialDocFirstViewTime(Guid documentId)
        {
            if (!await _trialDocUserTypeConfirmedUserRepository.AnyAsync(t => t.TrialDocumentId == documentId && t.ConfirmUserId == _userInfo.Id))
            {

                await _repository.AddAsync(new TrialDocConfirmedUser() { TrialDocumentId = documentId, ConfirmUserId = _userInfo.Id, SignFirstViewTime = DateTime.Now });

            }
            var success = await _repository.SaveChangesAsync();

            return ResponseOutput.Ok(success);
        }

        /// <summary>
        /// 用户 签名某个文档   可能是系统的，也可能是项目的
        /// </summary>
        /// <returns></returns>
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> UserConfirm(UserConfirmCommand userConfirmCommand)
        {

            if (userConfirmCommand.isSystemDoc)
            {

                var sysDocConfirm = await  _systemDocConfirmedUserRepository.FirstOrDefaultAsync(t => t.SystemDocumentId == userConfirmCommand.DocumentId && t.ConfirmUserId == _userInfo.Id,true);

                if(sysDocConfirm.ConfirmTime != null)
                {
                //---该文件已经签名
                    return ResponseOutput.NotOk(_localizer["TrialD_FileAlreadySigned"]);
                }

                if (sysDocConfirm.IsDeleted)
                {
                //---文件已废除,签署失败！
                    return ResponseOutput.NotOk(_localizer["TrialD_ObsoleteFile"]);
                }


                sysDocConfirm.ConfirmTime = DateTime.Now;
                sysDocConfirm.SignText = userConfirmCommand.SignText;



                await _systemDocConfirmedUserRepository.SaveChangesAsync();


            }
            else
            {

                var trialDocConfirm = await _trialDocUserTypeConfirmedUserRepository.FirstOrDefaultAsync(t => t.TrialDocumentId == userConfirmCommand.DocumentId && t.ConfirmUserId == _userInfo.Id, true);

                if (trialDocConfirm.ConfirmTime != null)
                {
                //---该文件已经签名
                    return ResponseOutput.NotOk(_localizer["TrialD_FileAlreadySigned"]);
                }

                if (trialDocConfirm.IsDeleted)
                {
                //---文件已废除,签署失败！
                    return ResponseOutput.NotOk(_localizer["TrialD_ObsoleteFile"]);
                }

                trialDocConfirm.ConfirmTime = DateTime.Now;
                trialDocConfirm.SignText = userConfirmCommand.SignText;

                await _trialDocUserTypeConfirmedUserRepository.SaveChangesAsync();

            }


            return ResponseOutput.Ok();
        }


        /// <summary>
        /// 用户 废除某个文档
        /// </summary>
        /// <param name="documentId"></param>
        /// <param name="isSystemDoc"></param>
        /// <returns></returns>
        [HttpPut("{documentId:guid}/{isSystemDoc:bool}")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> UserAbandonDoc(Guid documentId, bool isSystemDoc)
        {
            if (isSystemDoc)
            {
                await _systemDocumentRepository.UpdatePartialFromQueryAsync(documentId, u => new SystemDocument() { IsDeleted = true });
                await _systemDocConfirmedUserRepository.UpdatePartialFromQueryAsync(x => x.SystemDocumentId == documentId, x => new SystemDocConfirmedUser()
                {
                    IsDeleted = true
                });
            }
            else
            {
                await _trialDocumentRepository.UpdatePartialFromQueryAsync(documentId, u => new TrialDocument() { IsDeleted = true });
                await _trialDocUserTypeConfirmedUserRepository.UpdatePartialFromQueryAsync(x => x.TrialDocumentId == documentId, x => new TrialDocConfirmedUser()
                {
                    IsDeleted = true
                });
            }
            await _systemDocumentRepository.SaveChangesAsync();
            return ResponseOutput.Ok();
        }


        #region 废弃


        /// <summary>
        /// 从项目下参与者的维度  先看人员列表(展示统计数字)  点击数字 再看人员具体签署的  系统文档+项目文档（共用上面与人相关的具体文档列表）
        /// </summary>
        /// <param name="trialId"></param>
        /// <returns></returns>
        [HttpGet("{trialId:guid}")]
        [Obsolete]
        public List<TrialUserUnionDocumentView> GetTrialUserDocumentList(Guid trialId)
        {
            var query = _repository.Where<TrialUser>(t => t.TrialId == trialId)
                  .Select(t => new TrialUserUnionDocumentView()
                  {
                      UserId = t.UserId,
                      UserName = t.User.UserName,
                      RealName = t.User.FullName,
                      UserTypeShortName = t.User.UserTypeRole.UserTypeShortName,
                      TrialDocumentCount = t.Trial.TrialDocumentList.Count(u => u.NeedConfirmedUserTypeList.Any(k => k.NeedConfirmUserTypeId == t.User.UserTypeId)),
                      TrialDocumentConfirmedCount = t.Trial.TrialDocumentList.SelectMany(u => u.TrialDocConfirmedUserList).Count(k => k.ConfirmUserId == t.UserId),
                      SystemDocumentConfirmedCount = t.User.SystemDocConfirmedList.Count(),
                      //这样写不行
                      //SystemDocumentCount = _systemDocumentRepository.Where(s => s.NeedConfirmedUserTypeList.Any(kk => kk.NeedConfirmUserTypeId == t.User.UserTypeId))
                      //                       .WhereIf(!_userInfo.IsAdmin, s => s.IsAbandon == false || (s.IsAbandon == true && s.SystemDocConfirmedUserList.Any(uu => uu.ConfirmUserId == t.UserId))).Count()
                      SystemDocumentCount = t.User.UserTypeRole.SystemDocNeedConfirmedUserTypeList.Where(cc => cc.NeedConfirmUserTypeId == t.User.UserTypeId).Select(y => y.SystemDocument).Count()
                  });

            return query.ToList();
        }


        /// <summary>
        /// 从 文档的维度     先看到文档列表（系统文档+项目文档   以及需要确认的人数 和已经确认人数） 点击数字查看某文档下面人确认情况
        /// </summary>
        /// <param name="querySystemDocument"></param>
        /// <returns></returns>
        [HttpPost]
        [Obsolete]
        public PageOutput<DocumentUnionWithUserStatView> GetTrialSystemDocumentList(DocumentTrialUnionQuery querySystemDocument)
        {
            var systemDocumentQueryable = _repository
                .WhereIf<SystemDocument>(!_userInfo.IsAdmin, t => t.IsDeleted == false)
                .Select(t => new DocumentUnionWithUserStatView()
                {
                    Id = t.Id,
                    IsSystemDoc = true,
                    CreateTime = t.CreateTime,
                    FullFilePath = t.Path ,
                    IsDeleted = t.IsDeleted,
                    Name = t.Name,
                    Path = t.Path,
                    FileType = t.FileType.Value,
                    UpdateTime = t.UpdateTime,
                    SignViewMinimumMinutes = t.SignViewMinimumMinutes,
                    DocumentConfirmedUserCount = t.SystemDocConfirmedUserList.Count(),

                    //DocumentUserCount= _trialUserRepository.Where(tu=>tu.TrialId== querySystemDocument.TrialId).Count(u=>t.NeedConfirmedUserTypeList.Any(cc=>cc.NeedConfirmUserTypeId== u.User.UserTypeId ))
                    DocumentUserCount = t.NeedConfirmedUserTypeList.SelectMany(u => u.UserTypeRole.UserList.SelectMany(b => b.UserTrials.Where(r => r.TrialId == querySystemDocument.TrialId))).Count()
                });

            var trialDocQueryable = _trialDocumentRepository.Where(t => t.TrialId == querySystemDocument.TrialId).Select(t => new DocumentUnionWithUserStatView()
            {
                Id = t.Id,
                IsSystemDoc = false,
                CreateTime = t.CreateTime,
                FullFilePath = t.Path ,
                IsDeleted = t.IsDeleted,
                Name = t.Name,
                Path = t.Path,
                FileType = t.FileType.Value,
                UpdateTime = t.UpdateTime,
                SignViewMinimumMinutes = t.SignViewMinimumMinutes,

                DocumentConfirmedUserCount = t.TrialDocConfirmedUserList.Count(),
                DocumentUserCount = t.Trial.TrialUserList.Count(cc => t.NeedConfirmedUserTypeList.Any(k => k.NeedConfirmUserTypeId == cc.User.UserTypeId))

            });

            var unionQuery = systemDocumentQueryable.Union(trialDocQueryable)
                 .WhereIf(!string.IsNullOrEmpty(querySystemDocument.Name), t => t.Name.Contains(querySystemDocument.Name))
                 .WhereIf(querySystemDocument.FileTypeId != null, t => t.FileTypeId == querySystemDocument.FileTypeId);

            return unionQuery.ToPagedList(querySystemDocument.PageIndex, querySystemDocument.PageSize, querySystemDocument.SortField, querySystemDocument.Asc);
        }
        #endregion



    }
}
