using Cronos;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Shentun.Peis.CriticalFollowValues;
using Shentun.Peis.Enums;
using Shentun.Peis.Models;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;
namespace Shentun.Peis.PhoneFollowUps
{
    /// 
    /// 电话随访记录
    /// 
    [ApiExplorerSettings(GroupName = "Work")]
    [Authorize]
    public class PhoneFollowUpAppService : ApplicationService
    {
        private readonly IRepository _phoneFollowUpRepository;
        private readonly CacheService _cacheService;
        private readonly IRepository _followUpRepository;
        private readonly IRepository _patientRegisterRepository;
        private readonly IRepository _registerCheckRepository;
        private readonly IRepository _registerCheckItemRepository;
        private readonly IRepository _registerCheckAsbitemRepository;
        private readonly IRepository _asbitemRepository;
        private readonly IRepository-  _itemRepository;
        private readonly IRepository _patientRepository;
        public PhoneFollowUpAppService(
            IRepository phoneFollowUpRepository,
            CacheService cacheService,
            IRepository followUpRepository,
            IRepository patientRegisterRepository,
            IRepository registerCheckRepository,
            IRepository registerCheckItemRepository,
            IRepository registerCheckAsbitemRepository,
            IRepository asbitemRepository,
            IRepository
-  itemRepository,
            IRepository patientRepository)
        {
            _phoneFollowUpRepository = phoneFollowUpRepository;
            _cacheService = cacheService;
            _followUpRepository = followUpRepository;
            _patientRegisterRepository = patientRegisterRepository;
            _registerCheckRepository = registerCheckRepository;
            _registerCheckItemRepository = registerCheckItemRepository;
            _registerCheckAsbitemRepository = registerCheckAsbitemRepository;
            _asbitemRepository = asbitemRepository;
            _itemRepository = itemRepository;
            _patientRepository = patientRepository;
        }
        /// 
        /// 获取电话随访记录信息
        /// 
        /// 
        /// 
        [HttpPost("api/app/PhoneFollowUp/Get")]
        public async Task GetAsync(PhoneFollowUpIdInputDto input)
        {
            var phoneFollowUpEnt = await _phoneFollowUpRepository.GetAsync(input.PhoneFollowUpId);
            var entityDto = ObjectMapper.Map(phoneFollowUpEnt);
            entityDto.CreatorName = await _cacheService.GetSurnameAsync(entityDto.CreatorId);
            entityDto.LastModifierName = await _cacheService.GetSurnameAsync(entityDto.LastModifierId);
            return entityDto;
        }
        /// 
        /// 获取电话随访记录信息
        /// 
        /// 
        /// 
        [HttpPost("api/app/PhoneFollowUp/GetList")]
        public async Task
> GetListAsync(PhoneFollowUpListInputDto input)
        {
            var query = from phoneFollowUp in await _phoneFollowUpRepository.GetQueryableAsync()
                        join followUp in await _followUpRepository.GetQueryableAsync() on phoneFollowUp.FollowUpId equals followUp.Id
                        join patientRegister in await _patientRegisterRepository.GetQueryableAsync() on followUp.PatientRegisterId equals patientRegister.Id
                        orderby patientRegister.Id, phoneFollowUp.PlanFollowDate
                        select new
                        {
                            patientName = patientRegister.PatientName,
                            phoneFollowUp
                        };
            if (input.FollowUpId != null)
            {
                query = query.Where(m => m.phoneFollowUp.FollowUpId == input.FollowUpId);
            }
            if (!string.IsNullOrWhiteSpace(input.KeyWord))
            {
                query = query.Where(m => (!string.IsNullOrWhiteSpace(m.phoneFollowUp.FollowUpContent) && m.phoneFollowUp.FollowUpContent.Contains(input.KeyWord))
                || (!string.IsNullOrWhiteSpace(m.phoneFollowUp.ReplyContent) && m.phoneFollowUp.ReplyContent.Contains(input.KeyWord))
                );
            }
            if (input.IsComplete != null)
            {
                query = query.Where(m => m.phoneFollowUp.IsComplete == input.IsComplete);
            }
            if (!string.IsNullOrWhiteSpace(input.StartDate) && !string.IsNullOrWhiteSpace(input.EndDate))
            {
                query = query.Where(m => m.phoneFollowUp.PlanFollowDate >= Convert.ToDateTime(input.StartDate)
                && m.phoneFollowUp.PlanFollowDate <= Convert.ToDateTime(input.EndDate).AddDays(1));
            }
            var entListDto = query.ToList().Select(s => new PhoneFollowUpWithPatientRegisterDto
            {
                FollowUpId = s.phoneFollowUp.FollowUpId,
                CreationTime = s.phoneFollowUp.CreationTime,
                ReplyContent = s.phoneFollowUp.ReplyContent,
                PlanFollowDate = DataHelper.ConversionDateToString(s.phoneFollowUp.PlanFollowDate),
                CreatorId = s.phoneFollowUp.CreatorId,
                FollowUpContent = s.phoneFollowUp.ReplyContent,
                Id = s.phoneFollowUp.Id,
                IsComplete = s.phoneFollowUp.IsComplete,
                LastModificationTime = s.phoneFollowUp.LastModificationTime,
                LastModifierId = s.phoneFollowUp.LastModifierId,
                CreatorName = _cacheService.GetSurnameAsync(s.phoneFollowUp.CreatorId).GetAwaiter().GetResult(),
                LastModifierName = _cacheService.GetSurnameAsync(s.phoneFollowUp.LastModifierId).GetAwaiter().GetResult(),
                PatientName = s.patientName
            }).ToList();
            return entListDto;
        }
        /// 
        /// 获取人员随访记录
        /// 
        /// 
        [HttpPost("api/app/PhoneFollowUp/GetPatientRegisterCriticalList")]
        public async Task> GetPatientRegisterCriticalListAsync()
        {
            var query = from followUp in await _followUpRepository.GetQueryableAsync()
                        join patientRegister in await _patientRegisterRepository.GetQueryableAsync() on followUp.PatientRegisterId equals patientRegister.Id
                        join patient in await _patientRepository.GetQueryableAsync() on patientRegister.PatientId equals patient.Id
                        join registerCheck in await _registerCheckRepository.GetQueryableAsync() on patientRegister.Id equals registerCheck.PatientRegisterId
                        join registerCheckAsbitem in await _registerCheckAsbitemRepository.GetQueryableAsync() on registerCheck.Id equals registerCheckAsbitem.RegisterCheckId
                        join asbitem in await _asbitemRepository.GetQueryableAsync() on registerCheckAsbitem.AsbitemId equals asbitem.Id
                        join registerCheckItem in await _registerCheckItemRepository.GetQueryableAsync() on registerCheck.Id equals registerCheckItem.RegisterCheckId
                        join item in await _itemRepository.GetQueryableAsync() on registerCheckItem.ItemId equals item.Id
                        join phoneFollowUp in await _phoneFollowUpRepository.GetQueryableAsync() on followUp.Id equals phoneFollowUp.FollowUpId into phoneFollowUpTemp
                        from phoneFollowUpEmpty in phoneFollowUpTemp.DefaultIfEmpty()
                        select new
                        {
                            patientRegister,
                            registerCheck,
                            asbitem,
                            registerCheckItem,
                            item,
                            followUp,
                            phoneFollowUpEmpty,
                            patient
                        };
            var ff = query.ToQueryString();
            var followUpGroup = query.ToList().GroupBy(g => g.followUp);
            var entListDto = followUpGroup.Select(s => new PhoneFollowUpWithCriticalItemDto
            {
                PatientName = s.FirstOrDefault().patientRegister.PatientName,
                IdNo = s.FirstOrDefault().patient.IdNo,
                PatientRegisterNo = s.FirstOrDefault().patientRegister.PatientRegisterNo,
                PhoneFollowUpDetail = s.Where(m => m.phoneFollowUpEmpty != null).GroupBy(g => g.phoneFollowUpEmpty).Select(ss => new PhoneFollowUpSimpleDto
                {
                    FollowUpContent = ss.Key.FollowUpContent,
                    IsComplete = ss.Key.IsComplete,
                    PlanFollowDate = DataHelper.ConversionDateToString(ss.Key.PlanFollowDate),
                    ReplyContent = ss.Key.ReplyContent
                }).ToList(),
                AbnormalAsbitemDetail = s.Where(m => m.registerCheck.IsCriticalValue != null).GroupBy(g => g.registerCheck).Select(ss => new PhoneFollowUpWithCriticalItemAbnormalAsbitemDto
                {
                    CriticalValueContent = ss.Key.CriticalValueContent,
                    AsbitemName = string.Join(",", ss.Select(sss => sss.asbitem.DisplayName).Distinct()),
                    IsCriticalValue = ss.Key.IsCriticalValue == null ? 'N' : ss.Key.IsCriticalValue.Value,
                    IsReview = ss.Key.IsReview == null ? 'N' : ss.Key.IsReview.Value
                }).ToList(),
                AbnormalItemDetail = s.Where(m => m.registerCheckItem.IsCriticalValue != null).GroupBy(g => g.registerCheckItem).Select(ss => new PhoneFollowUpWithCriticalItemAbnormalItemDto
                {
                    CriticalValueContent = ss.Key.CriticalValueContent,
                    ItemName = ss.FirstOrDefault().item.DisplayName,
                    IsCriticalValue = ss.Key.IsCriticalValue == null ? 'N' : ss.Key.IsCriticalValue.Value,
                    IsReview = ss.Key.IsReview == null ? 'N' : ss.Key.IsReview.Value
                }).ToList()
            }).ToList();
            return entListDto;
            //var query = from phoneFollowUp in await _phoneFollowUpRepository.GetQueryableAsync()
            //            join followUp in await _followUpRepository.GetQueryableAsync() on phoneFollowUp.FollowUpId equals followUp.Id
            //            join patientRegister in await _patientRegisterRepository.GetQueryableAsync() on followUp.PatientRegisterId equals patientRegister.Id
            //            orderby patientRegister.Id, phoneFollowUp.PlanFollowDate
            //            select new
            //            {
            //                patientName = patientRegister.PatientName,
            //                phoneFollowUp
            //            };
            //if (input.FollowUpId != null)
            //{
            //    query = query.Where(m => m.phoneFollowUp.FollowUpId == input.FollowUpId);
            //}
            //if (!string.IsNullOrWhiteSpace(input.KeyWord))
            //{
            //    query = query.Where(m => (!string.IsNullOrWhiteSpace(m.phoneFollowUp.FollowUpContent) && m.phoneFollowUp.FollowUpContent.Contains(input.KeyWord))
            //    || (!string.IsNullOrWhiteSpace(m.phoneFollowUp.ReplyContent) && m.phoneFollowUp.ReplyContent.Contains(input.KeyWord))
            //    );
            //}
            //if (input.IsComplete != null)
            //{
            //    query = query.Where(m => m.phoneFollowUp.IsComplete == input.IsComplete);
            //}
            //if (!string.IsNullOrWhiteSpace(input.StartDate) && !string.IsNullOrWhiteSpace(input.EndDate))
            //{
            //    query = query.Where(m => m.phoneFollowUp.PlanFollowDate >= Convert.ToDateTime(input.StartDate)
            //    && m.phoneFollowUp.PlanFollowDate <= Convert.ToDateTime(input.EndDate).AddDays(1));
            //}
            //var entListDto = query.ToList().Select(s => new PhoneFollowUpWithPatientRegisterDto
            //{
            //    FollowUpId = s.phoneFollowUp.FollowUpId,
            //    CreationTime = s.phoneFollowUp.CreationTime,
            //    ReplyContent = s.phoneFollowUp.ReplyContent,
            //    PlanFollowDate = DataHelper.ConversionDateToString(s.phoneFollowUp.PlanFollowDate),
            //    CreatorId = s.phoneFollowUp.CreatorId,
            //    FollowUpContent = s.phoneFollowUp.ReplyContent,
            //    Id = s.phoneFollowUp.Id,
            //    IsComplete = s.phoneFollowUp.IsComplete,
            //    LastModificationTime = s.phoneFollowUp.LastModificationTime,
            //    LastModifierId = s.phoneFollowUp.LastModifierId,
            //    CreatorName = _cacheService.GetSurnameAsync(s.phoneFollowUp.CreatorId).GetAwaiter().GetResult(),
            //    LastModifierName = _cacheService.GetSurnameAsync(s.phoneFollowUp.LastModifierId).GetAwaiter().GetResult(),
            //    PatientName = s.patientName
            //}).ToList();
            //return entListDto;
        }
        /// 
        /// 创建电话随访记录
        /// 
        /// 
        /// 
        [HttpPost("api/app/PhoneFollowUp/Create")]
        public async Task CreateAsync(CreatePhoneFollowUpDto input)
        {
            if (string.IsNullOrWhiteSpace(input.ModeValue))
            {
                throw new UserFriendlyException("计划周期不能为空");
            }
            if (input.FollowUpMode == FollowUpModeFlag.Corn && string.IsNullOrWhiteSpace(input.EndDate))
            {
                throw new UserFriendlyException("采用corn表达式时需要截止日期");
            }
            var isPhoneFollowUp = await _phoneFollowUpRepository.CountAsync(c => c.FollowUpId == input.FollowUpId);
            if (isPhoneFollowUp > 0)
            {
                throw new UserFriendlyException("已存在电话随访记录,不允许重复生成");
            }
            List phoneFollowUpList = new List();
            if (input.FollowUpMode == FollowUpModeFlag.Corn)
            {
                //corn表达式
                #region 解析Cron表达式
                try
                {
                    var schedule = CronExpression.Parse(input.ModeValue, CronFormat.IncludeSeconds);
                    var occurrences = schedule.GetOccurrences(DateTime.UtcNow, Convert.ToDateTime(input.EndDate).ToUniversalTime());  //获取截止时间前所有的计划时间
                    foreach (var occurrence in occurrences)
                    {
                        var phoneFollowUpEntity = new PhoneFollowUp(GuidGenerator.Create())
                        {
                            FollowUpContent = input.FollowUpContent,
                            FollowUpId = input.FollowUpId,
                            ReplyContent = input.ReplyContent,
                            PlanFollowDate = occurrence,
                            IsComplete = 'N'
                        };
                        phoneFollowUpList.Add(phoneFollowUpEntity);
                    }
                }
                catch (Exception ex)
                {
                    throw new UserFriendlyException("Corn表达式不正确");
                }
                #endregion
            }
            else
            {
                //其他模式
                int planCount = 0;
                try
                {
                    planCount = Convert.ToInt32(input.ModeValue);
                }
                catch (Exception ex)
                {
                    throw new UserFriendlyException("Corn表达式不正确");
                }
                for (int i = 0; i < planCount; i++)
                {
                    DateTime planFollowDate = DateTime.Now;
                    if (input.FollowUpMode == FollowUpModeFlag.Day)
                    {
                        planFollowDate = planFollowDate.AddDays(i);
                    }
                    else if (input.FollowUpMode == FollowUpModeFlag.Week)
                    {
                        planFollowDate = planFollowDate.AddDays(7 * i);
                    }
                    else if (input.FollowUpMode == FollowUpModeFlag.Month)
                    {
                        planFollowDate = planFollowDate.AddMonths(i);
                    }
                    else if (input.FollowUpMode == FollowUpModeFlag.Year)
                    {
                        planFollowDate = planFollowDate.AddYears(i);
                    }
                    var phoneFollowUpEntity = new PhoneFollowUp(GuidGenerator.Create())
                    {
                        FollowUpContent = input.FollowUpContent,
                        FollowUpId = input.FollowUpId,
                        ReplyContent = input.ReplyContent,
                        PlanFollowDate = planFollowDate,
                        IsComplete = 'N'
                    };
                    phoneFollowUpList.Add(phoneFollowUpEntity);
                }
            }
            if (phoneFollowUpList.Any())
            {
                await _phoneFollowUpRepository.InsertManyAsync(phoneFollowUpList);
            }
        }
        /// 
        /// 修改电话随访记录
        /// 
        /// 
        /// 
        [HttpPost("api/app/PhoneFollowUp/Update")]
        public async Task UpdateAsync(UpdatePhoneFollowUpDto input)
        {
            var entity = await _phoneFollowUpRepository.GetAsync(input.PhoneFollowUpId);
            entity.IsComplete = input.IsComplete;
            if (input.PlanFollowDate != null)
            {
                entity.PlanFollowDate = Convert.ToDateTime(input.PlanFollowDate);
            }
            if (!string.IsNullOrWhiteSpace(input.ReplyContent))
            {
                entity.ReplyContent = input.ReplyContent;
            }
            if (!string.IsNullOrWhiteSpace(input.FollowUpContent))
            {
                entity.FollowUpContent = input.FollowUpContent;
            }
            await _phoneFollowUpRepository.UpdateAsync(entity);
        }
        /// 
        /// 删除
        /// 
        /// 
        /// 
        [HttpPost("api/app/PhoneFollowUp/Delete")]
        public async Task DeleteAsync(PhoneFollowUpIdInputDto input)
        {
            await _phoneFollowUpRepository.DeleteAsync(input.PhoneFollowUpId);
        }
    }
}