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

import com.yihu.wlyy.statistics.dao.QuartzJobLogDao;
import com.yihu.wlyy.statistics.etl.dataFilter.ConsultDataFilter;
import com.yihu.wlyy.statistics.etl.extract.DBExtract;
import com.yihu.wlyy.statistics.etl.model.ETLModel;
import com.yihu.wlyy.statistics.etl.model.FilterModel;
import com.yihu.wlyy.statistics.etl.role.Level1Role;
import com.yihu.wlyy.statistics.etl.storage.DBStorage;
import com.yihu.wlyy.statistics.model.consult.ConsultTeam;
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.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 javax.annotation.Resource;
import javax.sql.DataSource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Calendar;

/**
 * 咨询模块
 * 及时回复的指标执行类
 */
@Component
@Scope("prototype")
@DisallowConcurrentExecution//防止到了执行时间点前一任务还在执行中，但是这时有空闲的线程，那么马上又会执行，这样一来就会存在同一job被并行执行
public class ReyConsultJob implements Job {

    private WlyyQuotaVO wlyyQuota;//指标对象
    private WlyyJobConfigVO wlyyJobConfig;//配置对象
    @Autowired
    private QuartzJobLogDao quartzJobLogDao;//执行日志Dao
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private Level1Role levelRole;
    @Autowired
    private DBStorage dbStorage;
    @Autowired
    private ConsultDataFilter consultDataFilter;
    @Autowired
    private DBExtract dbExtract;
    //im库的jdbcTemplate
    private JdbcTemplate imjdbcTemplate;

    @Resource(name="imData")
    private DataSource dataSource;

    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");

            //初始化im数据源
            this.imjdbcTemplate = new JdbcTemplate();
            this.imjdbcTemplate.setDataSource(dataSource);

            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();  //線刪除今天的数据
            //计算指标
            computequota();
        } catch (Exception e) {
            //如果出錯立即重新執行
            JobExecutionException e2 = new JobExecutionException(e);
            e2.setRefireImmediately(true);
        }
    }

    @Transactional
    private void computequota() {
        try {
            jdbcTemplate.execute("delete from wlyy_quota_result where quota_date='" + yesterday + "' and quato_code='" + 23 + "'");

            //新建任务日志对象
            QuartzJobLog quartzJobLog = new QuartzJobLog();
            quartzJobLog.setJobStartTime(new Date());
            quartzJobLog.setJobId(wlyyJobConfig.getId());
            quartzJobLog.setJobName(wlyyJobConfig.getJobName());
            //查找Im库中的所有的医生ID
            List<String> consultIdMaps = getConsultIdsByIm();
            StringBuffer sb=new StringBuffer("");

            List<ConsultTeam> consultTeams = new ArrayList<>();
            for(int i=0;i<consultIdMaps.size();i++){
                sb.append(consultIdMaps.get(i));
                if(i<(consultIdMaps.size()-1)){
                    sb.append(",");
                }
                if ((1+1) % 100 == 0) {
                    //每隔100统计一次
                    String sql = " select admin_team_code,id,consult from wlyy_consult_team a where  a.czrq< '" + yesterday + Constant.quota_date_last + "' and a.czrq >'"+Constant.getStartTimeByDate(yesterday)+"' and a.consult in (" + sb.toString() + ")";
                    //抽取數據
                    List<ConsultTeam> consultTeamsTemp = dbExtract.extract(ConsultTeam.class, sql);
                    consultTeams.addAll(consultTeamsTemp);
                    sb = new StringBuffer();//重置 in条件
                }else{
                    //判断是不是最后的剩下一端不能被100整除的
                    if(consultIdMaps.size()==(i+1)){
                        String sql = " select admin_team_code,id,consult from wlyy_consult_team a where  a.czrq< '" + yesterday + Constant.quota_date_last + "' and a.czrq >'"+Constant.getStartTimeByDate(yesterday)+"' and a.consult in (" + sb.toString() + ")";
                        //抽取數據
                        List<ConsultTeam> consultTeamsTemp = dbExtract.extract(ConsultTeam.class, sql);
                        consultTeams.addAll(consultTeamsTemp);
                    }
                }
            }

            String sql ="";
            if(consultIdMaps.size()>0){
                sql = " select admin_team_code,id,consult from wlyy_consult_team a where  a.czrq< '" + yesterday + Constant.quota_date_last + "' and a.czrq >'"+Constant.getStartTimeByDate(yesterday)+"' and a.consult in ("+sb.toString()+")";
            }else{
                sql = " select admin_team_code,id,consult from wlyy_consult_team a where  a.czrq< '" + yesterday + Constant.quota_date_last + "' and a.czrq >'"+Constant.getStartTimeByDate(yesterday)+"' and a.consult ='noRey' ";
            } //抽取數據

            System.out.println("consultTeams num"+consultTeams.size());
            //過濾數據
            FilterModel etlModels = consultDataFilter.filter(consultTeams, sql, 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();
        }
    }


    public String getYesterday() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        String yesterday = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
        return yesterday;
    }

    /**
     * 找出 im中的及时回复的topic
     * 名医有算 求助没有
     * @return
     */
    public List<String> getConsultIdsByIm() throws Exception {
        String sql = "SELECT DISTINCT t.id consultId " +
                " FROM " +
                " topics t, " +
                " participants p, " +
                " doctors d ," +
                " sessions s " +
                " WHERE " +
                " p.participant_id = d.id " +
                " AND t.session_id = p.session_id " +
                " AND t.session_id = s.id " +
                " AND s.business_type=2 " +
                " AND t.`reply`=1 " +
                " AND TIMESTAMPDIFF(SECOND  ,t.create_time,t.reply_time) <86400 AND TIMESTAMPDIFF(SECOND  ,t.create_time,t.reply_time) >0 "+
                " AND t.create_time< '" + yesterday + Constant.quota_date_last + "' " +
                " And t.create_time>'"+Constant.getStartTimeByDate(yesterday)+"'";
        List<Map<String, Object>> ims = imjdbcTemplate.queryForList(sql);
        //得到医生的id
        List<String> ids = new ArrayList<>();
        ims.stream().forEach(map -> {
            if (map.containsKey("consultId")) {
                ids.add("'"+ String.valueOf(map.get("consultId"))+"'");
            }
        });
        System.out.println("ims num:"+ims.size());
        System.out.println("sql:"+sql);
        System.out.println("ids num:"+ids.size());
        return ids;
    }
}
