package com.yihu.wlyy.job;

import com.yihu.wlyy.entity.organization.Hospital;
import com.yihu.wlyy.entity.address.Town;
import com.yihu.wlyy.entity.job.QuartzJobLog;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.entity.statistics.WlyyQuotaResult;
import com.yihu.wlyy.repository.address.TownDao;
import com.yihu.wlyy.repository.job.QuartzJobLogDao;
import com.yihu.wlyy.repository.organization.HospitalDao;
import com.yihu.wlyy.repository.patient.SignFamilyDao;
import com.yihu.wlyy.repository.statistics.WlyyQuotaResultDao;
import com.yihu.wlyy.util.IdCardUtil;
import com.yihu.wlyy.web.quota.WlyyJobConfigVO;
import com.yihu.wlyy.web.quota.WlyyQuotaVO;
import org.json.JSONArray;
import org.json.JSONObject;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
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.*;

/**
 * 签约下按年龄分组后再按疾病统计
 */
@Component
public class SignAgeGroupDiseaseJob implements Job {
    private WlyyQuotaVO wlyyQuota;//指标对象
    private WlyyJobConfigVO wlyyJobConfig;//配置对象
    @Autowired
    private WlyyQuotaResultDao wlyyQuotaResultDao;//指标结果Dao
    @Autowired
    private QuartzJobLogDao quartzJobLogDao;//执行日志Dao
    @Autowired
    private SignFamilyDao signFamilyDao;
    @Autowired
    private HospitalDao hospitalDao;
    @Autowired
    private TownDao townDao;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private StringRedisTemplate redisTemplate;

    String yesterday;
    String now;

    @Override
    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        //初始化参数
        JobDataMap map = context.getJobDetail().getJobDataMap();
        wlyyQuota = (WlyyQuotaVO) map.get("quota");
        wlyyJobConfig = (WlyyJobConfigVO) map.get("jobConfig");
        now = StringUtils.isEmpty(map.get("now")) ? SignAgeGroupDiseaseJob.getDayString(0) : map.get("now").toString();
        yesterday = StringUtils.isEmpty(map.get("yesterday")) ? SignAgeGroupDiseaseJob.getDayString(-1) : map.get("yesterday").toString();

        computequotaByPatientAge();
    }
    /**
     * 机构维度患者年龄维度计算指标
     */
    @Transactional
    private void computequotaByPatientAge() {
        try {
            jdbcTemplate.execute("delete from wlyy_quota_result where quota_date='"+yesterday+"' and quato_code='"+12+"'");
            //新建任务日志对象
            QuartzJobLog wlyyJobLog = new QuartzJobLog();
            wlyyJobLog.setJobStartTime(new Date());
            wlyyJobLog.setJobId(wlyyJobConfig.getId());
            wlyyJobLog.setJobName(wlyyJobConfig.getJobName());
            //查找出系统全部的机构
            List<Hospital> hospitals = hospitalDao.findHospital2();
            Map<String, Hospital> hospitalsMap = new HashMap<String, Hospital>();
            for (Hospital hospital : hospitals) {
                hospitalsMap.put(hospital.getCode(), hospital);
            }
            //查找出厦门市全部的区
            List<Town> towns = townDao.findByCityCode(Constant.city);
            Map<String, Town> townsMap = new HashMap<String, Town>();
            for (Town town : towns) {
                townsMap.put(town.getCode(), town);
            }
            //找出今天的签约信息
            List<SignFamily> signFamilies = signFamilyDao.findByJiatingSignYesterday(yesterday, now);
            //数组里面第一个是健康人群 第二个是慢病人群 第三个是65岁以上人群
            Map<String, Map<String, Map>> cityAgeMap = new HashMap<String, Map<String, Map>>();//key是市行政代码 目前只有厦门市
            Map<String,Map> temp =new HashMap<String,Map>();
            cityAgeMap.put(Constant.city, temp);

            Map<String, Map<String, Map>> townAgeMap = new HashMap<String, Map<String, Map>>();//key是区行政代码
            Map<String, Map<String, Map>> orgAgeMap = new HashMap<String, Map<String, Map>>();//key是机构代码
            //统计有签约的
            String orgCodeTemp="";
            for (SignFamily signFamily : signFamilies) {
                orgCodeTemp=signFamily.getHospital();
                if(!"00".equals(orgCodeTemp.substring(orgCodeTemp.length()-2,orgCodeTemp.length()))){
                    //统计站
                    orgCodeTemp=orgCodeTemp.substring(0,orgCodeTemp.length()-2)+"00";
                }

                Hospital hospital = hospitalsMap.get(orgCodeTemp);//得到患者签约的机构
                String town = hospital.getTown();
                int age = IdCardUtil.getAgeForIdcard(signFamily.getIdcard());//根据card解析年龄
                String ageCode = getAgeCode(age);//得到年龄的code

                boolean hasGXY = false;//有高血压
                boolean hasTNB = false;//有糖尿病
                //如果是慢病的 统计高血压的 糖尿病  1高血压，2糖尿病  3 糖尿病和高血压 4健康人群数
                String diseaseType="";
                String jsonString = redisTemplate.opsForValue().get("disease:" + signFamily.getPatient());
                if (StringUtils.isEmpty(jsonString)) {
                    diseaseType="4";//健康人群
                }else{
                    //排除数据 只留下高血压和糖尿病
                    List<JSONObject> jsonObjects = new ArrayList<JSONObject>();
                    JSONArray redisValues = new JSONArray(jsonString);
                    if(redisValues.length()>0){
                        for (Object obj : redisValues) {
                            JSONObject redisValue = (JSONObject)(obj);
                            if(!redisValue.has("signType")){
                                continue;
                            }
                            //排除掉三师签约
                            if ("1".equals(redisValue.get("signType").toString())) {
                                continue;
                            }
                            String disease =  redisValue.getString("disease");
                            if ("1".equals(disease)) {
                                jsonObjects.add(redisValue);
                                hasGXY = true;//设置有高血压
                                diseaseType="1";
                            }
                            if ("2".equals(disease)) {
                                jsonObjects.add(redisValue);
                                hasTNB = true;//设置有糖尿病
                                diseaseType="2";
                            }
                        }
                        if(hasGXY&&hasTNB){
                            diseaseType="3";//高血压和糖尿病
                        }
                    }else{
                        diseaseType="4";//健康人群
                    }
                }
                //统计市
                compute(cityAgeMap, Constant.city, ageCode, diseaseType);
                //统计区
                compute(townAgeMap, town, ageCode, diseaseType);
                //统计机构
                //统计站
                String orgCode=hospital.getCode();
                if(!"00".equals(orgCode.substring(orgCode.length()-2,orgCode.length()))){
                    //统计站
                     orgCodeTemp=orgCode.substring(0,orgCode.length()-2)+"00";
                    //统计机构
                    compute(orgAgeMap, orgCodeTemp, ageCode, diseaseType);
                } else {
                    compute(orgAgeMap, hospital.getCode(), ageCode, diseaseType);
                }

            }
            //保存统计数据
            // 保存市的统计数据
            for (Map.Entry<String, Map<String, Map>> entry : cityAgeMap.entrySet()) {
               Map<String, Map> oneAgeMap = entry.getValue();
               for(int i=1;i<7;i++){
                   for(int j=1;j<5;j++){
                       String key_2=i+"";
                       String key_3=j+"";
                       String city=Constant.city;
                       String cityName=Constant.cityName;
                       String town="";
                       String townName="";
                       String org="";
                       String orgName="";
                       save(oneAgeMap, key_2, key_3, city, cityName, town, townName, org, orgName,"4");
                   }
               }
            }
            //保存区级
            for (Map.Entry<String, Town> entry : townsMap.entrySet()) {
                //判断该区是否有统计数据
                Map<String, Map> oneAgeMap = townAgeMap.get(entry.getKey());//得到当个区的统计数据
                Town townObj = entry.getValue();//得到区级信息
                for(int i=1;i<7;i++){
                    for(int j=1;j<5;j++){
                        String key_2=i+"";
                        String key_3=j+"";
                        String city=Constant.city;
                        String cityName=Constant.cityName;
                        String town=townObj.getCode();
                        String townName=townObj.getName();
                        String org="";
                        String orgName="";
                        save(oneAgeMap, key_2, key_3, city, cityName, town, townName, org, orgName,"3");
                    }
                }
            }

            for (Map.Entry<String, Hospital> entry : hospitalsMap.entrySet()) {
                //判断该机构是否有统计数据
                Map<String, Map> oneAgeMap = orgAgeMap.get(entry.getKey());//得到当个机构的统计数据
                Hospital hospital = entry.getValue();//得到机构信息
                for(int i=1;i<7;i++){
                    for(int j=1;j<5;j++){
                        String key_2=i+"";
                        String key_3=j+"";
                        String city=Constant.city;
                        String cityName=Constant.cityName;
                        String town=hospital.getTown();
                        String townName=hospital.getTownName();
                        String org=hospital.getCode();
                        String orgName=hospital.getName();
                        save(oneAgeMap, key_2, key_3, city, cityName, town, townName, org, orgName,"2");
                    }
                }
            }
            wlyyJobLog.setJobEndTime(new Date());
            wlyyJobLog.setJobContent("统计" + getYesterday() + " 的签约患者年龄数据完成,得到签约数目:"+signFamilies.size());
            wlyyJobLog.setJobType("1");
            quartzJobLogDao.save(wlyyJobLog);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void save(Map<String, Map> oneAgeMap, String key_2, String key_3, String city, String cityName, String town, String townName, String org, String orgName,String level) {
        WlyyQuotaResult wlyyQuotaResult = new WlyyQuotaResult();
        wlyyQuotaResult.setDel("1");
        wlyyQuotaResult.setCity(city);
        wlyyQuotaResult.setCityName(cityName);
        wlyyQuotaResult.setTown(town);
        wlyyQuotaResult.setTownName(townName);
        wlyyQuotaResult.setOrgCode(org);
        wlyyQuotaResult.setOrgName(orgName);
        wlyyQuotaResult.setQuatoCode(wlyyQuota.getId());
        wlyyQuotaResult.setQuatoName(wlyyQuota.getName());
        wlyyQuotaResult.setQuotaDate(getYesterday());
        wlyyQuotaResult.setCreateTime(new Date());
        wlyyQuotaResult.setLevel1Type(level);//等级
        wlyyQuotaResult.setLevel2Type(key_2);
        wlyyQuotaResult.setLevel2TypeName(Constant.getLevelAgeName(key_2));
        wlyyQuotaResult.setLevel3Type(key_3);
        wlyyQuotaResult.setLevel3TypeName(Constant.getLevelDiseaseName(key_3));
        if (oneAgeMap != null && oneAgeMap.containsKey(key_2)) {
            Map<String,Long> key3Map=oneAgeMap.get(key_2);
            if(key3Map!=null&&key3Map.containsKey(key_3)){
                wlyyQuotaResult.setResult(key3Map.get(key_3) + "");
            }else{
                wlyyQuotaResult.setResult("0");
            }
        } else {
            wlyyQuotaResult.setResult("0");
        }
        wlyyQuotaResultDao.save(wlyyQuotaResult);
    }

    /**
     * 统计方案
     * @param rootMap 数据存放的map
     * @param rootKey 数据的key 机构 区  市
     * @param ageCode 年龄的key
     * @param diseaseType 疾病类型 1是高血压 2是糖尿病 3是高血压和糖尿病 4是健康人群
     */
    private void compute(Map<String, Map<String, Map>> rootMap, String rootKey, String ageCode, String diseaseType) {
        if (rootMap.containsKey(rootKey)) {
            //得到市下面的所有的年龄map
            Map<String, Map> groupMapTemp = rootMap.get(rootKey);
            if(groupMapTemp.containsKey(ageCode)){
                //得到这个年龄下的患者map
                Map<String,Long> mape= groupMapTemp.get(ageCode);
                if(mape.containsKey(diseaseType)){
                    mape.put(diseaseType,mape.get(diseaseType)+1L); //key是三级维度
                }else{
                    mape.put(diseaseType,1L); //key是三级维度
                }
            }else{
                //新增疾病的统计map
                Map<String, Long> groupMapTemp1 = new HashMap<String, Long>();
                groupMapTemp1.put(diseaseType, 1L);//key是三级维度
                groupMapTemp.put(ageCode,groupMapTemp1);//key是二级维度
            }
        } else {
            //没有就新建统计数据  新增疾病的统计map
            Map<String, Long> groupMapTemp = new HashMap<String, Long>();
            groupMapTemp.put(diseaseType, 1L); //key是三级维度
            //把统计疾病的map放入对应的年龄组map中
            Map<String, Map> groupMapTemp2 = new HashMap<String, Map>();
            groupMapTemp2.put(ageCode,groupMapTemp); //key是二级维度
            //把年龄组map放入市的map里面
            rootMap.put(rootKey, groupMapTemp2); //key是一级维度
        }
    }


    /*
    得到昨天的日期字符串  yyyy-MM-dd
     */
    public String getYesterday() {
        return yesterday;
    }

    /**
     * 根据年龄得到对应的code
     *
     * @param age
     * @return
     */
    public String getAgeCode(int age) {
        if (age < 7) {
            return Constant.level_age_1;
        } else if (age >= 7 && age < 18) {
            return Constant.level_age_2;
        } else if (age >= 18 && age < 30) {
            return Constant.level_age_3;
        } else if (age >= 30 && age < 50) {
            return Constant.level_age_4;
        } else if (age >= 50 && age < 65) {
            return Constant.level_age_5;
        } else {
            return Constant.level_age_6;
        }
    }

    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;
    }
    private String getOrg(String org){
        if(!"00".equals(org.substring(org.length()-2,org.length()))){
            return org.substring(0,org.length()-2)+"00";
        }else{
            return org;
        }
    }
    public static void main(String[] args) {
        getDayString(0);
    }
}
