package com.yihu.jw.hospital.prescription.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.jw.doctor.dao.BaseDoctorDao;
import com.yihu.jw.doctor.dao.BaseDoctorHospitalDao;
import com.yihu.jw.doctor.service.excel.DoctorWorkTimeExcelDO;
import com.yihu.jw.doctor.service.excel.DoctorWorkTimeMainExcelDO;
import com.yihu.jw.entity.base.doctor.BaseDoctorDO;
import com.yihu.jw.entity.base.org.BaseOrgDO;
import com.yihu.jw.entity.hospital.consult.WlyyHospitalSysDictDO;
import com.yihu.jw.entity.hospital.doctor.WlyyDoctorWorkTimeDO;
import com.yihu.jw.entity.hospital.prescription.WlyyHospitalWorkRuleDO;
import com.yihu.jw.hospital.dict.WlyyHospitalSysDictDao;
import com.yihu.jw.hospital.doctor.dao.DoctorWorkTimeDao;
import com.yihu.jw.hospital.prescription.dao.WlyyHospitalWorkRuleDao;
import com.yihu.jw.org.dao.BaseOrgDao;
import com.yihu.jw.util.date.DateUtil;
import com.yihu.jw.utils.StringUtil;
import com.yihu.jw.utils.hibernate.HibenateUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Created by Trick on 2020/3/24.
 */
@Service
@Transactional
public class WorkTimeService {

    private static final Logger logger = LoggerFactory.getLogger(WorkTimeService.class);

    @Autowired
    private WlyyHospitalWorkRuleDao wlyyHospitalWorkRuleDao;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private DoctorWorkTimeDao doctorWorkTimeDao;

    @Autowired
    private HibenateUtils hibenateUtils;

    @Autowired
    private BaseDoctorDao baseDoctorDao;

    @Autowired
    private BaseDoctorHospitalDao hospitalDao;

    @Autowired
    private BaseOrgDao baseOrgDao;
    @Autowired
    private WlyyHospitalSysDictDao wlyyHospitalSysDictDao;

    /**
     * 保存排班规则
     * @param workTimeRuleJson
     * @return
     * @throws Exception
     */
    public WlyyHospitalWorkRuleDO saveWorkTimeRule(String workTimeRuleJson,String isDoctorWork) throws Exception{
        WlyyHospitalWorkRuleDO ruleDO = objectMapper.readValue(workTimeRuleJson,WlyyHospitalWorkRuleDO.class);
        List<WlyyHospitalWorkRuleDO> orgRules = wlyyHospitalWorkRuleDao.findByHospital(ruleDO.getHospital());
        if(orgRules!=null&&orgRules.size()>0){
            wlyyHospitalWorkRuleDao.delete(orgRules);
        }
        wlyyHospitalWorkRuleDao.save(ruleDO);
        if (StringUtils.isNoneBlank(isDoctorWork)){
            JSONArray jsonArray = JSONArray.parseArray(isDoctorWork);
            if (jsonArray!=null&&jsonArray.size()>0){
                for(int i=0;i<jsonArray.size();i++){
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    WlyyHospitalSysDictDO wlyyHospitalSysDictDO = wlyyHospitalSysDictDao.findById(jsonObject.getString("id"));
                    if (wlyyHospitalSysDictDO!=null&&StringUtils.isNoneBlank(jsonObject.get("value")==null?"":jsonObject.getString("value"))){
                        wlyyHospitalSysDictDO.setDictValue(jsonObject.getString("value"));
                        wlyyHospitalSysDictDao.save(wlyyHospitalSysDictDO);
                    }
                }
            }
        }
        return ruleDO;
    }

    /**
     * 获取医院排班规则
     * @param hospital
     * @return
     */
    public WlyyHospitalWorkRuleDO findWorkTimeRule(String hospital){
        List<WlyyHospitalWorkRuleDO> orgRules = wlyyHospitalWorkRuleDao.findByHospital(hospital);
        if(orgRules!=null&&orgRules.size()>0){
            return orgRules.get(0);
        }
        return null;
    }

    /**
     * 判断医生是否在班
     * @param doctor
     * @return
     */
    public Boolean checkDoctorWork(String doctor,String ywCode){
        logger.info("当前判断的业务Code:"+ywCode);
        if (StringUtils.isNoneBlank(ywCode)){
            if (ywCode.contains(",")){
                String[] split = ywCode.split(",");
                Integer j =0;
                for (int i = 0;i<split.length;i++){
                    WlyyHospitalSysDictDO wlyyHospitalSysDictDO = wlyyHospitalSysDictDao.findById(split[i]);
                    String isCheckDoctorWork = "";
                    if (wlyyHospitalSysDictDO!=null){
                        isCheckDoctorWork = wlyyHospitalSysDictDO.getDictValue();
                    }
                    if ("1".equalsIgnoreCase(isCheckDoctorWork)){
                        String sql = "SELECT " +
                                " d.id " +
                                " FROM " +
                                " base_doctor d " +
                                " WHERE " +
                                " d.id =:doctor " +
                                " AND ( " +
                                " EXISTS ( " +
                                "  SELECT " +
                                "   t.id " +
                                "  FROM " +
                                "   wlyy_doctor_work_time t " +
                                "  WHERE " +
                                "   t.doctor = d.id " +
                                "  AND t.start_time <=:startTime " +
                                "  AND t.end_time >=:endTime" +
                                " ) " +
                                " OR d.consult_status = '1' " +
                                ")";
                        Map<String,Object> params = new HashedMap();
                        params.put("doctor",doctor);
                        Date date = new Date();
                        params.put("startTime",date);
                        params.put("endTime",date);
                        List<Map<String,Object>> list = hibenateUtils.createSQLQuery(sql,params);
                        if(list!=null&&list.size()>0){
                            j++;
                        }
                    }else {
                        j++;
                    }
                }
                if (j>=1){
                    return true;
                }else {
                    return false;
                }
            }else {
                WlyyHospitalSysDictDO wlyyHospitalSysDictDO = wlyyHospitalSysDictDao.findById(ywCode);
                String isCheckDoctorWork = "1";
                if (wlyyHospitalSysDictDO!=null){
                    isCheckDoctorWork = wlyyHospitalSysDictDO.getDictValue();
                }
                if ("1".equalsIgnoreCase(isCheckDoctorWork)){
                    String sql = "SELECT " +
                            " d.id " +
                            " FROM " +
                            " base_doctor d " +
                            " WHERE " +
                            " d.id =:doctor " +
                            " AND ( " +
                            " EXISTS ( " +
                            "  SELECT " +
                            "   t.id " +
                            "  FROM " +
                            "   wlyy_doctor_work_time t " +
                            "  WHERE " +
                            "   t.doctor = d.id " +
                            "  AND t.start_time <=:startTime " +
                            "  AND t.end_time >=:endTime" +
                            " ) " +
                            " OR d.consult_status = '1' " +
                            ")";
                    Map<String,Object> params = new HashedMap();
                    params.put("doctor",doctor);
                    Date date = new Date();
                    params.put("startTime",date);
                    params.put("endTime",date);
                    List<Map<String,Object>> list = hibenateUtils.createSQLQuery(sql,params);
                    if(list!=null&&list.size()>0){
                        return true;
                    }else {
                        return false;
                    }
                }else {
                    return true;
                }
            }
        }else {
            String sql = "SELECT " +
                    " d.id " +
                    " FROM " +
                    " base_doctor d " +
                    " WHERE " +
                    " d.id =:doctor " +
                    " AND ( " +
                    " EXISTS ( " +
                    "  SELECT " +
                    "   t.id " +
                    "  FROM " +
                    "   wlyy_doctor_work_time t " +
                    "  WHERE " +
                    "   t.doctor = d.id " +
                    "  AND t.start_time <=:startTime " +
                    "  AND t.end_time >=:endTime" +
                    " ) " +
                    " OR d.consult_status = '1' " +
                    ")";
            Map<String,Object> params = new HashedMap();
            params.put("doctor",doctor);
            Date date = new Date();
            params.put("startTime",date);
            params.put("endTime",date);
            List<Map<String,Object>> list = hibenateUtils.createSQLQuery(sql,params);
            if(list!=null&&list.size()>0){
                return true;
            }
        }
        return false;
    }

    public Map<String,Object> getExcelWorkInfo(List<DoctorWorkTimeMainExcelDO> list,String date,String hospital){

        Map<String,Object> rs = new HashedMap();
        List<DoctorWorkTimeMainExcelDO> error =new ArrayList<>();
        List<WlyyDoctorWorkTimeDO> succ = new ArrayList<>();
        Integer total = 0;
        Integer errorTotal = 0;
        Integer succTotal =0;
        if(list!=null&&list.size()>0){
            for(DoctorWorkTimeMainExcelDO excelDO:list){
                List<BaseDoctorDO> doctorDOs = baseDoctorDao.findByIdcard(excelDO.getIdCard());
                if(doctorDOs==null||doctorDOs.size()==0){
                    excelDO.setErrorMes("第"+(excelDO.getRow()+1)+"行，医生身份证号不存在！");
                    error.add(excelDO);
                    continue;
                }

                BaseDoctorDO doctorDO = doctorDOs.get(0);
                BaseOrgDO orgDO = baseOrgDao.findByCode(hospital);
                WlyyHospitalWorkRuleDO ruleDO = findWorkTimeRule(hospital);

                //判断是否为本月
                String dm = DateUtil.dateToStr(new Date(),"yyyy-MM");
                if(dm.equals(date)){
                    Calendar calendar = Calendar.getInstance();
                    Date today = new Date();
                    calendar.setTime(today);
                    // 获取一月中第几天
                    int monthDay = calendar.get(Calendar.DAY_OF_MONTH);
                    //获取该月份一共几天
                    int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
                    calendar.add(1,Calendar.DATE);

                    //更新时间范围
                    //开始时间
                    String st = DateUtil.dateToStr(calendar.getTime(),"yyyy-MM-dd");
                    Date startDate = DateUtil.strToDate(st+" 00:00:00");
                    //结束时间
                    String et = date+":"+maxDay+" 23:59:59";
                    Date endDate = DateUtil.strToDate(et);

                    //删除明天开始的排班记录
                    List<WlyyDoctorWorkTimeDO> timeDOs = doctorWorkTimeDao.findDoctorWorkTimeByTime(doctorDO.getId(),startDate,endDate);
                    if(timeDOs!=null&&timeDOs.size()>0){
                        doctorWorkTimeDao.delete(timeDOs);
                    }
                    //解析具体排班
                    List<DoctorWorkTimeExcelDO> worktimes = excelDO.getWorkTime();
                    if(worktimes!=null&&worktimes.size()>0){
                        for(DoctorWorkTimeExcelDO worktime:worktimes){
                            //要排班的日期
                            String day = worktime.getDateOfMonth();
                            Integer dfm = Integer.parseInt(day);
                            //排班从明天开始
                            if(dfm >= (monthDay+1)){
                                WlyyDoctorWorkTimeDO workTimeDO = getWorkTimeDO(date,worktime,ruleDO,orgDO,doctorDO);
                                succ.add(workTimeDO);
                            }
                        }
                    }
                }else{
                    //判断日期是否大于本月
                    Date now = DateUtil.strToDate(dm,"yyyy-MM");
                    Date work = DateUtil.strToDate(date,"yyyy-MM");
                    if(now.before(work)){

                        //导入的月份大于当前月份，删除导入月份所有历史排班记录
                        List<WlyyDoctorWorkTimeDO> timeDOs = doctorWorkTimeDao.findDoctorWorkTimeByMonth(doctorDO.getId(),"%"+date+"%");
                        if(timeDOs!=null&&timeDOs.size()>0){
                            doctorWorkTimeDao.delete(timeDOs);
                        }
                        //解析具体排班
                        List<DoctorWorkTimeExcelDO> worktimes = excelDO.getWorkTime();
                        if(worktimes!=null&&worktimes.size()>0){
                            for(DoctorWorkTimeExcelDO worktime:worktimes){
                                WlyyDoctorWorkTimeDO workTimeDO = getWorkTimeDO(date,worktime,ruleDO,orgDO,doctorDO);
                                succ.add(workTimeDO);
                            }
                        }

                    }
                }

            }
            total = list.size();
            if(error!=null&&error.size()>0){
                errorTotal = error.size();
            }
            succTotal = total-errorTotal;

            if(succ!=null&&succ.size()>0){
                //保存排班
                doctorWorkTimeDao.save(succ);
            }

        }



        rs.put("error",error);
        rs.put("succ",succ);
        rs.put("total",total);
        rs.put("errorTotal",errorTotal);
        rs.put("succTotal",succTotal);

        return rs;
    }

    public WlyyDoctorWorkTimeDO getWorkTimeDO(String date,DoctorWorkTimeExcelDO worktime,WlyyHospitalWorkRuleDO ruleDO,BaseOrgDO orgDO,BaseDoctorDO doctorDO){
        WlyyDoctorWorkTimeDO workTimeDO = new WlyyDoctorWorkTimeDO();

        workTimeDO.setDoctor(doctorDO.getId());
        workTimeDO.setDoctorName(doctorDO.getName());
        workTimeDO.setHospital(orgDO.getCode());
        workTimeDO.setHospitalName(orgDO.getName());

        String day = worktime.getDateOfMonth();
        if(day.length()<2){
            day ="0"+day;
        }

        String workDate = date+"-"+day;
        logger.info("workDate:"+workDate);
        workTimeDO.setDate(workDate);
        workTimeDO.setCreateTime(new Date());

        //上午
        if("1".equals(worktime.getType())){

            workTimeDO.setTimeType("1");
            workTimeDO.setType("1");
            workTimeDO.setSourceNumber(ruleDO.getSwSourceNum());
            workTimeDO.setStartTime(DateUtil.strToDate(workDate+" "+ruleDO.getSwStartTime()+":00"));
            workTimeDO.setEndTime(DateUtil.strToDate(workDate+" "+ruleDO.getSwEndTime()+" :00"));

        }else if("2".equals(worktime.getType())){

            workTimeDO.setTimeType("2");
            workTimeDO.setType("1");
            workTimeDO.setSourceNumber(ruleDO.getXwSourceNum());
            workTimeDO.setStartTime(DateUtil.strToDate(workDate+" "+ruleDO.getXwStartTime()+":00"));
            workTimeDO.setEndTime(DateUtil.strToDate(workDate+" "+ruleDO.getXwEndTime()+" :00"));

        }else if("3".equals(worktime.getType())){

            workTimeDO.setTimeType("3");
            workTimeDO.setType("1");
            workTimeDO.setSourceNumber(ruleDO.getWsSourceNum());
            workTimeDO.setStartTime(DateUtil.strToDate(workDate+" "+ruleDO.getWsStartTime()+":00"));
            workTimeDO.setEndTime(DateUtil.strToDate(workDate+" "+ruleDO.getWsEndTime()+":00"));
        }
        return workTimeDO;
    }

//    public String saveDoctorWorkTime(List<WlyyDoctorWorkTimeDO> workTimeDOs){
//
//    }





//    public static void main(String ag[]){
//
////        Date start = DateUtil.stringToDate("2020-03-24 08:00:00","yyyy-MM-dd HH:mm:ss");
////
////        Date end = DateUtil.stringToDate("2020-03-24 12:00:00","yyyy-MM-dd HH:mm:ss");
////
////        Long total =end.getTime()-start.getTime();
////
////        Long jg = total/100;
////
////        start.setTime(start.getTime()+jg);
//
////        Date now = DateUtil.strToDate("2020-04","yyyy-MM");
////        Date work = DateUtil.strToDate("2020-04","yyyy-MM");
//
//        Calendar calendar = Calendar.getInstance();
//        Date today = new Date();
//        calendar.setTime(today);// 此处可换为具体某一时间
//        int monthDay = calendar.get(Calendar.DAY_OF_MONTH);
//        int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
//
//        System.out.println(monthDay);
//    }
    public String  findChargeTypeByDoctor(String doctor,String chargeType){
        JSONObject jsonObject = new JSONObject();
        String sqlCharge = "SELECT\n" +
                "\tt.id as \"id\",\n" +
                "\tt.name as \"name\",\n" +
                "\tt.idcard as \"idcard\",\n" +
                "\tm.req_fee as \"twfzFee\",\n" +
                "\ta.req_fee as \"spfzFee\",\n" +
                "\tb.req_fee as \"spzxFee\",\n" +
                "\tv.req_fee as \"twzxFee\",\n" +
                "\tg.req_fee as \"jyzxFee\",\n" +
                "\td.req_fee as \"xtzxFee\"\n" +
                "FROM\n" +
                "\tbase_doctor t\n" +
                "LEFT JOIN wlyy_charge_dict m ON t.twfz_charge_type = m.charge_type and m.is_del='1'\n" +
                "LEFT JOIN wlyy_charge_dict a ON t.spfz_charge_type = a.charge_type and a.is_del='1'\n" +
                "LEFT JOIN wlyy_charge_dict b ON t.spzx_charge_type = b.charge_type and b.is_del='1'\n" +
                "LEFT JOIN wlyy_charge_dict v ON t.twzx_charge_type = v.charge_type and v.is_del='1'\n" +
                "LEFT JOIN wlyy_charge_dict d ON t.twzx_charge_type = d.charge_type and d.is_del='1'\n" +
                " LEFT JOIN wlyy_charge_dict g ON t.jyzx_charge_type = g.charge_type and g.is_del='1'\n" +
                "WHERE t.id = '"+doctor+"' ";
        List<Map<String,Object>> list = hibenateUtils.createSQLQuery(sqlCharge);
        String chargeFee="";
       if (list!=null&&list.size()>0){
           Map<String,Object> map = list.get(0);
           if (StringUtils.isNoneBlank(chargeType)){
               System.out.println("=="+map.get("spfzFee"));
               chargeFee= map.get(chargeType)==null?"":map.get(chargeType).toString();
           }
       }
        return chargeFee;
    }


}
