using IRaCIS.Application.Interfaces;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Domain.Share;
using System.Linq.Expressions;
using System.Linq.Dynamic.Core;

using Microsoft.AspNetCore.Mvc;

namespace IRaCIS.Application.Services
{ /// <summary>
  /// Dashboard统计、全局工作量统计、入组两个维度统计（按照项目、按照人）
  /// </summary>

    [ApiExplorerSettings(GroupName = "Dashboard&Statistics")]
    public class StatisticsService : BaseService, IStatisticsService
    {
        private readonly IRepository<Trial> _trialRepository;
        private readonly IRepository<CRO> _croCompanyRepository;
        private readonly IRepository<Dictionary> _dictionaryRepository;
        private readonly IRepository<Hospital> _hospitalRepository;
        private readonly IRepository<User> _userRepository;
        private readonly IRepository<TrialUser> _userTrialRepository;


        public StatisticsService( IRepository<Trial> trialRepository,
           
             IRepository<CRO> croCompanyRepository,
            IRepository<Dictionary> dictionaryRepository,
            IRepository<Hospital> hospitalRepository,
           IRepository<User> userRepository,
            IRepository<TrialUser> userTrialRepository)
        {
          
            _trialRepository = trialRepository;
         
        
            _croCompanyRepository = croCompanyRepository;
            _dictionaryRepository = dictionaryRepository;
            _hospitalRepository = hospitalRepository;
         
            _userRepository = userRepository;
            _userTrialRepository = userTrialRepository;

        }






        /// <summary> 用户参与项目 统计[New] </summary>
        [HttpPost]
        public PageOutput<UserParticipateTrialStat> GetParticipateTrialStat(ParticipateQueryDto param)
        {

            Expression<Func<User, bool>> userLambda = x => true;
            Expression<Func<TrialUser, bool>> userTrialLambda = x => true;
            if (!string.IsNullOrEmpty(param.UserInfo))
            {
                var userInfo = param.UserInfo.Trim();
                userLambda = userLambda.And(o => o.UserCode.Contains(userInfo) || (o.LastName + ' ' + o.FirstName).Contains(userInfo) || o.UserName.Contains(userInfo));
            }

            if (!string.IsNullOrWhiteSpace(param.OrganizationName))
            {
                var organizationName = param.OrganizationName.Trim();
                userLambda = userLambda.And(o => o.OrganizationName.Contains(organizationName));
            }

            var userTypeEnumStr = _userInfo.UserTypeEnumStr;
            var userId = _userInfo.Id;


            //PM  进来只能看到他负责的项目下的参与人员列表
            if (userTypeEnumStr == UserTypeEnum.ProjectManager.ToString())
            {
                //参与到的项目
                var trialFilter = _userTrialRepository.Where(t => t.UserId == userId)
                        .Select(u => u.TrialId);
                userTrialLambda = userTrialLambda.And(t => trialFilter.Contains(t.TrialId));
            }
            //.Select(u => new { u.TrialId, u.UserId }).Distinct()
            var trialStatQuery = _userTrialRepository.Where(userTrialLambda)
                .GroupBy(t => t.UserId).Select(
                    g => new
                    {
                        UserId = g.Key,
                        TrialCount = g.Count()
                    });

            var userQuery = from trialStat in trialStatQuery
                            join user in _userRepository.Where(userLambda) on trialStat.UserId equals user.Id
                            select new UserParticipateTrialStat
                            {
                                Email = user.EMail,
                                Name = user.LastName + ' ' + user.FirstName,
                                UserName = user.UserName,
                                OrganizationName = user.OrganizationName,
                                Phone = user.Phone,
                                TrialCount = trialStat.TrialCount,
                                UserCode = user.UserCode,
                                UserId = user.Id
                            };

            var propName = param.SortField == "" ? "OrganizationName" : param.SortField;
            userQuery = param.Asc
                ? userQuery.OrderBy(propName)
                : userQuery.OrderBy(propName + " desc");

            var count = userQuery.Count();

            userQuery = userQuery
                .Skip((param.PageIndex - 1) * param.PageSize)
                .Take(param.PageSize);
            var list = userQuery.ToList();

            return new PageOutput<UserParticipateTrialStat>(param.PageIndex, param.PageSize, count, list);
        }
        /// <summary> 用户参与项目 列表[New] </summary>
        [HttpGet("{userId:guid}")]
        public List<UserParticipateTrialDetail> GetParticipateTrialList(Guid userId)
        {

            Expression<Func<TrialUser, bool>> userTrialLambda = x => x.UserId == userId;

            var userTypeEnum = _userInfo.UserTypeEnumStr;
            var loginUserId = _userInfo.Id;


            //PM  进来只能看到他负责的项目下的参与人员列表
            if (userTypeEnum == UserTypeEnum.ProjectManager.ToString())
            {
                //参与到的项目
                var trialFilter = _userTrialRepository.Where(t => t.UserId == loginUserId)
                       .Select(u => u.TrialId);
                userTrialLambda = userTrialLambda.And(t => trialFilter.Contains(t.TrialId));
            }

            var query = from userTrial in _userTrialRepository.Where(userTrialLambda)
                        join trial in _trialRepository.AsQueryable() on userTrial.TrialId equals trial.Id
                        join cro in _croCompanyRepository.AsQueryable() on trial.CROId equals cro.Id into cc
                        from cro in cc.DefaultIfEmpty()
                        select new UserParticipateTrialDetail()
                        {
                            Code = trial.TrialCode,
                            CROName = cro.CROName,
                            Expedited = trial.Expedited,
                            Indication = trial.Indication,
                            UserType = userTrial.User.UserTypeRole.UserTypeShortName,
                            TrialId = trial.Id

                        };

            return query.ToList();
        }


        #region Dashboard 数据统计
    
     
        #endregion

    }
}
