package cn.hnthyy.thmz.controller.mz;

import cn.hnthyy.thmz.Utils.DateUtil;
import cn.hnthyy.thmz.Utils.TokenUtil;
import cn.hnthyy.thmz.comment.UserLoginToken;
import cn.hnthyy.thmz.common.Constants;
import cn.hnthyy.thmz.entity.his.mz.*;
import cn.hnthyy.thmz.entity.thmz.Clinic;
import cn.hnthyy.thmz.entity.thmz.User;
import cn.hnthyy.thmz.enums.ClinicStatusEnum;
import cn.hnthyy.thmz.enums.GenderEnum;
import cn.hnthyy.thmz.enums.YesNoEnum;
import cn.hnthyy.thmz.service.his.mz.*;
import cn.hnthyy.thmz.service.thmz.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

@Slf4j
@RestController
public class ClinicController {
    @Autowired
    private ClinicService clinicService;
    @Autowired
    private MzVisitTableService mzVisitTableService;
    @Autowired
    private MzPatientMiService mzPatientMiService;
    @Autowired
    private MzyReqrecService mzyReqrecService;
    @Autowired
    private MzDepositFileService mzDepositFileService;
    @Autowired
    private MzfzPatientOrderService mzfzPatientOrderService;
    @Autowired
    private MzyRequestService mzyRequestService;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private HaiCiAdapterService haiCiAdapterService;

    /**
     * 叫号通知
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/clinicCallNumber", method = {RequestMethod.GET})
    public Map<String, Object> clinicCallNumber(@RequestParam("serialNo") String serialNo) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (StringUtils.isBlank(serialNo)) {
                resultMap.put("code", -1);
                resultMap.put("message", "分诊流水号不能为空");
                return resultMap;
            }
            haiCiAdapterService.notify(serialNo, 1);
            resultMap.put("code", 0);
            resultMap.put("message", "叫号通知成功");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "叫号通知出错，请联系管理员");
            log.error("叫号通知异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }


    /**
     * 保存就诊信息 接诊
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/saveClinic", method = {RequestMethod.GET})
    public Map<String, Object> saveClinic(@RequestParam("patientId") String patientId, @RequestParam("serialNo") String serialNo, HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (StringUtils.isBlank(patientId)) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人id不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(serialNo)) {
                resultMap.put("code", -1);
                resultMap.put("message", "分诊流水号不能为空");
                return resultMap;
            }
            MzPatientMi mzPatientMi = mzPatientMiService.queryByPatientId(patientId);
            if (mzPatientMi == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人不存在");
                return resultMap;
            }
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            //快速接诊的时候不知道分诊号
            if("-1".equals(serialNo)){
                MzfzPatientOrder mzfzPatientOrder =new MzfzPatientOrder();
                mzfzPatientOrder.setTableName(MzfzPatientOrder.MZFZ_PATIENT_ORDER);
                mzfzPatientOrder.setPatientId(patientId);
                List<String> deptCodes = mzyRequestService.queryUnitCodeByRequestDayAndDoctor(DateFormatUtils.format(new Date(), "yyyy-MM-dd"), tokenUser.getUserIdCode());
                if (deptCodes == null) {
                    deptCodes = new ArrayList<>();
                }
                //当前医生是急诊科医生，可以看全科室的病人
                if(deptCodes.contains(Constants.EMERGENCY_WARD_CODE)){
                    mzfzPatientOrder.setDeptCodes(Arrays.asList(Constants.EMERGENCY_WARD_CODE));
                }else {
                    mzfzPatientOrder.setDoctorCode(tokenUser.getUserIdCode());
                }
                List<MzfzPatientOrder> mzfzPatientOrderList=mzfzPatientOrderService.queryUnClinicWithPage(mzfzPatientOrder);
                if(mzfzPatientOrderList==null || mzfzPatientOrderList.size()==0){
                    resultMap.put("code", -1);
                    resultMap.put("message", "当前病人没有挂号信息");
                    return resultMap;
                }
                serialNo=mzfzPatientOrderList.get(0).getSerialNo().toString();
            }
            if("null".equals(serialNo)){
                serialNo=null;
            }
            //未接诊的需要变更接诊状态
            if (serialNo!=null && StringUtils.isNotBlank(serialNo)) {
                int num = clinicService.inClinic(patientId, serialNo, tokenUser);
                if (num > 0) {
                    haiCiAdapterService.notify(serialNo, 2);
                }
            }
            resultMap.put("code", 0);
            resultMap.put("message", "接诊成功");
            resultMap.put("data", mzPatientMi);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "接诊出错，请联系管理员");
            log.error("接诊异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }


    /**
     * 根据id查询就诊信息
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getClinicById", method = {RequestMethod.GET})
    public Map<String, Object> getClinicById(@RequestParam("id") Long id) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (id == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询就诊信息失败,参数为空");
                return resultMap;
            }
            resultMap.put("code", 0);
            resultMap.put("message", "查询就诊信息成功");
            resultMap.put("data", clinicService.queryById(id));
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询就诊信息失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询就诊信息失败");
            return resultMap;
        }
    }


    /**
     * 查询就诊记录
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getClinicWithPage", method = {RequestMethod.POST})
    public Map<String, Object> getClinicWithPage(@RequestBody Clinic clinic, HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (clinic == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询就诊记录失败,参数为空");
                return resultMap;
            }
            if (StringUtils.isBlank(clinic.getPatientName())) {
                clinic.setPatientName(null);
            } else {
                clinic.setPatientName("%" + clinic.getPatientName() + "%");
            }
            if (StringUtils.isBlank(clinic.getPatientId())) {
                clinic.setPatientId(null);
            } else {
                clinic.setPatientId("%" + clinic.getPatientId() + "%");
            }
            if (StringUtils.isBlank(clinic.getCommonParams())) {
                clinic.setCommonParams(null);
            } else {
                //如果在病人表查不到的话，就代入模糊查询
                clinic.setCommonParams("%" + clinic.getCommonParams() + "%");
            }
            if (StringUtils.isBlank(clinic.getBeginDate())) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询就诊记录失败,开始日期参数为空");
                return resultMap;
            }
            if (StringUtils.isBlank(clinic.getEndDate())) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询就诊记录失败,结束日期参数为空");
                return resultMap;
            }
            if (clinic.getPageSize() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询就诊记录失败,每页显示条数参数为空");
                return resultMap;
            }
            if (clinic.getOffset() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询就诊记录失败,当前所在页参数为空");
                return resultMap;
            }
            //如果医生字段是空，说明是查询就诊轨迹，就诊轨迹不限制科室和医生
            if(StringUtils.isBlank(clinic.getDoctorCode())){
                User tokenUser = TokenUtil.getUser(httpServletRequest);
                //clinic.setClinicStatuses(Arrays.asList(ClinicStatusEnum.HAD_CLINIC.code,ClinicStatusEnum.CHARGED.code,ClinicStatusEnum.REFUND.code));
                List<String> deptCodes = mzyRequestService.queryUnitCodeByRequestDayAndDoctor(DateFormatUtils.format(new Date(), "yyyy-MM-dd"), tokenUser.getUserIdCode());
                if (deptCodes == null) {
                    deptCodes = new ArrayList<>();
                }
                //当前医生是急诊科医生，可以看全科室的病人
                if(deptCodes.contains(Constants.EMERGENCY_WARD_CODE)){
                    clinic.setDeptCode(Constants.EMERGENCY_WARD_CODE);
                }else {
                    clinic.setDoctorCode(tokenUser.getUserIdCode());
                }
            }else {
                //前端传的-1需要清空
                clinic.setDoctorCode(null);
            }
            resultMap.put("code", 0);
            resultMap.put("message", "查询就诊记录成功");
            Integer total = clinicService.queryCountClinic(clinic);
            List<Clinic> clinicList = clinicService.queryClinicWithPage(clinic);
            setGender(clinicList);
            resultMap.put("data", clinicList);
            resultMap.put("total", total);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询就诊记录失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询就诊记录失败");
            return resultMap;
        }
    }


    private void setGender(List<Clinic> clinicList) {
        if (clinicList != null && clinicList.size() > 0) {
            for (Clinic cl : clinicList) {
                MzPatientMi mzPatientMi = mzPatientMiService.queryByPatientId(cl.getPatientId());
                if (mzPatientMi == null) {
                    cl.setGender(GenderEnum.UNKNOWN.name);
                    cl.setAge(0);
                } else {
                    cl.setGender(mzPatientMi.getSex() == null ? GenderEnum.UNKNOWN.name : GenderEnum.getGenderByCode(mzPatientMi.getSex()).name);
                    cl.setAge(mzPatientMi.getAge());
                }
            }
        }
    }


    /**
     * 初始化就诊记录表
     *
     * @return
     */
    @RequestMapping(value = "/initClinic", method = {RequestMethod.GET})
    public Map<String, Object> initClinic() {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            Integer count = clinicService.queryCountClinic(new Clinic());
            if (count > 0) {
                resultMap.put("code", 0);
                resultMap.put("message", "已经初始化就诊记录表成功，无需重新初始化");
                return resultMap;
            }
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.YEAR, 2012);
            calendar.set(Calendar.MONTH, 0);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            Date beginTime = calendar.getTime();
            Date now = DateUtil.getFirstSecond();
            Date breakDay = DateUtil.pase("2021-09-14 00:00:00", "yyyy-MM-dd HH:mm:ss");
            List<Clinic> list = new ArrayList<>();
            Set<String> set = new HashSet<>();
            while (beginTime.before(now)) {
                calendar.add(Calendar.DAY_OF_YEAR, 1);
                Date endTime = calendar.getTime();
                try {
                    process(beginTime, endTime, list,set);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("当前日期没有抓取 beginTime=" + beginTime + "----endTime=" + endTime);
                }
                log.info("=====>>>>>开始日期{},结束日期{}初始化统计完成", DateUtil.fomart(beginTime, "yyyy-MM-dd HH:mm:ss"), DateUtil.fomart(endTime, "yyyy-MM-dd HH:mm:ss"));
                beginTime = endTime;
                if (beginTime.equals(breakDay)) {
                    break;
                }
            }
            clinicService.batchSaveClinic(list);
            log.info("=====>>>>>全部初始化完成");
            resultMap.put("code", 0);
            resultMap.put("message", "已经初始化就诊记录表成功");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("初始化就诊记录表失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "初始化就诊记录表失败");
            return resultMap;
        }
    }


    private void process(Date beginTime, Date endTime, List<Clinic> list,Set<String> set) {
        List<MzVisitTable> mzVisitTableList = mzVisitTableService.queryByDateRages(beginTime, endTime, "mz_visit_table_b");
        setClinic(list, mzVisitTableList,set);
        mzVisitTableList = mzVisitTableService.queryByDateRages(beginTime, endTime, "mz_visit_table");
        setClinic(list, mzVisitTableList,set);
    }

    private void setClinic(List<Clinic> list, List<MzVisitTable> mzVisitTableList,Set<String> set) {
        if (mzVisitTableList != null && mzVisitTableList.size() > 0) {
            StringBuilder sbd = new StringBuilder();
            for (MzVisitTable mzVisitTable : mzVisitTableList) {
                sbd.setLength(0);
                sbd.append(mzVisitTable.getPatientId()).append("_").append(mzVisitTable.getTimes());
                String key =sbd.toString();
                if(set.contains(key)){
                    continue;
                }
                set.add(key);
                Clinic clinic = new Clinic();
                clinic.setPatientId(mzVisitTable.getPatientId());
                MzPatientMi mzPatientMi = mzPatientMiService.queryByPatientId(mzVisitTable.getPatientId());
                if (mzPatientMi != null) {
                    clinic.setPatientName(mzPatientMi.getName());
                } else {
                    clinic.setPatientName("");
                }
                clinic.setTimes(mzVisitTable.getTimes());
                clinic.setReceiptNo(mzVisitTable.getReceiptNo());
                clinic.setDeptCode(mzVisitTable.getVisitDeptCode());
                clinic.setDoctorCode(mzVisitTable.getDoctorCode());
                clinic.setIcdCode(StringUtils.isNotBlank(mzVisitTable.getIcdCode()) ? mzVisitTable.getIcdCode().trim() : null);
                clinic.setIcdText(StringUtils.isNotBlank(mzVisitTable.getIcdText()) ? mzVisitTable.getIcdText().trim() : null);
                clinic.setOpDay(mzVisitTable.getOpDay());
                clinic.setFirstOrNot(mzVisitTable.getFirstOrNot());
                MzyReqrec mzyReqrec = mzyReqrecService.queryMzyReqrecByPatientIdAndTimes(mzVisitTable.getPatientId(), mzVisitTable.getTimes(), "mzy_reqrec_b");
                if (mzyReqrec == null) {
                    mzyReqrec = mzyReqrecService.queryMzyReqrecByPatientIdAndTimes(mzVisitTable.getPatientId(), mzVisitTable.getTimes(), "mzy_reqrec");
                }
                if (mzyReqrec != null) {
                    clinic.setOpId(mzVisitTable.getOpId());
                    if (YesNoEnum.YES.code.equals(mzyReqrec.getCancelMark())) {
                        clinic.setClinicStatus(ClinicStatusEnum.BACK_REGISTRATION.code);
                    } else {
                        //傻b们写的医生接诊逻辑不设置visitedMark 字段  挂号的时候还设置成已接诊
                        if (mzyReqrec.getVisitDate() != null) {
                            clinic.setClinicStatus(ClinicStatusEnum.REGISTRATION_TO_CLINIC.code);
                        } else {
                            clinic.setClinicStatus(ClinicStatusEnum.REGISTRATION.code);
                        }
                    }
                } else {
                    BigDecimal amount = mzDepositFileService.queryAmountForPatientId(mzVisitTable.getPatientId(), mzVisitTable.getTimes(), "mz_deposit_file_b");
                    if (amount == null) {
                        amount = mzDepositFileService.queryAmountForPatientId(mzVisitTable.getPatientId(), mzVisitTable.getTimes(), "mz_deposit_file");
                    }
                    clinic.setOpId(StringUtils.isNotBlank(mzVisitTable.getDoctorCode()) ? mzVisitTable.getDoctorCode() : mzVisitTable.getOpId());
                    if (amount == null) {
                        clinic.setClinicStatus(ClinicStatusEnum.HAD_CLINIC.code);
                    } else if (BigDecimal.ZERO.compareTo(amount) == 0) {
                        clinic.setClinicStatus(ClinicStatusEnum.REFUND.code);
                    } else {
                        clinic.setClinicStatus(ClinicStatusEnum.CHARGED.code);
                    }
                }
                list.add(clinic);
                if (list.size() == 100) {
                    clinicService.batchSaveClinic(list);
                    list.clear();
                }
            }
        }
    }


    /**
     * 查询分诊记录
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getUnClinicWithPage", method = {RequestMethod.POST})
    public Map<String, Object> getUnClinicWithPage(@RequestBody MzfzPatientOrder mzfzPatientOrder, HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (mzfzPatientOrder == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询分诊记录失败,参数为空");
                return resultMap;
            }
            if(mzfzPatientOrder.getStatusFlagList()==null ||mzfzPatientOrder.getStatusFlagList().size()==0){
                resultMap.put("code", -1);
                resultMap.put("message", "查询分诊记录失败,分诊状态参数为空");
                return resultMap;
            }
            if (StringUtils.isBlank(mzfzPatientOrder.getPatientId())) {
                mzfzPatientOrder.setPatientId(null);
            }
            if (StringUtils.isNotBlank(mzfzPatientOrder.getName())) {
                mzfzPatientOrder.setName("%" + mzfzPatientOrder.getName() + "%");
            } else {
                mzfzPatientOrder.setName(null);
            }
            if (mzfzPatientOrder.getPageSize() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询分诊记录失败,每页显示条数参数为空");
                return resultMap;
            }
            if (mzfzPatientOrder.getPageIndex() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询分诊记录失败,当前所在页参数为空");
                return resultMap;
            }
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            mzfzPatientOrder.setTableName(MzfzPatientOrder.MZFZ_PATIENT_ORDER);
            mzfzPatientOrder.setDoctorCode(tokenUser.getUserIdCode());
            //mzfzPatientOrder.setStatusFlagList(Arrays.asList(MzfzStatusEnum.UN_TRIAGE.code, MzfzStatusEnum.TRIAGE.code, MzfzStatusEnum.NOTIFICATION.code, MzfzStatusEnum.HAD_NOTIFICATION.code));
            List<String> deptCodes = mzyRequestService.queryUnitCodeByRequestDayAndDoctor(DateFormatUtils.format(new Date(), "yyyy-MM-dd"), tokenUser.getUserIdCode());
            //Employee employee = employeeService.queryByUserCode(tokenUser.getUserIdCode());
            if (deptCodes == null) {
                deptCodes = new ArrayList<>();
            }
//            if (!deptCodes.contains(employee.getDeptCode())) {
//                deptCodes.add(employee.getDeptCode());
//            }
            //当前医生是急诊科医生，可以看全科室的病人
            if(deptCodes.contains(Constants.EMERGENCY_WARD_CODE)){
                mzfzPatientOrder.setDeptCodes(Arrays.asList(Constants.EMERGENCY_WARD_CODE));
            }
            resultMap.put("code", 0);
            resultMap.put("message", "查询分诊记录成功");
            Integer total = mzfzPatientOrderService.querycountUnClinic(mzfzPatientOrder);
            List<MzfzPatientOrder> mzfzPatientOrderList = mzfzPatientOrderService.queryUnClinicWithPage(mzfzPatientOrder);
            setMzfzPatientOrderGender(mzfzPatientOrderList);
            resultMap.put("data", mzfzPatientOrderList);
            resultMap.put("total", total);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询分诊记录失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询分诊记录失败");
            return resultMap;
        }
    }


    private void setMzfzPatientOrderGender(List<MzfzPatientOrder> mzfzPatientOrderList) {
        if (mzfzPatientOrderList != null && mzfzPatientOrderList.size() > 0) {
            for (MzfzPatientOrder cl : mzfzPatientOrderList) {
                MzPatientMi mzPatientMi = mzPatientMiService.queryByPatientId(cl.getPatientId());
                if (mzPatientMi == null) {
                    cl.setGender(GenderEnum.UNKNOWN.name);
                    cl.setAge(0);
                } else {
                    cl.setGender(mzPatientMi.getSex() == null ? GenderEnum.UNKNOWN.name : GenderEnum.getGenderByCode(mzPatientMi.getSex()).name);
                    cl.setAge(mzPatientMi.getAge());
                    cl.setPhoneNo(mzPatientMi.getPhoneNo());
                }
            }
        }
    }

}
