package cn.hnthyy.thmz.controller.zy;

import cn.hnthyy.thmz.Utils.NumberToCN;
import cn.hnthyy.thmz.Utils.TokenUtil;
import cn.hnthyy.thmz.comment.UserLoginToken;
import cn.hnthyy.thmz.entity.MzException;
import cn.hnthyy.thmz.entity.his.mz.Employee;
import cn.hnthyy.thmz.entity.his.mz.MzPatientMi;
import cn.hnthyy.thmz.entity.his.zd.ZdChequeType;
import cn.hnthyy.thmz.entity.his.zy.ZyActpatient;
import cn.hnthyy.thmz.entity.his.zy.ZyDepositFile;
import cn.hnthyy.thmz.entity.his.zy.ZyLedgerFile;
import cn.hnthyy.thmz.entity.thmz.User;
import cn.hnthyy.thmz.enums.ZyDepositFileStatusEnum;
import cn.hnthyy.thmz.service.his.mz.EmployeeService;
import cn.hnthyy.thmz.service.his.mz.MzPatientMiService;
import cn.hnthyy.thmz.service.his.zd.ZdChequeTypeService;
import cn.hnthyy.thmz.service.his.zd.ZdUnitCodeService;
import cn.hnthyy.thmz.service.his.zy.ZyActpatientService;
import cn.hnthyy.thmz.service.his.zy.ZyDepositFileService;
import cn.hnthyy.thmz.service.his.zy.ZyLedgerFileService;
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 java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
public class ZyDepositFileController {
    @Autowired
    private ZyDepositFileService zyDepositFileService;
    @Autowired
    private ZyLedgerFileService zyLedgerFileService;
    @Autowired
    private ZdChequeTypeService zdChequeTypeService;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private ZyActpatientService zyActpatientService;
    @Autowired
    private ZdUnitCodeService zdUnitCodeService;
    @Autowired
    private MzPatientMiService mzPatientMiService;
    /**
     * 根据住院号和次数查询缴费记录
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getZyDepositFileBYInpatientNoAndTimes", method = {RequestMethod.POST})
    public Map<String, Object> getZyDepositFileBYInpatientNoAndTimes(@RequestBody ZyDepositFile zyDepositFile) {
        log.info("根据住院号和次数查询缴费记录");
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (zyDepositFile == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "参数不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(zyDepositFile.getInpatientNo())) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人住院号不能为空");

                return resultMap;
            }
            if (zyDepositFile.getAdmissTimes() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人住院次数不能为空");
                return resultMap;
            }
            resultMap.put("code", 0);
            resultMap.put("message", "根据住院号和次数查询缴费记录成功");
            List<ZyDepositFile> zyDepositFiles = zyDepositFileService.queryZyDepositFileBYInpatientNoAndTimes(zyDepositFile);
            //总支付金额
            BigDecimal totalPay=BigDecimal.ZERO;
            //总退费金额
            BigDecimal totalRefund=BigDecimal.ZERO;
            if(zyDepositFiles!=null && zyDepositFiles.size()>0){
                List<ZdChequeType> zdChequeTypes=zdChequeTypeService.queryAllZdChequeTypeForZy();
                Map<String,String> zdChequeTypeMap=zdChequeTypes.stream().collect(Collectors.toMap(ZdChequeType::getCode,ZdChequeType::getName));
 //               List<ZyLedgerFile> zyLedgerFiles = zyLedgerFileService.queryZyLedgerFileByInpatientNoAndTimes(zyDepositFile.getInpatientNo(), zyDepositFile.getAdmissTimes().intValue());
              //  Map<Integer, ZyLedgerFile> zyLedgerFileMap = new HashMap<>();
//                if (zyLedgerFiles != null && zyLedgerFiles.size() > 0) {
//                    for (ZyLedgerFile zyLedgerFile : zyLedgerFiles) {
//                        zyLedgerFileMap.put(zyLedgerFile.getLedgerSn(), zyLedgerFile);
//                    }
//                }
                ZyLedgerFile lastZyLedgerFile=zyLedgerFileService.queryLastLedgerSn(zyDepositFile.getInpatientNo(),zyDepositFile.getAdmissTimes().intValue());
                for (ZyDepositFile zdf:zyDepositFiles){
                    zdf.setStatusName(ZyDepositFileStatusEnum.geteZyDepositFileStatusByCode(zdf.getStatus()).name);
//                    if(StringUtils.isNotBlank(zdf.getStatus())){
//                        String status = zdf.getStatus().trim();
//                        ZyLedgerFile zlf = zyLedgerFileMap.get(zdf.getLedgerSn());
//                        if(ZyDepositFile.PAY_STATUS.equals(status)){
//                            zdf.setStatusName("预交");
//                            totalPay=totalPay.add(zdf.getDepoAmount());
//                        }else if(ZyDepositFile.REFUND_STATUS.equals(status)){
//                            if(zlf==null || zlf.getAccountDate()==null || zlf.getAccountDate().after(zdf.getDepoDate())){
//                                zdf.setStatusName("直退");
//                            }else {
//                                zdf.setStatusName("结算退款");
//                            }
//                            totalRefund=totalRefund.add(zdf.getDepoAmount());
//                        }else if(ZyDepositFile.HAND_OVER_STATUS.equals(status)){
//                            zdf.setStatusName("结算补交");
//                        }else{
//                            zdf.setStatusName("未知事物");
//                        }
//                    }
                    //设置账页的结算状态到支付信息，做退费控制
                    zdf.setSettleType(lastZyLedgerFile.getSettleType());
                    zdf.setDepoTypeName(zdChequeTypeMap.get(zdf.getDepoType()));
                    Employee opEmployee = employeeService.queryByUserCode(zdf.getOpIdCode());
                    if (opEmployee != null) {
                        zdf.setOpIdName(opEmployee.getEmployeeName());
                    }
                }
            }
            resultMap.put("data", zyDepositFiles);
            resultMap.put("totalPay", totalPay);
            resultMap.put("totalRefund", totalRefund);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "根据住院号和次数查询缴费记录出错，请联系管理员");
            log.error("根据住院号和次数查询缴费记录异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }




    /**
     * 保存住院收费或者退费
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/saveZyDepositFile", method = {RequestMethod.POST})
    public Map<String, Object> saveZyDepositFile(@RequestBody ZyDepositFile zyDepositFile, HttpServletRequest httpServletRequest) {
        log.info("保存住院收费或者退费");
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (zyDepositFile == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "参数不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(zyDepositFile.getStatus())) {
                resultMap.put("code", -1);
                resultMap.put("message", "事务类型不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(zyDepositFile.getDepoType())) {
                resultMap.put("code", -1);
                resultMap.put("message", "支付方式不能为空");
                return resultMap;
            }
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            zyDepositFile.setOpIdCode(tokenUser.getUserIdCode());
            //缴费
            if(ZyDepositFileStatusEnum.PREPAY.code.equals(zyDepositFile.getStatus())){
                if (StringUtils.isBlank(zyDepositFile.getInpatientNo())) {
                    resultMap.put("code", -1);
                    resultMap.put("message", "病人住院号不能为空");

                    return resultMap;
                }
                if (zyDepositFile.getDepoAmount() == null) {
                    resultMap.put("code", -1);
                    resultMap.put("message", "缴费金额不能为空");
                    return resultMap;
                }
            }else if(ZyDepositFileStatusEnum.STRAIGHT_BACK.code.equals(zyDepositFile.getStatus())){
                ZyDepositFile dbZyDepositFile=zyDepositFileService.queryZyDepositFileByReceiptNo(zyDepositFile.getReceiptNo());
                if(dbZyDepositFile==null){
                    resultMap.put("code", -1);
                    resultMap.put("message", "当前退费的收据号不存在。");
                    return resultMap;
                }
                if(!dbZyDepositFile.getDepoType().equals(zyDepositFile.getDepoType())){
                    resultMap.put("code", -1);
                    resultMap.put("message", "当前退费的退费方式与原收据的付款方式不一致。");
                    return resultMap;
                }
                BigDecimal  depoAmount=zyDepositFileService.querySumDepoAmountByReceiptNo(zyDepositFile.getReceiptNo());
                if(BigDecimal.ZERO.compareTo(depoAmount)==0){
                    zyDepositFileService.modifyReportFlag(zyDepositFile.getReceiptNo());
                    resultMap.put("code", -1);
                    resultMap.put("message", "当前操作的费用已经退过费，请勿重复操作。");
                    return resultMap;
                }
                //退费
                zyDepositFile.setDepoAmount(BigDecimal.ZERO.subtract(dbZyDepositFile.getDepoAmount()));
                zyDepositFile.setInpatientNo(dbZyDepositFile.getInpatientNo());
                zyDepositFile.setAdmissTimes(dbZyDepositFile.getAdmissTimes());
                zyDepositFile.setLedgerSn(dbZyDepositFile.getLedgerSn());
                zyDepositFile.setPrinted(dbZyDepositFile.getPrinted());
            }
            zyDepositFileService.saveZyDepositFile(zyDepositFile);
            resultMap.put("code", 0);
            resultMap.put("message", "操作成功");
            resultMap.put("receiptNo", zyDepositFile.getReceiptNo());
            resultMap.put("zyDepositFile", zyDepositFileService.queryZyDepositFileByReceiptNo(zyDepositFile.getReceiptNo()));
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "保存住院收费或者退费记录出错，请联系管理员");
            log.error("保存住院收费或者退费异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }




    /**
     * 根据流水号查询住院缴费单
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getZyDepositFileByReceiptNo", method = {RequestMethod.GET})
    public Map<String, Object> getZyDepositFileByReceiptNo(@RequestParam("receiptNo") String receiptNo,@RequestParam("inpatientNo") String inpatientNo) {
        log.info("根据流水号查询住院缴费单");
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (StringUtils.isBlank(receiptNo)) {
                resultMap.put("code", -1);
                resultMap.put("message", "流水号不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(inpatientNo)) {
                resultMap.put("code", -1);
                resultMap.put("message", "住院号不能为空");
                return resultMap;
            }
            ZyDepositFile zyDepositFile=zyDepositFileService.queryZyDepositFileByReceiptNo(receiptNo);
            if(zyDepositFile==null){
                resultMap.put("code", -1);
                resultMap.put("message", "流水号对应的缴费记录不存在");
                return resultMap;
            }
            ZyActpatient zyActpatient=zyActpatientService.queryByInpatientNo("zy_actpatient",inpatientNo,zyDepositFile.getAdmissTimes().intValue());
            if(zyActpatient==null){
                resultMap.put("code", -1);
                resultMap.put("message", "住院号对应的住院记录不存在");
                return resultMap;
            }
            zyActpatient.setAdmissDept(zdUnitCodeService.queryDeptNameByIdInCache(zyActpatient.getAdmissDept()));
            MzPatientMi mzPatientMi=mzPatientMiService.queryByPatientId(zyActpatient.getMzNo());
            if(mzPatientMi==null){
                resultMap.put("code", -1);
                resultMap.put("message", "门诊病人不存在");
                return resultMap;
            }

            ZdChequeType zdChequeType=zdChequeTypeService.queryChequeTypeByCode(zyDepositFile.getDepoType());
            if(zdChequeType==null){
                resultMap.put("code", -1);
                resultMap.put("message", "支付方式不存在");
                return resultMap;
            }
            Employee employee=employeeService.queryByUserCode(zyDepositFile.getOpIdCode());
            if(employee==null){
                resultMap.put("code", -1);
                resultMap.put("message", "操作员不存在");
                return resultMap;
            }
            resultMap.put("code", 0);
            resultMap.put("message", "根据流水号查询住院缴费单成功");
            resultMap.put("data", zyDepositFile);
            resultMap.put("zdChequeType", zdChequeType);
            resultMap.put("zyActpatient", zyActpatient);
            resultMap.put("mzPatientMi", mzPatientMi);
            resultMap.put("employee", employee);
            resultMap.put("depoAmountDx", NumberToCN.number2CNMontrayUnit(zyDepositFile.getDepoAmount().setScale(2, BigDecimal.ROUND_HALF_UP)));
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "根据流水号查询住院缴费单出错，请联系管理员");
            log.error("根据流水号查询住院缴费单异常，错误信息{}", e.getMessage());
            return resultMap;
        }
    }






    /**
     * 打印住院缴费单
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/printZyDepositFile", method = {RequestMethod.GET})
    public Map<String, Object> printZyDepositFile(@RequestParam("receiptNo") String receiptNo) {
        log.info("打印住院缴费单");
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (StringUtils.isBlank(receiptNo)) {
                resultMap.put("code", -1);
                resultMap.put("message", "流水号不能为空");
                return resultMap;
            }
            zyDepositFileService.modifyPrinted(receiptNo);
            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 = "/cancelCashi", method = {RequestMethod.GET})
    public Map<String, Object> cancelCashi(@RequestParam("inpatientNo") String inpatientNo,@RequestParam("admissTimes") Integer admissTimes, HttpServletRequest httpServletRequest) {
        log.info("根据流水号查询住院缴费单");
        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;
            }
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            zyDepositFileService.cancelCashi(tokenUser.getUserIdCode(),inpatientNo,admissTimes);
            resultMap.put("code", 0);
            resultMap.put("message", "费用冲消成功");
            return resultMap;
        } catch (MzException e) {
            resultMap.put("code", -1);
            resultMap.put("message", e.getMessage());
            log.error("费用冲消异常，错误信息{}", e.getMessage());
            return resultMap;
        } catch (Exception e1) {
            e1.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "费用冲消出错，请联系管理员");
            log.error("费用冲消异常，错误信息{}", e1.getMessage());
            return resultMap;
        }
    }



    /**
     * 住院费用出纳处理
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/teller", method = {RequestMethod.POST})
    public Map<String, Object> teller(@RequestBody List<ZyDepositFile> zyDepositFiles, HttpServletRequest httpServletRequest) {
        log.info("根据流水号查询住院缴费单");
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (zyDepositFiles==null || zyDepositFiles.size()==0) {
                resultMap.put("code", -1);
                resultMap.put("message", "费用支付渠道不能为空");
                return resultMap;
            }
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            zyDepositFileService.teller(tokenUser.getUserIdCode(),zyDepositFiles);
            resultMap.put("code", 0);
            resultMap.put("message", "出纳处理成功");
            return resultMap;
        } catch (MzException e) {
            resultMap.put("code", -1);
            resultMap.put("message", e.getMessage());
            log.error("出纳处理异常，错误信息{}", e.getMessage());
            return resultMap;
        } catch (Exception e1) {
            e1.printStackTrace();
            resultMap.put("code", -1);
            resultMap.put("message", "出纳处理出错，请联系管理员");
            log.error("出纳处理异常，错误信息{}", e1.getMessage());
            return resultMap;
        }
    }
}
