using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Contracts.DTO;
using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Service;

using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Contracts;

namespace IRaCIS.Application.Services
{
    [ApiExplorerSettings(GroupName = "Trial")]
    public class TrialMaintenanceService : BaseService, ITrialMaintenanceService
    {
        private readonly IRepository<TrialUser> _trialUseRepository;
        private readonly IRepository<Trial> _trialRepository;


        public TrialMaintenanceService(IRepository<TrialUser> trialUseRepository, IRepository<Trial> trialRepository)
        {
            _trialUseRepository = trialUseRepository;
            _trialRepository = trialRepository;
        }


        #region 移动废弃

        ///// <summary>
        ///// 项目参与人员导出
        ///// </summary>
        ///// <param name="param"></param>
        ///// <param name="_commonDocumentRepository"></param>
        ///// <returns></returns>
        ///// <exception cref="Exception"></exception>
        //[HttpPost]
        //[AllowAnonymous]
        //public async Task<IActionResult> TrialUserListExport(TrialMaintenanceExportQuery param, [FromServices] IRepository<CommonDocument> _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService)
        //{

        //    var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo<ExcelExportInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException();

        //    exportInfo.List = await _trialUseRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters()
        //        .WhereIf(param.UserTypeId != null, t => t.User.UserTypeId == param.UserTypeId)
        //        .WhereIf(!string.IsNullOrWhiteSpace(param.UserName), t => t.User.UserName.Contains(param.UserName))

        //        .WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted)
        //        .WhereIf(!string.IsNullOrWhiteSpace(param.OrganizationName),
        //            t => t.User.OrganizationName.Contains(param.OrganizationName))
        //        .WhereIf(!string.IsNullOrWhiteSpace(param.UserRealName),
        //            t => (t.User.FullName).Contains(param.UserRealName))
        //        .ProjectTo<TrialMaintenanceDTO>(_mapper.ConfigurationProvider).ToListAsync();


        //    exportInfo.IsEn_US = _userInfo.IsEn_Us;

        //    return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialUserList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialMaintenanceDTO));

        //}
        #endregion




        /// <summary>
        /// Setting页面    获取项目参与人员列表
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<TrialMaintenanceDTO>> GetMaintenanceUserList(TrialMaintenanceQuery param)
        {

            var query = _trialUseRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters()
                .WhereIf(param.UserTypeId != null, t => t.User.UserTypeId == param.UserTypeId)
                .WhereIf(!string.IsNullOrWhiteSpace(param.UserName), t => t.User.UserName.Contains(param.UserName))

                 .WhereIf(param.IsDeleted != null, t => t.IsDeleted == param.IsDeleted)
                .WhereIf(!string.IsNullOrWhiteSpace(param.OrganizationName), t => t.User.OrganizationName.Contains(param.OrganizationName))
                .WhereIf(!string.IsNullOrWhiteSpace(param.UserRealName), t => (t.User.FullName).Contains(param.UserRealName))
                .ProjectTo<TrialMaintenanceDTO>(_mapper.ConfigurationProvider);

            return await query.ToPagedListAsync(param.PageIndex, param.PageSize, string.IsNullOrWhiteSpace(param.SortField) ? "UpdateTime" : param.SortField, param.Asc);

        }





        /// <summary> Setting页面  为 site 勾选CRC用户列表</summary> 
        [HttpPost]
        public async Task<PageOutput<AssginSiteCRCListDTO>> GetSiteCRCScreeningList(SiteCRCQuery param)
        {
            // 最开始过滤site已经选择的用户 现在又改回去。。。 

            var query = _trialUseRepository.Where(t => t.TrialId == param.TrialId).IgnoreQueryFilters()
                .Where(t => t.User.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.User.UserTypeEnum == UserTypeEnum.CRA ||t.User.UserTypeEnum==UserTypeEnum.SR)
                 .WhereIf(param.UserTypeId != null, t => t.User.UserTypeId == param.UserTypeId)
                .WhereIf(!string.IsNullOrWhiteSpace(param.UserRealName), t => (t.User.FullName).Contains(param.UserRealName))
                .WhereIf(!string.IsNullOrWhiteSpace(param.OrganizationName), t => t.User.OrganizationName.Contains(param.OrganizationName))
                .ProjectTo<AssginSiteCRCListDTO>(_mapper.ConfigurationProvider, new { siteId = param.SiteId });

            return await query.ToPagedListAsync(param.PageIndex,
                param.PageSize, string.IsNullOrWhiteSpace(param.SortField) ? "UpdateTime" : param.SortField, param.Asc);

        }


        /// <summary> Setting页面   项目参与人员勾选列表   </summary>
        [HttpPost]
        public async Task<IResponseOutput<PageOutput<TrialUserScreeningDTO>> > GetTrialUserScreeningList(TrialUserQuery trialUserQuery)
        {
            var trialConfig = _trialRepository.Where(t => t.Id == trialUserQuery.TrialId).Select(t => new { t.TrialType ,t.QCProcessEnum}).FirstOrDefault();

            var trialType = trialConfig.TrialType;
            var qcProcessEnum=trialConfig.QCProcessEnum;


            //之前已经选择的用户 不放在列表中,现在又要改回去 废弃
            var query = _repository.Where<User>(t => t.UserTypeEnum != UserTypeEnum.SuperAdmin)

                 //正式或者培训的项目  不能允许测试用户(必须正式用户)  同时必须是内部的用户
                 .WhereIf(trialType == TrialType.OfficialTrial || trialType == TrialType.Training, t => t.IsTestUser == false && t.IsZhiZhun)

                 //测试项目 可以加入 测试用户  或者内部正式用户
                 .WhereIf(trialType == TrialType.NoneOfficial, t => t.IsTestUser == true || (t.IsTestUser == false && t.IsZhiZhun))

                 //TA  只能加PM
                 .WhereIf(_userInfo.UserTypeEnumInt==(int)UserTypeEnum.TA, t => t.UserTypeEnum== UserTypeEnum.ProjectManager)

                 //PM  不审  只能加IM    IQC
                 .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && qcProcessEnum == TrialQCProcess.NotAudit, t => (t.UserTypeEnum == UserTypeEnum.IM ||t.UserTypeEnum==UserTypeEnum.QA))
                 .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager && qcProcessEnum != TrialQCProcess.NotAudit, t =>( t.UserTypeEnum == UserTypeEnum.IM|| t.UserTypeEnum == UserTypeEnum.IQC || t.UserTypeEnum == UserTypeEnum.QA))



                 .WhereIf(!string.IsNullOrWhiteSpace(trialUserQuery.UserRealName), t => (t.FullName).Contains(trialUserQuery.UserRealName))
                 .WhereIf(!string.IsNullOrWhiteSpace(trialUserQuery.UserName), t => t.UserName.Contains(trialUserQuery.UserName))
                 .WhereIf(!string.IsNullOrWhiteSpace(trialUserQuery.OrganizationName), t => t.OrganizationName.Contains(trialUserQuery.OrganizationName))
                 .WhereIf(trialUserQuery.UserTypeEnum != null, t => t.UserTypeEnum == trialUserQuery.UserTypeEnum)
                 //.WhereIf(_userInfo.IsAdmin, t => t.UserTypeRole.Type == UserTypeGroup.TrialUser)
                 //.WhereIf(!_userInfo.IsAdmin, t => t.UserTypeRole.Type == UserTypeGroup.TrialUser || t.UserTypeEnum != UserTypeEnum.ProjectManager)
                 .ProjectTo<TrialUserScreeningDTO>(_mapper.ConfigurationProvider, new { trialId = trialUserQuery.TrialId });

            var pageList= await query.ToPagedListAsync(trialUserQuery.PageIndex,
               trialUserQuery.PageSize, string.IsNullOrWhiteSpace(trialUserQuery.SortField) ? "UserRealName" : trialUserQuery.SortField, trialUserQuery.Asc);

            return ResponseOutput.Ok(pageList, trialConfig);

        }


        /// <summary>
        /// Setting页面   批量添加项目参与人员
        /// </summary>
        /// <param name="userTrialCommands"></param>
        /// <returns></returns>
        //[TrialAudit(AuditType.TrialAudit, AuditOptType.AddTrialStaff)]
        [HttpPost]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        //[Authorize(Policy = IRaCISPolicy.PM_APM)]
        public async Task<IResponseOutput> AddTrialUsers(TrialUserAddCommand[] userTrialCommands)
        {

            var addArray = _mapper.Map<TrialUser[]>(userTrialCommands);

            var trialUsers = await _trialUseRepository.AddRangeAsync(addArray);

            foreach (var item in trialUsers)
            {
                item.JoinTime = DateTime.Now;
            }


            var success = await _repository.SaveChangesAsync();

            return ResponseOutput.Result(success);
        }



        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        //[Authorize(Policy = IRaCISPolicy.PM_APM)]
        [HttpPut]
        public async Task<IResponseOutput> UpdateTrialUser(UpdateTrialUserCommand updateTrialUserCommand)
        {
            var trialUser = await _trialUseRepository.Where(t => t.Id == updateTrialUserCommand.Id, true, true).FirstOrDefaultAsync();

            if (trialUser == null) return Null404NotFound(trialUser);


            if (updateTrialUserCommand.IsDeleted)
            {
                if (await _repository.AnyAsync<TrialSiteUser>(t => t.UserId == trialUser.UserId && t.TrialId == trialUser.TrialId))
                {
					// ----人员已加入现场维护
					return ResponseOutput.NotOk(_localizer["TrialMaint_PersonnelJoined"]);
                }

                if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC)
                {
                    await _repository.BatchUpdateAsync<SubjectVisit>(t => t.CurrentActionUserId == trialUser.UserId && t.TrialId == trialUser.TrialId && t.IsTake, u => new SubjectVisit() { CurrentActionUserId = null, CurrentActionUserExpireTime = null, IsTake = false });
                }

            }

            _mapper.Map(updateTrialUserCommand, trialUser);

            await _repository.SaveChangesAsync();

            return ResponseOutput.Ok();


        }


        /// <summary> 项目参与人员退出   其中IQC退出 回去释放工作量 </summary>
        //[TrialAudit(AuditType.TrialAudit, AuditOptType.DeleteTrailStaff)]
        [HttpDelete, Route("{id:guid}/{trialId:guid}/{isDelete:bool}")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        [UnitOfWork]
        [Obsolete]
        public async Task<IResponseOutput> DeleteMaintenanceUser(Guid id, bool isDelete)
        {

            var trialUser = await _trialUseRepository.AsQueryable().IgnoreQueryFilters().FirstOrDefaultAsync(t => t.Id == id);

            if (trialUser == null) return Null404NotFound(trialUser);

            if (await _repository.AnyAsync<TrialSiteUser>(t => t.UserId == trialUser.UserId && t.TrialId == trialUser.TrialId))
            {
                //---人员已加入现场维护
                return ResponseOutput.NotOk(_localizer["TrialMaint_PersonnelJoined"]);
            }

            if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC && isDelete)
            {
                await _repository.BatchUpdateAsync<SubjectVisit>(t => t.CurrentActionUserId == trialUser.UserId && t.TrialId == trialUser.TrialId && t.IsTake, u => new SubjectVisit() { CurrentActionUserId = null, CurrentActionUserExpireTime = null, IsTake = false });
            }

            await _trialUseRepository.BatchUpdateNoTrackingAsync(t => t.Id == id, u => new TrialUser() { IsDeleted = isDelete, RemoveTime = isDelete ? DateTime.Now : null });

            await _repository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }



    }
}