package cn.hnthyy.thmz.controller.zy;

import cn.hnthyy.thmz.Utils.DateUtil;
import cn.hnthyy.thmz.Utils.NumberToCN;
import cn.hnthyy.thmz.Utils.TokenUtil;
import cn.hnthyy.thmz.comment.UserLoginToken;
import cn.hnthyy.thmz.common.Constants;
import cn.hnthyy.thmz.entity.MzException;
import cn.hnthyy.thmz.entity.his.mz.*;
import cn.hnthyy.thmz.entity.his.zd.ZdChequeType;
import cn.hnthyy.thmz.entity.his.zy.ZyActpatient;
import cn.hnthyy.thmz.entity.his.zy.ZyReceipt;
import cn.hnthyy.thmz.entity.thmz.User;
import cn.hnthyy.thmz.enums.GenderEnum;
import cn.hnthyy.thmz.enums.ResponceTypeEnum;
import cn.hnthyy.thmz.enums.YesNoEnum;
import cn.hnthyy.thmz.service.his.zd.ZdUnitCodeService;
import cn.hnthyy.thmz.service.his.zy.ZyActpatientService;
import cn.hnthyy.thmz.service.his.zy.ZyLedgerFileService;
import cn.hnthyy.thmz.service.his.zy.ZyReceiptService;
import cn.hnthyy.thmz.vo.MzReceiptSerialVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

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

@Slf4j
@RestController
public class ZyReceiptlController {
    @Autowired
    private ZyReceiptService zyReceiptService;
    @Autowired
    private ZyActpatientService zyActpatientService;
    @Autowired
    private ZyLedgerFileService zyLedgerFileService;
    @Autowired
    private ZdUnitCodeService zdUnitCodeService;

    /**
     * 根据住院号与住院次数号查本次住院所有未打印发票
     *
     * @param inpatientNo
     * @param admissTimes
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getAllReceiptForThisTime", method = {RequestMethod.GET})
    public Map<String, Object> getAllReceiptForThisTime(@RequestParam("inpatientNo") String inpatientNo, @RequestParam("admissTimes") Integer admissTimes) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (StringUtils.isBlank(inpatientNo)) {
                resultMap.put("code", -1);
                resultMap.put("message", "住院号参数不能为空");
                return resultMap;
            }
            if (admissTimes == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "住院次数不能为空");
                return resultMap;
            }
            List<ZyReceipt> zyReceipts = zyReceiptService.queryAllValidAndNotPrintReceipt(inpatientNo, admissTimes);
            if (zyReceipts == null || zyReceipts.size() == 0) {
                resultMap.put("code", -1);
                resultMap.put("message", "该患者本次住院发票暂未生成！");
                return resultMap;
            }
//            if(zyReceipts.size()==1){
//                //只有一条记录时直接转发到查询单条记录接口
//                httpServletRequest.getRequestDispatcher("/getReceiptForThisLedgerSn?inpatientNo="+inpatientNo+"&admissTimes="+admissTimes+"&ledgerSn="+zyReceipts.get(0).getLedgerSn()).forward(httpServletRequest,httpServletResponse);
//            }
            resultMap.put("code", 0);
            resultMap.put("message", "住院发票查询成功！");
            resultMap.put("data", zyReceipts);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "根据住院号与住院次数号查本次住院所有未打印发票失败，系统出错，请联系管理员");
            log.error("根据住院号与住院次数号查本次住院所有未打印发票失败，系统异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }


    /**
     * 根据住院号与住院次数号查本次住院所有已经打印发票
     *
     * @param inpatientNo
     * @param admissTimes
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getAllPrintReceipt", method = {RequestMethod.GET})
    public Map<String, Object> getAllPrintReceipt(@RequestParam("inpatientNo") String inpatientNo, @RequestParam("admissTimes") Integer admissTimes) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (StringUtils.isBlank(inpatientNo)) {
                resultMap.put("code", -1);
                resultMap.put("message", "住院号参数不能为空");
                return resultMap;
            }
            if (admissTimes == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "住院次数不能为空");
                return resultMap;
            }
            List<ZyReceipt> zyReceipts = zyReceiptService.queryAllPrintReceipt(inpatientNo, admissTimes);
            if (zyReceipts == null || zyReceipts.size() == 0) {
                resultMap.put("code", -1);
                resultMap.put("message", "该患者本次住院发票暂未打印！");
                return resultMap;
            }
            resultMap.put("code", 0);
            resultMap.put("message", "住院发票查询成功！");
            resultMap.put("data", zyReceipts);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "根据住院号与住院次数号查本次住院所有已经打印发票失败，系统出错，请联系管理员");
            log.error("根据住院号与住院次数号查本次住院所有已经打印发票失败，系统异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }


    /**
     * 根据住院号与住院次数以及账页号查询该账页的住院发票
     *
     * @param inpatientNo
     * @param admissTimes
     * @param ledgerSn
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getReceiptForThisLedgerSn", method = {RequestMethod.GET})
    public Map<String, Object> getReceiptForThisLedgerSn(@RequestParam("inpatientNo") String inpatientNo, @RequestParam("admissTimes") Integer admissTimes, @RequestParam("ledgerSn") Long ledgerSn) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (StringUtils.isBlank(inpatientNo)) {
                resultMap.put("code", -1);
                resultMap.put("message", "住院号参数不能为空");
                return resultMap;
            }
            if (admissTimes == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "住院次数不能为空");
                return resultMap;
            }
            if (ledgerSn == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "账页号码不能为空");
                return resultMap;
            }
            ZyReceipt zyReceipt = zyReceiptService.queryZyReceiptByLedgerSn(inpatientNo, admissTimes, ledgerSn);
            resultMap.put("code", 0);
            resultMap.put("message", "住院发票查询成功！");
            resultMap.put("data", zyReceipt);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "根据住院号与住院次数以及账页号查询该账页的住院发票失败，系统出错，请联系管理员");
            log.error("根据住院号与住院次数以及账页号查询该账页的住院发票失败，系统异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }


    /**
     * 打印住院发票
     *
     * @param inpatientNo
     * @param admissTimes
     * @param ledgerSn
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/printReceiptForThisLedgerSn", method = {RequestMethod.GET})
    public Map<String, Object> printReceiptForThisLedgerSn(@RequestParam("inpatientNo") String inpatientNo, @RequestParam("admissTimes") Integer admissTimes, @RequestParam("ledgerSn") Long ledgerSn, HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (StringUtils.isBlank(inpatientNo)) {
                resultMap.put("code", -1);
                resultMap.put("message", "打印住院发票失败,住院号参数不能为空");
                return resultMap;
            }
            if (admissTimes == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "打印住院发票失败,住院次数不能为空");
                return resultMap;
            }
            if (ledgerSn == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "打印住院发票失败,账页号码不能为空");
                return resultMap;
            }
            ZyActpatient zyActpatient = zyActpatientService.queryByInpatientNo(ZyActpatient.ZY_INACTPATIENT, inpatientNo, admissTimes);
            if (zyActpatient == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "打印住院发票失败,病人出院信息不存在");
                return resultMap;
            }
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            ZyReceipt zyReceipt = zyReceiptService.printReceipt(inpatientNo, admissTimes, ledgerSn, tokenUser);
            GenderEnum genderEnum = GenderEnum.getGenderByCode(Integer.valueOf(zyActpatient.getSex()));
            zyActpatient.setSex(genderEnum == null ? GenderEnum.UNKNOWN.name : genderEnum.name);
            zyActpatient.setResponceTypeName(ResponceTypeEnum.getReportTypeByCode(zyActpatient.getResponceType()).name);
            Map<String, Object> jeMap = zyLedgerFileService.queryTellerInfo(inpatientNo, admissTimes, ledgerSn.intValue());
            int days = DateUtil.getBetweenDatesDesc(DateUtil.pase(zyActpatient.getAdmissDate(), "yyyy-MM-dd"), DateUtil.pase(zyActpatient.getDisDate(), "yyyy-MM-dd")).size();
            zyActpatient.setWardName(zdUnitCodeService.queryDeptNameByIdInCache(zyActpatient.getWard()));
            resultMap.put("code", 0);
            resultMap.put("message", "打印住院发票成功！");
            resultMap.put("zyReceipt", zyReceipt);
            resultMap.put("zyActpatient", zyActpatient);
            resultMap.put("jeMap", jeMap);
            resultMap.put("days", days);
            resultMap.put("printer", tokenUser.getUserName());
            resultMap.put("grhjzfje", NumberToCN.number2CNMontrayUnit((BigDecimal) jeMap.get("zfje")));
            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 obsolete           Yes 作废重打  no 重新打印
     * @param receiptNo
     * @param httpServletRequest
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/repPrintZyReceipt", method = {RequestMethod.GET})
    public Map<String, Object> repPrintZyReceipt(@RequestParam("obsolete") String obsolete, @RequestParam("receiptNo") String receiptNo, HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (StringUtils.isBlank(receiptNo)) {
                resultMap.put("code", -1);
                resultMap.put("message", "需要重打的发票号码不能为空");
                return resultMap;
            }
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            ZyReceipt zyReceipt = zyReceiptService.obsoleteAndRepPrint(receiptNo, obsolete, tokenUser);
            if (zyReceipt == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "重打失败，请稍后重试");
                return resultMap;
            }
            ZyActpatient zyActpatient = zyActpatientService.queryByInpatientNo(ZyActpatient.ZY_INACTPATIENT, zyReceipt.getInpatientNo(), zyReceipt.getAdmissTimes());
            if (zyActpatient == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "打印住院发票失败,病人出院信息不存在");
                return resultMap;
            }
            GenderEnum genderEnum = GenderEnum.getGenderByCode(Integer.valueOf(zyActpatient.getSex()));
            zyActpatient.setSex(genderEnum == null ? GenderEnum.UNKNOWN.name : genderEnum.name);
            zyActpatient.setResponceTypeName(ResponceTypeEnum.getReportTypeByCode(zyActpatient.getResponceType()).name);
            Map<String, Object> jeMap = zyLedgerFileService.queryTellerInfo(zyReceipt.getInpatientNo(), zyReceipt.getAdmissTimes(), zyReceipt.getLedgerSn().intValue());
            int days = DateUtil.getBetweenDatesDesc(DateUtil.pase(zyActpatient.getAdmissDate(), "yyyy-MM-dd"), DateUtil.pase(zyActpatient.getDisDate(), "yyyy-MM-dd")).size();
            zyActpatient.setWardName(zdUnitCodeService.queryDeptNameByIdInCache(zyActpatient.getWard()));
            resultMap.put("code", 0);
            resultMap.put("message", "重新打印当前发票成功");
            resultMap.put("zyReceipt", zyReceipt);
            resultMap.put("zyActpatient", zyActpatient);
            resultMap.put("jeMap", jeMap);
            resultMap.put("days", days);
            resultMap.put("printer", tokenUser.getUserName());
            resultMap.put("grhjzfje", NumberToCN.number2CNMontrayUnit((BigDecimal) jeMap.get("zfje")));
            log.info("院发票receiptNo=" + receiptNo + "已经重新打印了");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "重新打印当前住院发票失败，系统出错，请联系管理员");
            log.error("重新打印当前住院发票失败，系统异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }


}
