package thyyxxk.webserver.controller.medicalinsurance;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import thyyxxk.webserver.config.auth.PassToken;
import thyyxxk.webserver.config.exception.BizException;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.constants.sidicts.MdtrtCertType;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.markmtfees.ModifyFundAmt;
import thyyxxk.webserver.entity.markmtfees.SiMzBusinessParams;
import thyyxxk.webserver.entity.medicalinsurance.onlinepayment.EcToken;
import thyyxxk.webserver.entity.medicalinsurance.outpatient.MzPatientInfo;
import thyyxxk.webserver.entity.medicalinsurance.outpatient.SpcChrDiseAcct;
import thyyxxk.webserver.entity.medicalinsurance.query.BscQryPrm;
import thyyxxk.webserver.entity.medicalinsurance.query.PsnBaseInfo;
import thyyxxk.webserver.entity.medicalinsurance.query.QryPsnBsInfo;
import thyyxxk.webserver.entity.medicalinsurance.setlinfo.FundDetail;
import thyyxxk.webserver.service.medicalinsurance.SiMzService;
import thyyxxk.webserver.service.medicalinsurance.SiQueryService;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.StringUtil;
import thyyxxk.webserver.utils.TokenUtil;

import java.util.*;

@Slf4j
@RestController
@RequestMapping("/markMtFees")
public class MarkMtFeesController {
    private final SiMzService mzService;
    private final SiQueryService queryService;

    @Autowired
    public MarkMtFeesController(SiMzService mzService, SiQueryService queryService) {
        this.mzService = mzService;
        this.queryService = queryService;
    }

    /**
     * THMZ调用试算
     * */
    @PassToken
    @PostMapping("/preSettle")
    public Map<String, Object> preSettle(@RequestBody SiMzBusinessParams param) {
        MzPatientInfo mz = new MzPatientInfo();
        mz.setPatNo(param.getPatientId());
        mz.setTimes(param.getTimes());
        mz.setStaffId(param.getStaffId());
        mz.setAcctUsedFlag(param.getAcctUsedFlag());
        ResultVo<FundDetail> result = mzService.outpatientPreSettlement(mz);
        return getStringObjectMap(param, result, "收费窗口门诊统筹试算");
    }

    /**
     * THMZ调用结算
     * */
    @PassToken
    @PostMapping("/calculateCost")
    public Map<String, Object> settlement(@RequestBody SiMzBusinessParams param) {
        MdtrtCertType mdtrtCertType = MdtrtCertType.get(param.getReadCardType());
        if(mdtrtCertType == null) {
            throw new BizException("请先读卡！");
        }
        MzPatientInfo mz = new MzPatientInfo();
        mz.setPatNo(param.getPatientId());
        mz.setTimes(param.getTimes());
        mz.setStaffId(param.getStaffId());
        mz.setAcctUsedFlag(param.getAcctUsedFlag());
        mz.setReadCardBizType(param.getReadCardType());
        mz.setReadCardResult(param.getReadCardResult());
        mz.setBusCardInfo(param.getBusCardInfo());
        mz.setMdtrtCertType(mdtrtCertType.getLabel());
        ResultVo<FundDetail> result = mzService.outpatientSettlement(mz);
        return getStringObjectMap(param, result, "收费窗口门诊统筹结算");
    }

    /**
     * THMZ调用取消结算
     * */
    @PassToken
    @PostMapping("/retractFees")
    public Map<String, Object> revokeSettlement(@RequestBody SiMzBusinessParams param) {
        MzPatientInfo mz = new MzPatientInfo();
        mz.setPatNo(param.getPatientId());
        mz.setTimes(param.getTimes());
        mz.setStaffId(param.getStaffId());
        mz.setNeedRevokeRegistration(1);
        mz.setRevokeRegistration(true);
        ResultVo<FundDetail> result = mzService.revokeOutpatientSettlement(mz);
        mzService.insertSiPatInfo(mz);
        return getStringObjectMap(param, result, "处方有修改，撤销门诊统筹结算与登记");
    }

    private Map<String, Object> getStringObjectMap(SiMzBusinessParams param, ResultVo<FundDetail> result, String logText) {
        Map<String, Object> map = new HashMap<>();
        if (!Objects.equals(result.getCode(), ExceptionEnum.SUCCESS.getCode())) {
            map.put("code", -2);
            map.put("msg", result.getMessage());
            log.info("{}：参数：{}，结果：{}", logText, param, map);
            return map;
        }
        FundDetail fund = result.getData();
        Map<String, Object> payInfo = new HashMap<>();
        payInfo.put("totalCost", fund.getTotalCost());
        payInfo.put("fundPay", fund.getFundPay());
        payInfo.put("cashPay", fund.getCashPay());
        payInfo.put("acctPay", fund.getAcctPay());
        payInfo.put("selfPay", fund.getSelfPay());
        payInfo.put("cardType", fund.getCardType());
        map.put("code", 0);
        map.put("msg", "成功。");
        map.put("payInfo", payInfo);
        log.info("{}：参数：{}，结果：{}", logText, param, map);
        return map;
    }

    @PassToken
    @PostMapping("/queryInsuinfo")
    public Map<String, Object> queryInsuinfo(@RequestBody SiMzBusinessParams param) {
        log.info("门诊查询参保信息：{}", JSONObject.toJSON(param));
        return mzService.queryInsuinfo(param);
    }

    @PassToken
    @PostMapping("/directRegistration")
    public Map<String, Object> directRegistration(@RequestBody SiMzBusinessParams param) {
        log.info("门诊共济：{}", param);
        ResultVo<FundDetail> result = mzService.directRegistration(param);
        return getStringObjectMap(param, result, "医生保存处方试算");
    }

    @PassToken
    @PostMapping("/mzgjAfterModifyReceipt")
    public Map<String, Object> mzgjAfterModifyReceipt(@RequestBody SiMzBusinessParams param) {
        log.info("修改/删除处方后再次门诊共济：{}", param);
        ResultVo<FundDetail> result = mzService.mzgjAfterModifyReceipt(param);
        return getStringObjectMap(param, result, "医生保存处方试算");
    }

    @PassToken
    @PostMapping("/ybRegForRx")
    public ResultVo<FundDetail> ybRegForRx(@RequestBody SiMzBusinessParams params) {
        params.setAbortBeforeUploadFees(true);
        if (StringUtil.isBlank(params.getStaffId())) {
            params.setStaffId(TokenUtil.getInstance().getTokenUserId());
        }
        mzService.queryInsuinfo(params);
        return mzService.ybRegForRx(params);
    }

    @PassToken
    @GetMapping("/isPatientDuringSiSettle")
    public Map<String, Object> isPatientDuringSiSettle(@RequestParam("patientId") String patientId) {
        ResultVo<Integer> resvo = mzService.isPatientDuringSiSettle(patientId);
        Map<String, Object> map = new HashMap<>();
        if (resvo.getData() == 1) {
            map.put("code", -1);
            map.put("msg", "此患者正处于医保统筹进程中，请稍候。");
        } else {
            map.put("code", 0);
            map.put("msg", "OK");
        }
        return map;
    }

    @PassToken
    @PostMapping("/queryModifyPermission")
    public ResultVo<String> queryModifyPermission(@RequestBody MzPatientInfo info) {
        String result = mzService.queryModifyPermission(info);
        log.info("查询是否有修改医保处方的权限：[{}, {}, {}]，结果：{}",
                info.getPatNo(), info.getTimes(), info.getStaffId(), result);
        if (result.equals("OK")) {
            return ResultVoUtil.success(result);
        }
        return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, result);
    }

    @PassToken
    @PostMapping("/modifyFundPayAmount")
    public Map<String, Object> modifyFundPayAmount(@RequestBody ModifyFundAmt modifyFundAmt) {
        return mzService.modifyFundPayAmount(modifyFundAmt);
    }

    @PassToken
    @PostMapping("/payOnline")
    public ResultVo<String> payOnline(@RequestBody EcToken token) {
        return ResultVoUtil.success(token.getEcToken());
    }

    /**
     * 查询慢特病备案
     * */
    @PassToken
    @PostMapping("/scdRecord")
    public ResultVo<List<SpcChrDiseAcct>> scdRecord(@RequestBody BscQryPrm bscQryPrm) {
        if (StringUtil.isBlank(bscQryPrm.getReadCardResult())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "读卡内容不能为空，请先读卡！");
        }

        JSONObject obj = JSONObject.parseObject(bscQryPrm.getReadCardResult());
        String idNo = obj.getString("idNo");
        String insuOrg = obj.getString("insuOrg");
        bscQryPrm.setSocialNo(idNo);
        bscQryPrm.setAdmdvs(insuOrg);

        QryPsnBsInfo qryPsnBsInfo = new QryPsnBsInfo();
        qryPsnBsInfo.setReadCardResult(bscQryPrm.getReadCardResult());
        qryPsnBsInfo.setBusCardInfo(bscQryPrm.getBusCardInfo());
        qryPsnBsInfo.setMdtrtCertType(bscQryPrm.getMdtrtCertType());
        qryPsnBsInfo.setOnlyQry(1);
        qryPsnBsInfo.setPatNo(bscQryPrm.getPatNo());
        qryPsnBsInfo.setTimes(bscQryPrm.getTimes());
        ResultVo<PsnBaseInfo> psnRes = queryService.obtainBasicPersonInfo(qryPsnBsInfo);

        if (!Objects.equals(psnRes.getCode(), ExceptionEnum.SUCCESS.getCode())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, psnRes.getMessage());
        }
        bscQryPrm.setPsnNo(psnRes.getData().getPsnNo());
        return queryService.querySpecialChronicDiseasesAccreditation(bscQryPrm);
    }

}
