package cn.hnthyy.thmz.controller.mz;

import cn.hnthyy.thmz.Utils.*;
import cn.hnthyy.thmz.comment.UserLoginToken;
import cn.hnthyy.thmz.common.Constants;
import cn.hnthyy.thmz.entity.MzException;
import cn.hnthyy.thmz.entity.his.*;
import cn.hnthyy.thmz.entity.his.mz.*;
import cn.hnthyy.thmz.entity.his.zd.ZdChequeType;
import cn.hnthyy.thmz.entity.his.zd.ZdUnitCode;
import cn.hnthyy.thmz.entity.thmz.User;
import cn.hnthyy.thmz.enums.YesNoEnum;
import cn.hnthyy.thmz.service.his.*;
import cn.hnthyy.thmz.pageDto.MzyReqrecPageDto;
import cn.hnthyy.thmz.service.his.mz.*;
import cn.hnthyy.thmz.service.his.zd.ZdChequeTypeService;
import cn.hnthyy.thmz.service.his.zd.ZdUnitCodeService;
import cn.hnthyy.thmz.vo.MzyReqrecVo;
import cn.hnthyy.thmz.vo.PageViewVo;
import cn.hnthyy.thmz.vo.ThmzmxsrParamsVo;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
public class MzyReqrecController {
    @Autowired
    private MzyReqrecService mzyReqrecService;
    @Autowired
    private MzPatientMiService mzPatientMiService;
    @Autowired
    private ResponceTypeService responceTypeService;
    @Autowired
    private ZdUnitCodeService zdUnitCodeService;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private ZdChequeTypeService zdChequeTypeService;
    @Autowired
    private MzZdWorkTimeService mzZdWorkTimeService;
    @Autowired
    private MzyZdChargeTypeService mzyZdChargeTypeService;

    /**
     * 保存挂号信息
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/saveMzyReqrec", method = {RequestMethod.POST})
    public Map<String, Object> saveMzyReqrec(@RequestBody MzyReqrecPageDto mzyReqrecPageDto, HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (mzyReqrecPageDto == null || mzyReqrecPageDto.getMzyReqrec() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "挂号参数不能为空");
                return resultMap;
            }
            MzyReqrec mzyReqrec = mzyReqrecPageDto.getMzyReqrec();
            if (StringUtils.isBlank(mzyReqrec.getPatientId())) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人id不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(mzyReqrec.getAmpm())) {
                resultMap.put("code", -1);
                resultMap.put("message", "挂号时间段不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(mzyReqrec.getUnitCode())) {
                resultMap.put("code", -1);
                resultMap.put("message", "科室编码不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(mzyReqrec.getChargeType())) {
                resultMap.put("code", -1);
                resultMap.put("message", "号别不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(mzyReqrec.getPaymode())) {
                resultMap.put("code", -1);
                resultMap.put("message", "付款方式不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(mzyReqrecPageDto.getResponceType())) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人性质不能为空");
                return resultMap;
            }
            if (mzyReqrecPageDto.getMzyRequestId() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "门诊号表主键不能为空");
                return resultMap;
            }
            if (mzyReqrecPageDto.getTotalFee() == null) {
                resultMap.put("resultCode", -1);
                resultMap.put("message", "实缴费用不能为空");
                return resultMap;
            }
            MzZdWorkTime mzZdWorkTime = mzZdWorkTimeService.queryMzZdWorkTimeByCode(mzyReqrec.getAmpm());
            if (mzZdWorkTime == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "号段不存在");
                return resultMap;
            }
            if (checkWorkTime(resultMap, mzZdWorkTime)) {
                return resultMap;
            }
            String token = TokenUtil.getToken(httpServletRequest);
            if (StringUtils.isBlank(token)) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询窗口号失败,用户Token不存在");
                return resultMap;
            }
            DecodedJWT decodedJWT = TokenUtil.parseJWT(token);
            User tokenUser = (User) JsonUtil.jsontoObject(decodedJWT.getSubject(), User.class);
            mzyReqrec.setOpId(tokenUser.getUserIdCode());
            int num = mzyReqrecService.saveMzyReqrec(mzyReqrecPageDto);
            if (num == 0) {
                resultMap.put("code", -1);
                resultMap.put("message", "挂号失败，请稍后重试！");
                return resultMap;
            }
            resultMap.put("code", 0);
            resultMap.put("message", "保存挂号信息成功");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", StringUtils.isBlank(e.getMessage()) ? "挂号失败，系统出错，请联系管理员" : e.getMessage());
            log.error("挂号失败，系统异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }

    /**
     * 校验挂号时段的选择是否合理
     *
     * @param resultMap
     * @param mzZdWorkTime
     * @return
     * @throws ParseException
     */
    private boolean checkWorkTime(Map<String, Object> resultMap, MzZdWorkTime mzZdWorkTime) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
        //挂还开始时间取当前时间前15分钟
        Date now = DateUtil.getMinuteAfterDate(15);
//        if (Constants.PM.equals(mzZdWorkTime.getCode())){
//            now= DateUtil.getMinuteAfterDate(10);
//        }
        String nowStr = simpleDateFormat.format(now);
        Date hour = simpleDateFormat.parse(nowStr);
        long hourTs = hour.getTime();
        //真正的当前时间  挂号结束时间还是当前时间
        Date realNow = new Date();
        String realNowStr = simpleDateFormat.format(realNow);
        Date realHour = simpleDateFormat.parse(realNowStr);
        long realHourTs = realHour.getTime();
        Date dateStartTime = simpleDateFormat.parse(mzZdWorkTime.getStartTime());
        long tsStartTime = dateStartTime.getTime();
        Date dateEndTime = simpleDateFormat.parse(mzZdWorkTime.getEndTime());
        long tsEndTime = dateEndTime.getTime();
        if (Constants.AM.equals(mzZdWorkTime.getCode())) {
            if (hourTs < tsStartTime || realHourTs > tsEndTime) {
                resultMap.put("code", -1);
                resultMap.put("message", "挂号失败，当前挂号时间与所选时段不符，请重新选择合适的号段！");
                return true;
            }
        } else if (Constants.PM.equals(mzZdWorkTime.getCode())) {
            if (realHourTs > tsEndTime) {
                resultMap.put("code", -1);
                resultMap.put("message", "挂号失败，当前挂号时间与所选时段不符，请重新选择合适的号段！");
                return true;
            }
        }
        return false;
    }


    /**
     * 导出挂号列表
     *
     * @return
     */
    @RequestMapping(value = "/exportListMzyReqrec", method = {RequestMethod.GET})
    public Map<String, Object> exportListMzyReqrec(@RequestParam("name") String name, @RequestParam("unitCode") String unitCode, @RequestParam("doctorCode") String doctorCode,
                                                   @RequestParam("phoneNo") String phoneNo, @RequestParam("serialNo") String serialNo, @RequestParam("beginTime") String beginTime,
                                                   @RequestParam("endTime") String endTime, @RequestParam("visitedMark") String visitedMark, @RequestParam("cancelMark") String cancelMark, HttpServletRequest request, HttpServletResponse response) {
        try {
            MzyReqrecPageDto mzyReqrecPageDto = new MzyReqrecPageDto();
            mzyReqrecPageDto.setMzyReqrec(new MzyReqrec());
            MzyReqrec mzyReqrec = mzyReqrecPageDto.getMzyReqrec();
            mzyReqrec.setName(name);
            mzyReqrec.setUnitCode(unitCode);
            mzyReqrec.setDoctorCode(doctorCode);
            mzyReqrec.setSerialNo(StringUtils.isBlank(serialNo) ? null : Integer.valueOf(serialNo));
            mzyReqrec.setVisitedMark(StringUtils.isBlank(visitedMark) ? null : Integer.valueOf(visitedMark));
            mzyReqrec.setCancelMark(StringUtils.isBlank(cancelMark) ? null : Integer.valueOf(cancelMark));
            mzyReqrecPageDto.setPhoneNo(phoneNo);
            mzyReqrecPageDto.setBeginTime(DateUtil.pase(beginTime, "yyyy-MM-dd HH:mm:ss"));
            mzyReqrecPageDto.setEndTime(DateUtil.pase(endTime, "yyyy-MM-dd HH:mm:ss"));
            if (StringUtils.isBlank(mzyReqrec.getName())) {
                mzyReqrec.setName(null);
            } else {
                mzyReqrec.setName("%" + mzyReqrec.getName() + "%");
            }
            if (StringUtils.isBlank(mzyReqrec.getUnitCode())) {
                mzyReqrec.setUnitCode(null);
            }
            if (StringUtils.isBlank(mzyReqrec.getDoctorCode())) {
                mzyReqrec.setDoctorCode(null);
            }
            if (StringUtils.isNotBlank(mzyReqrecPageDto.getPhoneNo())) {
                List<MzPatientMi> mzPatientMis = mzPatientMiService.queryByPhoneNo(mzyReqrecPageDto.getPhoneNo());
                if (mzPatientMis == null || mzPatientMis.size() == 0) {
                    return null;
                }
                List<String> patientIds = mzPatientMis.stream().filter(u -> StringUtils.isNotBlank(u.getPatientId())).map(u -> u.getPatientId()).collect(Collectors.toList());
                mzyReqrecPageDto.setPatientIds(patientIds);
            }
            Integer count = mzyReqrecService.countMzyReqrec(mzyReqrecPageDto);
            mzyReqrecPageDto.setPageSize(count);
            ExcelUtil.exportExcelForReqrecList(request, response, getMzyReqrecVo(mzyReqrecService.queryMzyReqrecWithPage(mzyReqrecPageDto)));
            return null;
        } catch (Exception e) {
            log.error("导出挂号列表失败，系统异常，错误信息{}", e.getMessage());
            return null;
        }
    }


    /**
     * 查询挂号列表
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/listMzyReqrec", method = {RequestMethod.POST})
    public Map<String, Object> listMzyReqrec(@RequestBody MzyReqrecPageDto mzyReqrecPageDto) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (mzyReqrecPageDto == null || mzyReqrecPageDto.getMzyReqrec() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "挂号查询参数不能为空");
                return resultMap;
            }
            MzyReqrec mzyReqrec = mzyReqrecPageDto.getMzyReqrec();
            if (StringUtils.isBlank(mzyReqrec.getName())) {
                mzyReqrec.setName(null);
            } else {
                mzyReqrec.setName("%" + mzyReqrec.getName() + "%");
            }
            if (StringUtils.isBlank(mzyReqrec.getUnitCode())) {
                mzyReqrec.setUnitCode(null);
            }
            if (StringUtils.isBlank(mzyReqrec.getDoctorCode())) {
                mzyReqrec.setDoctorCode(null);
            }
            PageViewVo pageViewVo = new PageViewVo(mzyReqrecPageDto.getPageIndex(), mzyReqrecPageDto.getPageSize());
            if (StringUtils.isNotBlank(mzyReqrecPageDto.getPhoneNo())) {
                List<MzPatientMi> mzPatientMis = mzPatientMiService.queryByPhoneNo(mzyReqrecPageDto.getPhoneNo());
                if (mzPatientMis == null || mzPatientMis.size() == 0) {
                    pageViewVo.setTotal(0);
                    pageViewVo.setData(Collections.EMPTY_LIST);
                    resultMap.put("code", 0);
                    resultMap.put("message", "查询挂号信息成功");
                    resultMap.put("pageViewVo", pageViewVo);
                    return resultMap;
                }
                List<String> patientIds = mzPatientMis.stream().filter(u -> StringUtils.isNotBlank(u.getPatientId())).map(u -> u.getPatientId()).collect(Collectors.toList());
                mzyReqrecPageDto.setPatientIds(patientIds);
            }
            Integer count = mzyReqrecService.countMzyReqrec(mzyReqrecPageDto);
            pageViewVo.setTotal(count == null ? 0 : count);
            pageViewVo.setData(getMzyReqrecVo(mzyReqrecService.queryMzyReqrecWithPage(mzyReqrecPageDto)));
            resultMap.put("code", 0);
            resultMap.put("message", "查询挂号信息成功");
            resultMap.put("pageViewVo", pageViewVo);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "查询挂号列表失败，系统出错，请联系管理员");
            log.error("查询挂号列表失败，系统异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }


    /**
     * 查询挂号中，已就诊人数，退号人次
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getCountByParams", method = {RequestMethod.POST})
    public Map<String, Object> getCountByParams(@RequestBody MzyReqrecPageDto mzyReqrecPageDto) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (mzyReqrecPageDto == null || mzyReqrecPageDto.getMzyReqrec() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "挂号统计查询参数不能为空");
                return resultMap;
            }
            MzyReqrec mzyReqrec = mzyReqrecPageDto.getMzyReqrec();
            if (StringUtils.isBlank(mzyReqrec.getName())) {
                mzyReqrec.setName(null);
            } else {
                mzyReqrec.setName("%" + mzyReqrec.getName() + "%");
            }
            if (StringUtils.isBlank(mzyReqrec.getUnitCode())) {
                mzyReqrec.setUnitCode(null);
            }
            if (StringUtils.isBlank(mzyReqrec.getDoctorCode())) {
                mzyReqrec.setDoctorCode(null);
            }
            if (StringUtils.isNotBlank(mzyReqrecPageDto.getPhoneNo())) {
                List<MzPatientMi> mzPatientMis = mzPatientMiService.queryByPhoneNo(mzyReqrecPageDto.getPhoneNo());
                if (mzPatientMis == null || mzPatientMis.size() == 0) {
                    resultMap.put("code", 0);
                    resultMap.put("message", "查询挂号统计信息成功");
                    resultMap.put("registrationNum", 0);
                    resultMap.put("haveClinicalNum", 0);
                    resultMap.put("backNoNum", 0);
                    return resultMap;
                }
                List<String> patientIds = mzPatientMis.stream().filter(u -> StringUtils.isNotBlank(u.getPatientId())).map(u -> u.getPatientId()).collect(Collectors.toList());
                mzyReqrecPageDto.setPatientIds(patientIds);
            }
            mzyReqrec.setVisitedMark(YesNoEnum.NO.code);
            mzyReqrec.setCancelMark(YesNoEnum.NO.code);

            Integer registrationNum = mzyReqrecService.countMzyReqrec(mzyReqrecPageDto);
            mzyReqrec.setVisitedMark(YesNoEnum.YES.code);
            Integer haveClinicalNum = mzyReqrecService.countMzyReqrec(mzyReqrecPageDto);
            mzyReqrec.setVisitedMark(null);
            mzyReqrec.setCancelMark(YesNoEnum.YES.code);
            Integer backNoNum = mzyReqrecService.countMzyReqrec(mzyReqrecPageDto);
            resultMap.put("code", 0);
            resultMap.put("message", "查询挂号统计信息成功");
            resultMap.put("registrationNum", registrationNum == null ? 0 : registrationNum);
            resultMap.put("haveClinicalNum", haveClinicalNum == null ? 0 : haveClinicalNum);
            resultMap.put("backNoNum", backNoNum == null ? 0 : backNoNum);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "查询挂号统计失败，系统出错，请联系管理员");
            log.error("查询挂号统计失败，系统异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }


    /**
     * 构造包含病人信息的挂号记录视图
     *
     * @param mzyReqrecs
     * @return
     */
    private List<MzyReqrecVo> getMzyReqrecVo(List<MzyReqrec> mzyReqrecs) {
        List<MzyReqrecVo> mzyReqrecVos = new ArrayList<>();
        if (mzyReqrecs == null) {
            return mzyReqrecVos;
        }
        Set<String> patientIds = mzyReqrecs.stream().map(u -> u.getPatientId()).collect(Collectors.toSet());
        List<MzPatientMi> mzPatientMis = new ArrayList<>();
        if (patientIds != null && patientIds.size() > 0) {
            List<String> temp = new ArrayList<>();
            int num = 0;
            for (String str : patientIds) {
                temp.add(str);
                num++;
                if (num == 200) {
                    mzPatientMis.addAll(mzPatientMiService.queryByPatientIds(temp));
                    temp = new ArrayList<>();
                    num = 0;
                }
            }
            if (num > 0) {
                mzPatientMis.addAll(mzPatientMiService.queryByPatientIds(temp));
            }
        }
        if (mzPatientMis != null) {
            List<ResponceType> responceTypes = responceTypeService.queryAllMzResponceType();
            if (responceTypes != null) {
                Map<String, String> responceTypeMap = responceTypes.stream().collect(Collectors.toMap(ResponceType::getCode, ResponceType::getName));
                if (responceTypeMap != null) {
                    for (MzPatientMi mzPatientMi : mzPatientMis) {
                        mzPatientMi.setResponseType(responceTypeMap.get(mzPatientMi.getResponseType()));
                    }
                }
            }
        }
        Map<String, MzPatientMi> mzPatientMiMap = null;
        if (mzPatientMis != null) {
            mzPatientMiMap = mzPatientMis.stream().collect(Collectors.toMap(MzPatientMi::getPatientId, mzPatientMi -> mzPatientMi));
        }
        Set<String> doctorCodes = mzyReqrecs.stream().map(u -> u.getDoctorCode()).collect(Collectors.toSet());
        List<Employee> employees = new ArrayList<>();
        if (doctorCodes != null && doctorCodes.size() > 0) {
            List<String> temp = new ArrayList<>();
            int num = 0;
            for (String str : doctorCodes) {
                temp.add(str);
                num++;
                if (num == 200) {
                    employees.addAll(employeeService.queryByCodes(temp));
                    temp = new ArrayList<>();
                    num = 0;
                }
            }
            if (num > 0) {
                employees.addAll(employeeService.queryByCodes(temp));
            }
        }
        Map<String, String> employeeMap = null;
        if (employees != null) {
            employeeMap = employees.stream().collect(Collectors.toMap(Employee::getEmployeeCode, Employee::getEmployeeName));
        }
        List<ZdChequeType> chequeTypes = zdChequeTypeService.queryAllZdChequeTypeForMz();
        Map<String, String> chequeTypeMap = null;
        if (chequeTypes != null) {
            chequeTypeMap = chequeTypes.stream().collect(Collectors.toMap(ZdChequeType::getCode, ZdChequeType::getName));
        }
        List<MzZdWorkTime> workTimes = mzZdWorkTimeService.queryAllMzZdWorkTime();
        Map<String, String> workTimeMap = null;
        if (workTimes != null) {
            workTimeMap = workTimes.stream().collect(Collectors.toMap(MzZdWorkTime::getCode, MzZdWorkTime::getName));
        }
        List<MzyZdChargeType> mzyZdChargeTypes = mzyZdChargeTypeService.queryAllMzyZdChargeType();
        Map<String, String> mzyZdChargeTypeMap = null;
        if (mzyZdChargeTypes != null) {
            mzyZdChargeTypeMap = mzyZdChargeTypes.stream().collect(Collectors.toMap(MzyZdChargeType::getCode, MzyZdChargeType::getName));
        }
        for (MzyReqrec mzyReqrec : mzyReqrecs) {
            if (mzyReqrec != null) {
                mzyReqrec.setUnitCode(zdUnitCodeService.queryDeptNameByIdInCache(mzyReqrec.getUnitCode()));
                if (employeeMap != null) {
                    String doctorCode = employeeMap.get(mzyReqrec.getDoctorCode());
                    mzyReqrec.setDoctorCode(doctorCode == null ? "" : doctorCode);
                }
                if (chequeTypeMap != null) {
                    String paymode = chequeTypeMap.get(mzyReqrec.getPaymode());
                    mzyReqrec.setPaymode(paymode == null ? "" : paymode);
                }
                if (workTimeMap != null) {
                    String workTime = workTimeMap.get(mzyReqrec.getAmpm());
                    mzyReqrec.setAmpm(workTime == null ? "" : workTime);
                }
                if (mzyZdChargeTypeMap != null) {
                    String chargeType = mzyZdChargeTypeMap.get(mzyReqrec.getChargeType());
                    mzyReqrec.setChargeType(chargeType == null ? "" : chargeType);
                }
                //傻b们写的医生接诊逻辑不设置visitedMark 字段  挂号的时候还设置成已接诊
                if (mzyReqrec.getVisitDate() != null) {
                    mzyReqrec.setVisitedMark(YesNoEnum.YES.code);
                } else {
                    mzyReqrec.setVisitedMark(YesNoEnum.NO.code);
                }
                MzyReqrecVo mzyReqrecVo = new MzyReqrecVo();
                mzyReqrecVo.setMzyReqrec(mzyReqrec);
                if (mzPatientMiMap != null) {
                    mzyReqrecVo.setMzPatientMi(mzPatientMiMap.get(mzyReqrec.getPatientId()));
                }
                mzyReqrecVos.add(mzyReqrecVo);
            }
        }
        return mzyReqrecVos;
    }


    /**
     * 根据病人id查询挂号信息
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getMzyReqrecByPatientIdAndTimes", method = {RequestMethod.POST})
    public Map<String, Object> getMzyReqrecByPatientIdAndTimes(@RequestBody MzyReqrec mzyReqrec) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (mzyReqrec == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "挂号查询参数不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(mzyReqrec.getPatientId())) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人id不能为空");
                return resultMap;
            }
            if (mzyReqrec.getTimes() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人挂号次数不能为空");
                return resultMap;
            }
            MzyReqrec result = mzyReqrecService.queryMzyReqrecByPatientIdAndTimes(mzyReqrec.getPatientId(), mzyReqrec.getTimes());
            if (result != null) {
                List<MzyReqrecVo> mzyReqrecVos = getMzyReqrecVo(Arrays.asList(result));
                if (mzyReqrecVos != null && mzyReqrecVos.size() > 0) {
                    resultMap.put("code", 0);
                    resultMap.put("message", "查询挂号信息成功");
                    resultMap.put("data", mzyReqrecVos.get(0));
                    return resultMap;
                }
            }
            resultMap.put("code", -1);
            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 = "/updateReqrec", method = {RequestMethod.POST})
    public Map<String, Object> updateReqrec(@RequestBody MzyReqrec mzyReqrec, HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (mzyReqrec == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "更新挂号信息参数不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(mzyReqrec.getPatientId())) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人id不能为空");
                return resultMap;
            }
            if (mzyReqrec.getTimes() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人挂号次数不能为空");
                return resultMap;
            }
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            if (tokenUser == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询窗口号失败,用户Token不存在");
                return resultMap;
            }
            mzyReqrec.setOpId(tokenUser.getUserIdCode());
            int num = mzyReqrecService.modifyMzyReqrec(mzyReqrec, tokenUser);
            if (num == 1) {
                resultMap.put("code", 0);
                resultMap.put("message", "更新挂号信息成功");
                return resultMap;
            }
            resultMap.put("code", -1);
            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 = "/printMzyReqrecRecept", method = {RequestMethod.GET})
    public Map<String, Object> printMzyReqrecRecept(@RequestParam("patientId") String patientId, @RequestParam("times") Integer times, HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (StringUtils.isBlank(patientId)) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人编号参数不能为空");
                return resultMap;
            }
            if (times == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人就诊次数不能为空");
                return resultMap;
            }
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            if (tokenUser == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "打印当前挂号的发票信息失败,用户Token不存在");
                return resultMap;
            }
            MzyReqrec mzyReqrec;
            if (times == -1) {
                mzyReqrec = mzyReqrecService.queryLastMzyReqrecByPatientId(patientId);
            } else {
                mzyReqrec = mzyReqrecService.queryMzyReqrecByPatientIdAndTimes(patientId, times);
            }
            if (mzyReqrec == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "当前病人不存在挂号信息");
                return resultMap;
            }
            if (StringUtils.isNotBlank(mzyReqrec.getPrinterId())) {
                resultMap.put("code", -1);
                resultMap.put("message", "当前挂号信息已经打印过发票，请勿重复操作");
                return resultMap;
            }
            if (Constants.BYJZ.equals(mzyReqrec.getPaymode())) {
                //当前病人没有实际缴费，暂时不打印发票
                resultMap.put("code", -2);
                resultMap.put("message", "挂号成功,记账不打发票");
                log.info("当前病人没有实际缴费，暂时不打印发票，patientId={},time={}", patientId, times);
                return resultMap;
            }
            ZdUnitCode zdUnitCode = zdUnitCodeService.queryByCode(mzyReqrec.getUnitCode());
            if (zdUnitCode != null) {
                mzyReqrec.setUnitCode(zdUnitCode.getName());
                resultMap.put("officePos", zdUnitCode.getOfficePos());
            }
            Employee employee = employeeService.queryByUserCode(mzyReqrec.getDoctorCode());
            if (employee != null) {
                mzyReqrec.setDoctorCode(employee.getEmployeeName());
            }
            MzyZdChargeType mzyZdChargeType = mzyZdChargeTypeService.queryByCode(mzyReqrec.getChargeType());
            if (mzyZdChargeType != null) {
                mzyReqrec.setChargeType(mzyZdChargeType.getName());
            }
            if ("a".equals(mzyReqrec.getAmpm())) {
                mzyReqrec.setAmpm("上午");
            } else if ("p".equals(mzyReqrec.getAmpm())) {
                mzyReqrec.setAmpm("下午");
            } else if ("n".equals(mzyReqrec.getAmpm())) {
                mzyReqrec.setAmpm("中午");
            } else if ("d".equals(mzyReqrec.getAmpm())) {
                mzyReqrec.setAmpm("全天");
            }
            BigDecimal totalFee = mzyReqrec.getReqFee().add(mzyReqrec.getClinicFee()).add(mzyReqrec.getOthFee()).add(mzyReqrec.getBrochureFee());
            if (totalFee.compareTo(BigDecimal.ZERO) == 0) {
                resultMap.put("code", -1);
                resultMap.put("message", "当前病人无费用信息，无需开具发票");
                return resultMap;
            }
            resultMap.put("totalFee", totalFee);
            resultMap.put("totalFeeStr", NumberToCN.number2CNMontrayUnit(totalFee));
            Date chargeDate = mzyReqrec.getRequestDay();
            if (chargeDate == null) {
                chargeDate = new Date();
            }
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(chargeDate);
            resultMap.put("year", calendar.get(Calendar.YEAR));
            Integer month = calendar.get(Calendar.MONTH) + 1;
            if (month < 10) {
                resultMap.put("month", "0" + month);
            } else {
                resultMap.put("month", month.toString());
            }
            Integer day = calendar.get(Calendar.DAY_OF_MONTH);
            if (day < 10) {
                resultMap.put("day", "0" + day);
            } else {
                resultMap.put("day", day.toString());
            }
            mzyReqrec.setPrinterId(tokenUser.getUserIdCode());
            mzyReqrecService.printMzyReqrecRecept(mzyReqrec);
            resultMap.put("code", 0);
            resultMap.put("data", mzyReqrec);
            resultMap.put("user", tokenUser);
            return resultMap;
        } catch (MzException e) {
            resultMap.put("code", -1);
            resultMap.put("message", "获取当前挂号的发票信息失败，" + e.getMessage());
            log.error("获取当前挂号的发票信息失败，系统异常，错误信息{}", e);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "获取当前挂号的发票信息失败，系统出错，请联系管理员");
            log.error("获取当前挂号的发票信息失败，系统异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }


    /**
     * 本院记账退费重收
     * @param serialNo
     * @param paymode 付费方式
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/chargeFeeForByjz", method = {RequestMethod.GET})
    public Map<String, Object> chargeFeeForByjz(@RequestParam Integer serialNo,@RequestParam String paymode, HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (serialNo==null) {
                resultMap.put("code", -1);
                resultMap.put("message", "需要退费重收的流水号不能为空");
                return resultMap;
            }
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            if (tokenUser == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "本院记账退费重收失败,用户Token不存在");
                return resultMap;
            }
            MzyReqrec mzyReqrec = mzyReqrecService.chargeFeeForByjz(serialNo,paymode,tokenUser.getUserIdCode());
            if (mzyReqrec==null) {
                resultMap.put("code", -1);
                resultMap.put("message", "本院记账退费重收操作失败");
                return resultMap;
            }
            resultMap.put("code", 0);
            resultMap.put("data", mzyReqrec);
            resultMap.put("message", "本院记账退费重收成功");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", e.getMessage());
            log.error("本院记账退费重收失败，系统异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }


    /**
     * 修改收费方式
     * @param patientId
     * @param times
     * @param payMode 付费方式
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/updatePayMode", method = {RequestMethod.GET})
    public Map<String, Object> updatePayMode(@RequestParam String patientId,@RequestParam Integer times,@RequestParam String payMode, HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if(StringUtils.isBlank(patientId)){
                resultMap.put("code", -1);
                resultMap.put("message", "病人ID不能为空");
                return resultMap;
            }
            if (times==null) {
                resultMap.put("code", -1);
                resultMap.put("message", "就诊次数不能为空");
                return resultMap;
            }
            if (times<0) {
                resultMap.put("code", -1);
                resultMap.put("message", "就诊次数必须是正数");
                return resultMap;
            }
            if(StringUtils.isBlank(payMode)){
                resultMap.put("code", -1);
                resultMap.put("message", "新的付款方式不能为空");
                return resultMap;
            }
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            if (tokenUser == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "修改收费方式失败,用户Token不存在");
                return resultMap;
            }
            MzyReqrec mzyReqrec= mzyReqrecService.queryMzyReqrecByPatientIdAndTimes(patientId,times);
            if (mzyReqrec==null) {
                resultMap.put("code", -1);
                resultMap.put("message", "没有找到对应的挂号记录");
                return resultMap;
            }
//            if(YesNoEnum.YES.code.equals(mzyReqrec.getDcountNo())){
//                resultMap.put("code", -1);
//                resultMap.put("message", "挂号记录已经结算，无法修复付款方式");
//                return resultMap;
//            }
            if(payMode.equals(mzyReqrec.getPaymode())){
                resultMap.put("code", -1);
                resultMap.put("message", "新的付款方式与原付款方式一致，无需修改");
                return resultMap;
            }
            MzyReqrec updateMzyReqrec = new MzyReqrec();
            updateMzyReqrec.setPaymode(payMode);
            updateMzyReqrec.setPatientId(mzyReqrec.getPatientId());
            updateMzyReqrec.setTimes(mzyReqrec.getTimes());
            mzyReqrecService.modifyMzyReqrec(updateMzyReqrec);
            resultMap.put("code", 0);
            resultMap.put("message", "修改收费方式成功");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", e.getMessage());
            log.error("修改挂号收费方式失败，系统异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }


    /**
     * 门诊号别统计表
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getMzhbCount", method = {RequestMethod.POST})
    public Map<String, Object> getMzhbCount(@RequestBody ThmzmxsrParamsVo thmzmxsrParamsVo) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (thmzmxsrParamsVo == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "门诊号别统计表失败,参数为空");
                return resultMap;
            }
            if (thmzmxsrParamsVo.getBeginDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "门诊号别统计表失败,开始时间为空");
                return resultMap;
            }
            if (thmzmxsrParamsVo.getEndDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "门诊号别统计表失败,结束时间为空");
                return resultMap;
            }
            if (StringUtils.isBlank(thmzmxsrParamsVo.getCaseType())) {
                thmzmxsrParamsVo.setCaseType(YesNoEnum.NO.code.toString());
            }
            if (StringUtils.isBlank(thmzmxsrParamsVo.getJzSqDept())) {
                thmzmxsrParamsVo.setJzSqDept(null);
            }
            if (StringUtils.isBlank(thmzmxsrParamsVo.getJzSqDoctor())) {
                thmzmxsrParamsVo.setJzSqDoctor(null);
            }
            resultMap.put("code", 0);
            resultMap.put("message", "门诊号别统计表成功");
            List<Map<String, Object>> mzhbCounts = mzyReqrecService.queryMzhbCount(thmzmxsrParamsVo);
            if (mzhbCounts == null || mzhbCounts.size() == 0) {
                resultMap.put("code", -1);
                resultMap.put("message", "没有查询到符合条件的门诊挂号统计信息");
                return resultMap;
            }
            Set<String> chargeTypeSet = new HashSet<>();
            Set<String> depetSet = new HashSet<>();
            //医生类别列表
            List<Map<String, Object>> chargeTypeList = new ArrayList<>();
            //科室列表
            List<Map<String, Object>> depetList = new ArrayList<>();
            //按照科室合计统计
            Map<String, Map<String, Object>> deptHjMap = new HashMap<>();
            //按照号别类型合计统计
            Map<String, Map<String, Object>> chargeTypeHjMap = new HashMap<>();
            for (Map<String, Object> map : mzhbCounts) {
                String chargeType = (String) map.get("charge_type");
                if (!chargeTypeSet.contains(chargeType)) {
                    Map<String, Object> chargeTemp = new HashMap<>();
                    chargeTemp.put("charge_type_name", map.get("charge_type_name"));
                    chargeTemp.put("charge_type", chargeType);
                    chargeTypeList.add(chargeTemp);
                    chargeTypeSet.add(chargeType);
                    chargeTypeHjMap.put(chargeType, chargeTemp);
                }
                String unitCode = (String) map.get("unit_code");
                if (!depetSet.contains(unitCode)) {
                    Map<String, Object> deptTemp = new HashMap<>();
                    deptTemp.put("dept_name", map.get("dept_name"));
                    deptTemp.put("unit_code", unitCode);
                    depetList.add(deptTemp);
                    depetSet.add(unitCode);
                    deptHjMap.put(unitCode, deptTemp);
                }
                Map<String, Object> deptMap = deptHjMap.get(unitCode);
                Integer hshj = (Integer) deptMap.get("hshj");
                Double jehj = (Double) deptMap.get("jehj");
                if (hshj == null) {
                    hshj = 0;
                }
                if (jehj == null) {
                    jehj = 0D;
                }
                Integer patientCount = (Integer) map.get("patient_count");
                Double reqFee = ((Double) map.get("req_fee"));
                hshj = hshj + patientCount;
                jehj = jehj + reqFee;
                deptMap.put("hshj", hshj);
                deptMap.put("jehj", jehj);

                Map<String, Object> chargeMap = chargeTypeHjMap.get(chargeType);
                Integer chargeHshj = (Integer) chargeMap.get("chargeHshj");
                Double chargeHehj = (Double) chargeMap.get("chargeHehj");
                if (chargeHshj == null) {
                    chargeHshj = 0;
                }
                if (chargeHehj == null) {
                    chargeHehj = 0D;
                }
                chargeHshj = chargeHshj + patientCount;
                chargeHehj = chargeHehj + reqFee;
                chargeMap.put("chargeHshj", chargeHshj);
                chargeMap.put("chargeHehj", chargeHehj);
            }
            resultMap.put("depetList", depetList);
            resultMap.put("chargeTypeList", chargeTypeList);
            resultMap.put("data", mzhbCounts);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("门诊号别统计表失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "门诊号别统计表失败");
            return resultMap;
        }
    }

}
