package com.yihu.wlyy.statistics.job.business;

import com.yihu.wlyy.statistics.dao.*;
import com.yihu.wlyy.statistics.etl.dataFilter.SignDataFilter;
import com.yihu.wlyy.statistics.etl.extract.DBExtract;
import com.yihu.wlyy.statistics.etl.model.CacheModel;
import com.yihu.wlyy.statistics.etl.model.ETLModel;
import com.yihu.wlyy.statistics.etl.model.FilterModel;
import com.yihu.wlyy.statistics.etl.mycache.CachePool;
import com.yihu.wlyy.statistics.etl.role.Level1Role;
import com.yihu.wlyy.statistics.etl.role.Level2Role;
import com.yihu.wlyy.statistics.etl.storage.DBStorage;
import com.yihu.wlyy.statistics.model.job.QuartzJobLog;
import com.yihu.wlyy.statistics.util.JsonUtil;
import com.yihu.wlyy.statistics.vo.WlyyJobConfigVO;
import com.yihu.wlyy.statistics.vo.WlyyQuotaVO;
import org.json.JSONObject;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Calendar;

/**
 * 签约的指标执行类
 */
@Component
@Scope("prototype")
@DisallowConcurrentExecution//防止到了执行时间点前一任务还在执行中，但是这时有空闲的线程，那么马上又会执行，这样一来就会存在同一job被并行执行
public class SignJob implements Job {
    private WlyyQuotaVO wlyyQuota;//指标对象
    private WlyyJobConfigVO wlyyJobConfig;//配置对象
    @Autowired
    private QuartzJobLogDao quartzJobLogDao;//执行日志Dao
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private Level1Role levelRole;
    @Autowired
    private Level2Role level2Role;
    @Autowired
    private DBStorage dbStorage;
    @Autowired
    private SignDataFilter signDataFilter;
    @Autowired
    private CachePool cachePool;

    String yesterday;
    String daybefore;

    @Override
    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        try{
            SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
            //初始化参数
            JobDataMap map = context.getJobDetail().getJobDataMap();
            wlyyQuota = (WlyyQuotaVO) map.get("quota");
            wlyyJobConfig = (WlyyJobConfigVO) map.get("jobConfig");
            daybefore = StringUtils.isEmpty(map.get("daybefore")) ? SignJob.getDayString(-2) : map.get("daybefore").toString();
            yesterday = StringUtils.isEmpty(map.get("yesterday")) ? SignJob.getDayString(-1) : map.get("yesterday").toString();
            String level1 = wlyyQuota.getLevel1();//得到一级维度
            String level2 = wlyyQuota.getLevel2();//得到二级维度
            //如果一级维度为空 不进行统计
            if (!StringUtils.isEmpty(level1)) {
                if (StringUtils.isEmpty(level2)) {
                    //線刪除今天的数据
                    //2级维度是空按照一级的机构唯独计算指标
                    computequota();
                } else {
                    switch (level2) {
                        case "1": {
                            //線刪除今天的数据
                            //患者性别
                            computequotaByPatientSex();
                            break;
                        }
                        case "2": {
                            //患者分组
                            computequotaByPatientGroup();
                            break;
                        }
                        case "3": {
                            //患者年龄
                            computequotaByPatientAge();
                            break;
                        }
                    }
                }
            }
        }catch (Exception e){
            //如果出錯立即重新執行
            JobExecutionException e2 =new JobExecutionException(e);
            e2.setRefireImmediately(true);
        }
    }

    /**
     * 机构维度下患者性别维度计算指标
     */
    @Transactional
    private void computequotaByPatientSex() {

        jdbcTemplate.execute("delete from wlyy_quota_result where quota_date='" + yesterday + "' and quato_code='" + 6 + "'");
        try{
            //新建任务日志对象
            QuartzJobLog quartzJobLog = new QuartzJobLog();
            quartzJobLog.setJobStartTime(new Date());
            quartzJobLog.setJobId(wlyyJobConfig.getId());
            quartzJobLog.setJobName(wlyyJobConfig.getJobName());
            //从缓存取数据
            CacheModel cacheModel=cachePool.getSignFamilysWithExpenseStatus1ByDate(yesterday);
            //清洗數據
            FilterModel etlModels= signDataFilter.filter(cacheModel.getSignFamilies(),SignDataFilter.level2Sex,cacheModel.getSql(),yesterday);
            //统计数据 1级维度
            List<Map<String, List<ETLModel>>>  returnDatas= levelRole.elt(etlModels.getEtlModelList());
            //统计数据 二级维度
            List<Map<String, Map<String, List<ETLModel>>>>  level2Data= level2Role.elt(returnDatas);;
                //保存数据
            dbStorage.saveByLevel2(level2Data,yesterday,wlyyQuota,3,1);
            //保存日志
            quartzJobLog.setJobEndTime(new Date());
            quartzJobLog.setJobContent(JsonUtil.objToStr(etlModels.getLogModel()));
            quartzJobLog.setJobType(etlModels.getError()?"1":"0");
            quartzJobLogDao.save(quartzJobLog);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * 机构维度患者分组维度计算指标
     */
    @Transactional
    private void computequotaByPatientGroup() {
        try{
            jdbcTemplate.execute("delete from wlyy_quota_result where quota_date='"+yesterday+"' and quato_code='"+7+"'");
            //新建任务日志对象
            QuartzJobLog quartzJobLog = new QuartzJobLog();
            quartzJobLog.setJobStartTime(new Date());
            quartzJobLog.setJobId(wlyyJobConfig.getId());
            quartzJobLog.setJobName(wlyyJobConfig.getJobName());

            //找出今天的解约信息
            //String sql=" select code,idcard,hospital,admin_team_code,patient from wlyy_sign_family a where  a.type =2 and   a.expenses_time< '"+yesterday+ Constant.quota_date_last+"' and a.expenses_status=1 ";
            //抽取數據
            //List<SignFamily> signFamilies= dbExtract.extract(SignFamily.class,sql);
            //从缓存取数据
            CacheModel cacheModel=cachePool.getSignFamilysWithExpenseStatus1ByDate(yesterday);
            //清洗數據
            FilterModel etlModels= signDataFilter.filter(cacheModel.getSignFamilies(),SignDataFilter.level2Group,cacheModel.getSql(),yesterday);
            //统计数据 1级维度
            List<Map<String, List<ETLModel>>>  returnDatas= levelRole.elt(etlModels.getEtlModelList());
            //统计数据 二级维度
            List<Map<String, Map<String, List<ETLModel>>>>  level2Data= level2Role.elt(returnDatas);
            //保存数据 1 表示：从1开始循环 6表示：循环6次 3表示 2级维度是 3
             dbStorage.saveByLevel2(level2Data,yesterday,wlyyQuota,7,3,-1);
            //dbStorage.saveByLevel2(level2Data,yesterday,wlyyQuota,6,3,-1);

            //保存日志
            quartzJobLog.setJobEndTime(new Date());
            quartzJobLog.setJobContent(JsonUtil.objToStr(etlModels.getLogModel()));
            quartzJobLog.setJobType(etlModels.getError()?"1":"0");
            quartzJobLogDao.save(quartzJobLog);
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    /**
     * 机构维度患者年龄维度计算指标
     */
    @Transactional
    private void computequotaByPatientAge() {
        try {
            jdbcTemplate.execute("delete from wlyy_quota_result where quota_date='" + yesterday + "' and quato_code='" + 8 + "'");
            //新建任务日志对象
            QuartzJobLog quartzJobLog = new QuartzJobLog();
            quartzJobLog.setJobStartTime(new Date());
            quartzJobLog.setJobId(wlyyJobConfig.getId());
            quartzJobLog.setJobName(wlyyJobConfig.getJobName());
            //从缓存取数据
            CacheModel cacheModel=cachePool.getSignFamilysWithExpenseStatus1ByDate(yesterday);
            //清洗數據
            FilterModel etlModels= signDataFilter.filter(cacheModel.getSignFamilies(),SignDataFilter.level2Age,cacheModel.getSql(),yesterday);
            //统计数据 1级维度
            List<Map<String, List<ETLModel>>>  returnDatas= levelRole.elt(etlModels.getEtlModelList());
            //统计数据 二级维度
            List<Map<String, Map<String, List<ETLModel>>>>  level2Data= level2Role.elt(returnDatas);;
            //保存数据
            dbStorage.saveByLevel2(level2Data,yesterday,wlyyQuota,6,2);
            //保存日志
            quartzJobLog.setJobEndTime(new Date());;
            quartzJobLog.setJobContent(JsonUtil.objToStr(etlModels.getLogModel()));
            quartzJobLog.setJobType(etlModels.getError()?"1":"0");
            quartzJobLogDao.save(quartzJobLog);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 机构维度计算指标
     */
    @Transactional
    private void computequota() {
        try{
            jdbcTemplate.execute("delete from wlyy_quota_result where quota_date='" + yesterday + "' and quato_code='" + 1 + "'");
            //新建任务日志对象
            QuartzJobLog quartzJobLog = new QuartzJobLog();
            quartzJobLog.setJobStartTime(new Date());
            quartzJobLog.setJobId(wlyyJobConfig.getId());
            quartzJobLog.setJobName(wlyyJobConfig.getJobName());
            //找出今天的签约信息 yesterday,now
           // String sql=" select code,idcard,hospital,admin_team_code from wlyy_sign_family a where  a.type =2 and  a.expenses_time< '"+yesterday+ Constant.quota_date_last+"' and a.expenses_status=1 ";
            //抽取數據
           // List<SignFamily> signFamilies= dbExtract.extract(SignFamily.class,sql);
            //从缓存取数据
            CacheModel cacheModel=cachePool.getSignFamilysWithExpenseStatus1ByDate(yesterday);
            //清洗數據
            FilterModel etlModels= signDataFilter.filter(cacheModel.getSignFamilies(),cacheModel.getSql(),yesterday);
            //统计数据
            List<Map<String, List<ETLModel>>>  returnDatas= levelRole.elt(etlModels.getEtlModelList());
            //保存数据
            dbStorage.saveByLevel1(returnDatas,yesterday,wlyyQuota);
            //保存日志
            quartzJobLog.setJobEndTime(new Date());
            quartzJobLog.setJobContent(JsonUtil.objToStr(etlModels.getLogModel()));
            quartzJobLog.setJobType(etlModels.getError()?"1":"0");
            quartzJobLogDao.save(quartzJobLog);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /*
    得到昨天的日期字符串  yyyy-MM-dd
     */
    public String getYesterday() {
        return yesterday;
    }

    public static String getDayString(Integer size) {
        Date date = new Date();//取时间
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE, size);//把日期往后增加一天.整数往后推,负数往前移动
        date = calendar.getTime(); //这个时间就是日期往后推一天的结果
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(date);
        return dateString;
    }

}
