package com.xinelu.manage.service.homepage.impl;

import com.xinelu.common.core.domain.entity.SysUser;
import com.xinelu.common.enums.NodeExecuteStatusEnum;
import com.xinelu.common.enums.PhoneDialMethodEnum;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.manage.domain.agency.Agency;
import com.xinelu.manage.mapper.agency.AgencyMapper;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.patientprehospitalization.PatientPreHospitalizationMapper;
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
import com.xinelu.manage.mapper.signpatientrecord.SignPatientRecordMapper;
import com.xinelu.manage.service.homepage.SystemHomePageService;
import com.xinelu.manage.vo.homepage.*;
import com.xinelu.system.mapper.SysUserMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 首页信息Service业务层处理
 *
 * @author ZH
 * @date 2024-08-13
 */
@Service
public class SystemHomePageServiceImpl implements SystemHomePageService {
    @Resource
    private PatientInfoMapper patientInfoMapper;
    @Resource
    private PatientPreHospitalizationMapper patientPreHospitalizationMapper;
    @Resource
    private SignPatientManageRouteNodeMapper signPatientManageRouteNodeMapper;
    @Resource
    private SignPatientRecordMapper signPatientRecordMapper;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private AgencyMapper agencyMapper;

    /**
     * 顶部统计
     *
     * @return TopStatisticsVO
     */
    @Override
    public TopStatisticsVO topStatistics() {
        LocalDate now = LocalDate.now();
        Long hospitalAgencyId = null;
        SysUser sysUser = sysUserMapper.selectUserById(SecurityUtils.getUserId());
        if(Objects.nonNull(sysUser.getHospitalAgencyId())){
            Agency agency = agencyMapper.selectAgencyById(sysUser.getHospitalAgencyId());
            if (Objects.nonNull(agency.getId())){
                hospitalAgencyId = agency.getId();
            }
        }
        TopStatisticsVO topStatisticsVO = new TopStatisticsVO();
        //本月第一天
        LocalDate firstDay = now.with(TemporalAdjusters.firstDayOfMonth());
        //本月患者数量
        int createPatientCount = patientInfoMapper.getPatientInfoCountByCreateTime(firstDay, now, hospitalAgencyId);
        //本月预住院数量
        int patientPreHospitalizationCount = patientPreHospitalizationMapper.getPatientPreHospitalizationCountByCreateTime(firstDay, now, hospitalAgencyId);
        //本月患者数
        topStatisticsVO.setThisMonthPatient(createPatientCount + patientPreHospitalizationCount);
        //本月本月出院患者数 统计门诊/出院的 患者数量
        topStatisticsVO.setThisMonthDischargePatient(createPatientCount);
        //本月签约数
        topStatisticsVO.setSignPatientCount(patientInfoMapper.selectPatientInfoCountBySignTime(firstDay, now, hospitalAgencyId));
        //本月任务数
        topStatisticsVO.setNodeCount(signPatientManageRouteNodeMapper.selectNodeCountByCreateTime(firstDay, now));
        //已签约总数
        topStatisticsVO.setPatientSignCount(patientInfoMapper.selectPatientSignTotalCount(hospitalAgencyId));
        //服务中患者数
        topStatisticsVO.setPatientSignServiceCount(patientInfoMapper.selectPatientSignServiceCount());
        return topStatisticsVO;
    }

    /**
     * 患者签约情况
     *
     * @return SignPatientCount
     */
    @Override
    public List<SignPatientCount> signPatientCount() {
        //时间集合
        Long hospitalAgencyId = null;
        SysUser sysUser = sysUserMapper.selectUserById(SecurityUtils.getUserId());
        if(Objects.nonNull(sysUser.getHospitalAgencyId())){
            Agency agency = agencyMapper.selectAgencyById(sysUser.getHospitalAgencyId());
            if (Objects.nonNull(agency.getId())){
                hospitalAgencyId = agency.getId();
            }
        }
        List<LocalDate> localDates = new ArrayList<>();
        List<SignPatientCount> signPatientCounts = new ArrayList<>();
        LocalDate now = LocalDate.now();
        for (int i = 5; i >= 0; i--) {
            LocalDate localDate = now.minusMonths(i);
            localDates.add(localDate);
        }
        //数据
        for (LocalDate localDate : localDates) {
            SignPatientCount signPatientCount = new SignPatientCount();
            LocalDate firstDay = localDate.with(TemporalAdjusters.firstDayOfMonth());
            LocalDate lastDay = localDate.with(TemporalAdjusters.lastDayOfMonth());
            //患者数量
            int createPatientCount = patientInfoMapper.getPatientInfoCountByCreateTime(firstDay, lastDay,hospitalAgencyId);
            int patientPreHospitalizationCount = patientPreHospitalizationMapper.getPatientPreHospitalizationCountByCreateTime(firstDay, lastDay,hospitalAgencyId);
            int i = patientInfoMapper.selectPatientInfoCountBySignTime(firstDay, lastDay,hospitalAgencyId);
            //签约
            int signPatient = patientInfoMapper.selectPatientInfoCountBySignTime(firstDay, now,hospitalAgencyId);
            signPatientCount.setTime(localDate);
            signPatientCount.setPatientCount(createPatientCount + patientPreHospitalizationCount);
            signPatientCount.setSignPatientCount(signPatient);
            //除法运算
            if (createPatientCount != 0) {
                signPatientCount.setProportion(new BigDecimal(i).divide(new BigDecimal(createPatientCount), 2, RoundingMode.HALF_UP));
            } else {
                signPatientCount.setProportion(BigDecimal.ZERO);
            }
            signPatientCounts.add(signPatientCount);
        }
        return signPatientCounts;
    }

    /**
     * 服务方式
     *
     * @return ServiceModeStatistics
     */
    @Override
    public List<ServiceModeStatistics> serviceModeStatistics() {
        ArrayList<ServiceModeStatistics> serviceModeStatisticsList = new ArrayList<>();
        //人工随访
        BigDecimal common = signPatientManageRouteNodeMapper.selectNodeCount(PhoneDialMethodEnum.COMMON.getInfo(), null, null);
        //ai
        BigDecimal AI = signPatientManageRouteNodeMapper.selectNodeCount(PhoneDialMethodEnum.AI.getInfo(), null, null);
        //短信
        BigDecimal messagePushSign = signPatientManageRouteNodeMapper.selectNodeCount(null, 0L, null);
        //微信
        BigDecimal appletPushSign = signPatientManageRouteNodeMapper.selectNodeCount(null, null, 0L);
        //全部
        BigDecimal all = common.add(AI).add(messagePushSign).add(appletPushSign);
        //除法运算
        if (all.equals(BigDecimal.ZERO)) {
            serviceModeStatisticsList.add(new ServiceModeStatistics("AI", BigDecimal.ZERO, AI));
            serviceModeStatisticsList.add(new ServiceModeStatistics("短信", BigDecimal.ZERO, messagePushSign));
            serviceModeStatisticsList.add(new ServiceModeStatistics("微信", BigDecimal.ZERO, appletPushSign));
            serviceModeStatisticsList.add(new ServiceModeStatistics("人工随访", BigDecimal.ZERO, common));
        } else {
            serviceModeStatisticsList.add(new ServiceModeStatistics("AI", AI.divide(all, 2, RoundingMode.HALF_UP), AI));
            serviceModeStatisticsList.add(new ServiceModeStatistics("短信", messagePushSign.divide(all, 2, RoundingMode.HALF_UP), messagePushSign));
            serviceModeStatisticsList.add(new ServiceModeStatistics("微信", appletPushSign.divide(all, 2, RoundingMode.HALF_UP), appletPushSign));
            serviceModeStatisticsList.add(new ServiceModeStatistics("人工随访", common.divide(all, 2, RoundingMode.HALF_UP), common));
        }
        return serviceModeStatisticsList;
    }

    /**
     * 代办任务
     *
     * @return TaskSituation
     */
    @Override
    public List<TaskSituation> taskSituation() {
        Long hospitalAgencyId = null;
        SysUser sysUser = sysUserMapper.selectUserById(SecurityUtils.getUserId());
        if(Objects.nonNull(sysUser.getHospitalAgencyId())){
            Agency agency = agencyMapper.selectAgencyById(sysUser.getHospitalAgencyId());
            if (Objects.nonNull(agency.getId())){
                hospitalAgencyId = agency.getId();
            }
        }
        LocalDate now = LocalDate.now();
        List<TaskSituation> taskSituations = new ArrayList<>();
        //未审核
        int checkStatusCount = signPatientRecordMapper.selectCheckStatus("UNAUDITED", "SERVICE_CENTER");
        //全部
        int signTimeCount = signPatientRecordMapper.selectCheckStatus(null, "SERVICE_CENTER");
        //任务
        List<PatientAndNode> patientAndNodes = signPatientManageRouteNodeMapper.selectNodeExecuteStatus(hospitalAgencyId);
        //未审核
        int unExecutedCount = 0;
        //全部
        int allCount = 0;
        if (CollectionUtils.isNotEmpty(patientAndNodes)) {
            allCount = patientAndNodes.size();
            for (PatientAndNode patientAndNode : patientAndNodes) {
                LocalDateTime localDateTime = null;
                //如果有计划执行时间，则直接获取
                if (patientAndNode.getNodePlanTime() != null) {
                    localDateTime = patientAndNode.getNodePlanTime();
                }
                // 否则 ，则根据诊后/院后 第几天 计算
                else {
                    LocalTime et = LocalTime.of(8,0,0);

                    if (Objects.nonNull(patientAndNode.getDischargeTime()) && Objects.nonNull(patientAndNode.getRouteNodeDay()) ) {
                        localDateTime = LocalDateTime.of(patientAndNode.getDischargeTime().plusDays(patientAndNode.getRouteNodeDay()).toLocalDate(), et);

                    }
                    if (Objects.isNull(patientAndNode.getDischargeTime()) && Objects.nonNull(patientAndNode.getVisitDate()) && Objects.nonNull(patientAndNode.getRouteNodeDay())) {
                        localDateTime = LocalDateTime.of(patientAndNode.getVisitDate().plusDays(patientAndNode.getRouteNodeDay()).toLocalDate(), et);
                    }
                    if  (Objects.isNull(localDateTime)) {
                            continue;
                    }
                }
                boolean before = localDateTime.isBefore(LocalDateTime.now()) || localDateTime.isEqual(LocalDateTime.now());
                if (before) {
                    //未执行
                    if (!NodeExecuteStatusEnum.EXECUTED.getInfo().equals(patientAndNode.getNodeExecuteStatus())) {
                        unExecutedCount++;
                    }
                }
            }
        }
        taskSituations.add(new TaskSituation("人工审核", checkStatusCount, signTimeCount));
        taskSituations.add(new TaskSituation("人工随访", unExecutedCount, allCount));
        return taskSituations;
    }
}
