package com.saye.hospitalgd.scheduler.jobMethod;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.saye.hospitalgd.commons.date.DateDUtil;
import com.saye.hospitalgd.commons.getBean.GetBeanUtil;
import com.saye.hospitalgd.commons.log.LogUtil;
import com.saye.hospitalgd.commons.string.StringDUtil;
import com.saye.hospitalgd.model.Dicinfo;
import com.saye.hospitalgd.service.HisDetailService;
import com.saye.hospitalgd.service.HisInterFaceConfigService;
import com.saye.hospitalgd.service.OperatorService;
import com.saye.hospitalgd.service.historyLog.HisBillLogService;
import com.saye.hospitalgd.service.historyLog.impl.HisBillLogServiceImpl;
import com.saye.hospitalgd.service.impl.HisDetailServiceImpl;
import com.saye.hospitalgd.service.impl.HisInterFaceConfigServiceImpl;
import com.saye.hospitalgd.service.impl.OperatorServiceImpl;
import com.saye.hospitalgd.service.system.DicinfoService;
import com.saye.hospitalgd.service.system.ServiceParamsService;
import com.saye.hospitalgd.service.system.impl.DicinfoServiceImpl;
import com.saye.hospitalgd.service.system.impl.ServiceParamsServiceImpl;
import com.saye.hospitalgd.util.HisUtil;
import org.dom4j.Element;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author thuang
 * @version 1.0
 * @description: His获取数据方法（卫宁）
 * @date 2021/9/30 13:41
 */
public class HISGetDataMethodByWN {

    public HashMap<Object,Object> getDate(String id,String name,String trade_date,String his_wsdl_id){
        HashMap<Object,Object> responseMap=new HashMap<>();
        String errCode="0";
        String errMsg="";

        HisBillLogService hisBillLogService = GetBeanUtil.getBean(HisBillLogServiceImpl.class);
        HisDetailService hisDetailService = GetBeanUtil.getBean(HisDetailServiceImpl.class);
        OperatorService operatorService = GetBeanUtil.getBean(OperatorServiceImpl.class);
        DicinfoService dicinfoService = GetBeanUtil.getBean(DicinfoServiceImpl.class);

        ServiceParamsService serviceParamsService = GetBeanUtil.getBean(ServiceParamsServiceImpl.class);

        HisInterFaceConfigService hisInterFaceConfigService = GetBeanUtil.getBean(HisInterFaceConfigServiceImpl.class);

        try {
            //查询需要用到的参数

            //his接口地址
            List<HashMap<Object, Object>> hisConfigList = hisInterFaceConfigService.findConfigById(his_wsdl_id);
            String his_wsdl = StringDUtil.changeNullToEmpty(hisConfigList.get(0).get("HIS_INTERFACE_WSDL"));
            String code = StringDUtil.changeNullToEmpty(hisConfigList.get(0).get("CODE"));
            String partner = StringDUtil.changeNullToEmpty(hisConfigList.get(0).get("PARTNER"));
            String sign = StringDUtil.changeNullToEmpty(hisConfigList.get(0).get("SIGN"));
            String operid = StringDUtil.changeNullToEmpty(hisConfigList.get(0).get("OPERID"));
            String password = StringDUtil.changeNullToEmpty(hisConfigList.get(0).get("PASSWORD"));
            String kfsdm = StringDUtil.changeNullToEmpty(hisConfigList.get(0).get("KFSDM"));

            //现金支付方式
            List<HashMap<Object, Object>> serviceParams = serviceParamsService.findParamValByParamCode("cash_code");
            String cash_code = StringDUtil.changeNullToEmpty(serviceParams.get(0).get("PARAM_VAL"));

            //his端其他支付方式 也单独处理 因为里面没有唯一id 且都是支票记录
            String zhipiao="5";

            //操作员号
            List<HashMap<Object,Object>> operators = operatorService.findAllOperator(new HashMap<Object,Object>());
            //将操作员号用逗号连接
            String operatorsCodeStr="";
            for (int i = 0; i < operators.size(); i++) {
                HashMap<Object, Object> hashMap = operators.get(i);
                operatorsCodeStr =operatorsCodeStr + StringDUtil.changeNullToEmpty(hashMap.get("HISOPERCODE")) + ",";
            }
            if (operatorsCodeStr.length()>0){
                operatorsCodeStr=operatorsCodeStr.substring(0,operatorsCodeStr.length()-1);
            }

            //全部支付方式
            List<Dicinfo> pay_type = dicinfoService.findDicinfoTreeNodeList("PAY_TYPE");
            HashMap<String,String> payTypeMap=new HashMap<>();
            for (Dicinfo dicinfo : pay_type) {
                payTypeMap.put( dicinfo.getDicname(),dicinfo.getDicvalue());
            }


            //开始结束时间
            String startTime="";
            String endTime="";
            if ("".equals(trade_date)) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -1);
                Date time = calendar.getTime();

                startTime = DateDUtil.DateToStr(DateDUtil.yyyyMMdd, time);
                endTime = startTime;
                trade_date=DateDUtil.DateToStr(DateDUtil.yyyy_MM_dd, time);
            }else {
                Date date = DateDUtil.strToDate(DateDUtil.yyyy_MM_dd, trade_date);

                startTime = DateDUtil.DateToStr(DateDUtil.yyyyMMdd,date);
                endTime = startTime;
            }

            String timestamp = DateDUtil.getCurrentDate(DateDUtil.yyyyMMddHHmmss);

            //组织request
            String requestStr="";
            requestStr="<request>" +
                    " <partner>"+ partner +"</partner>" +
                    " <sign>"+sign+"</sign>" +
                    " <timestamp>"+timestamp+"</timestamp>" +
                    " <operid>"+operid+"</operid>" +
                    " <password>"+password+"</password>" +
                    " <kfsdm>"+kfsdm+"</kfsdm>" +
                    " <params>" +
                    " <ksrq>"+startTime+"</ksrq>" +
                    " <jsrq>"+endTime+"</jsrq>" +
                    " <czyh></czyh>" +
                    "</params>" +
                    "</request>";

            //获取数据
            HisUtil hisUtil = new HisUtil();
            HashMap<String, String> histData = hisUtil.getHisDataByWN(his_wsdl, code, requestStr);

            errCode = histData.get("errCode");
            if (!"0".equals(errCode)){
                errMsg=histData.get("errMsg");
            }else {
                String dataStr = histData.get("dataStr");

                //分析数据，判断调用正确与否
                HashMap<String, Object> hisBillResult = hisUtil.managerDataStrByWN(dataStr);
                errCode = StringDUtil.changeNullToEmpty(hisBillResult.get("errCode"));
                if (!"0".equals(errCode)){
                    errMsg=StringDUtil.changeNullToEmpty(hisBillResult.get("errMsg"));
                }else {
                    List<HashMap<Object,Object>> hisBillList  = (List<HashMap<Object,Object>>)hisBillResult.get("addList");
                    //存一份his原始的
                    hisDetailService.insertHisBillOriginalWN(hisBillList,trade_date,his_wsdl_id);

                    //将原始的转换成统一格式
                    List<HashMap<Object,Object>> newAddList= new ArrayList<>();

                    List<HashMap<Object,Object>> cashList= new ArrayList<>();

                    List<HashMap<Object,Object>> zhipiaoList= new ArrayList<>();


                    for (int i = 0; i < hisBillList.size(); i++) {
                        HashMap<Object, Object> objectObjectHashMap = hisBillList.get(i);

                        //数据类型 sjlx
                        String payMethod = StringDUtil.changeNullToEmpty(objectObjectHashMap.get("sjlx"));
                        if("门诊".equals(payMethod)){
                            payMethod="1";
                        }else {
                            payMethod="2";
                        }

                        //过滤不需要的数据 当数据类型是住院的时候 345689是不必要的数据。 不会存在于银联商务平台 所以对账不需要这个数据
//                    门诊 sftkjl 0收费，1退费
//                    住院  sftkjl 0：预交金收1：预交金红冲2：结算收退款(包含出院结算收退, 在院结算收)3：在院结算结转4：取消结算结转(取消结算后病人的预交金)5：取消结算红冲6：取消结算收退(对应操作类别2)8：结算收入(发票金额)9：取消结算收入(取消的发票金额)
                        if ("2".equals(payMethod)){
                            String sftkjl = StringDUtil.changeNullToEmpty(objectObjectHashMap.get("sftkjl"));
                            //判断 只要不是这三个的跳过。
                            if (!("0".equals(sftkjl) || "1".equals(sftkjl) || "2".equals(sftkjl))){
                                continue;
                            }
                        }

                        //交易状态
                        String jyje = StringDUtil.changeNullToEmpty(objectObjectHashMap.get("jyje"));
                        String tyje = StringDUtil.changeNullToEmpty(objectObjectHashMap.get("tyje"));
                        String tradingStatus="";
                        if (new BigDecimal(jyje).compareTo(new BigDecimal(0))==0){
                            tradingStatus="2";
                        }else if (new BigDecimal(tyje).compareTo(new BigDecimal(0))==0){
                            tradingStatus="1";
                        }

                        //业务类型
                        //卫宁 交易类型 1 挂号 2 缴费 3 门诊充值 4 住院预交金
                        //统一转成 业务类型1-门诊收费 2-门诊预交 3-住院预交 4-门诊挂号 5-门诊发卡 6-住院结算
                        String bizType = StringDUtil.changeNullToEmpty(objectObjectHashMap.get("jylx"));
                        if ("1".equals(bizType)){
                            bizType="4";
                        }else if ("2".equals(bizType)){
                            bizType="1";
                        }else if ("3".equals(bizType)){
                            bizType="2";
                        }else if("4".equals(bizType)){
                            bizType="3";
                        }

                        //支付方式
                        //中联
//                    -1-其他 0-帐户余额 1-刷卡
//                    2-微信支付 3-支付宝支付
//                    4-聚合支付 5-自助现金 6-云闪付

                        //卫宁 传输的中文
//                        	扫码支付
//                          银行卡支付
//                        	掌医支付
//                        	现金支付
//                        	其他
                        String payType = StringDUtil.changeNullToEmpty(objectObjectHashMap.get("zffs"));
                        //将中文转为字典对应值
                        payType = payTypeMap.get(payType);

                        //交易时间
                        String tradeTime = StringDUtil.changeNullToEmpty(objectObjectHashMap.get("jyrq"));
                        //卫宁的日期格式为yyyyMMddHH:mm:ss 格式化日期为 yyyy-MM-dd HH:mm:ss
                        tradeTime = DateDUtil.DateToStr(DateDUtil.yyyy_MM_dd_HH_mm_ss, DateDUtil.strToDate(DateDUtil.yyyyMMddHH_mm_ss, tradeTime));

                        //操作员号
                        String hisOperCode = StringDUtil.changeNullToEmpty(objectObjectHashMap.get("czyh"));

                        //交易金额
                        String amount="0";
                        if ("1".equals(tradingStatus)){
                            amount=jyje;
                        }else if ("2".equals(tradingStatus)){
                            //退款转为负数
                            amount=new BigDecimal(tyje).negate().toString();
                        }
                        //格式化金额 原先小数四位 有效两位
                        amount = new BigDecimal(amount).setScale(2, BigDecimal.ROUND_HALF_UP).toString();

                        //备注 卫宁直接为空
                        String remarks="";

                        //平台交易号 zflsh
                        String platformTransId = StringDUtil.changeNullToEmpty(objectObjectHashMap.get("zflsh"));

                        //患者标识
                        String patientId = StringDUtil.changeNullToEmpty(objectObjectHashMap.get("patid"));

                        //患者姓名
                        String patientName = StringDUtil.changeNullToEmpty(objectObjectHashMap.get("hzxm"));

                        //交易日期
                        String thistrade_date="";
                        if (tradeTime.length()>10){
                            thistrade_date = tradeTime.substring(0,10);
                        }

                        //接口厂商
                        HashMap<Object,Object> addMap=new HashMap<>();
                        addMap.put("payMethod",payMethod);
                        addMap.put("tradingStatus",tradingStatus);
                        addMap.put("bizType",bizType);
                        addMap.put("payType",payType);
                        addMap.put("tradeTime",tradeTime);
                        addMap.put("hisOperCode",hisOperCode);
                        addMap.put("amount",amount);
                        addMap.put("remarks",remarks);
                        addMap.put("platformTransId",platformTransId);
                        addMap.put("patientId",patientId);
                        addMap.put("patientName",patientName);
                        addMap.put("trade_date",thistrade_date);
                        addMap.put("his_wsdl_id",his_wsdl_id);

                        //如果是现金记录先放进现金集合内
                        if (cash_code.equals(payType)){
                            cashList.add(addMap);
                        }else if (zhipiao.equals(payType)){
                            zhipiaoList.add(addMap);
                        }else{
                            newAddList.add(addMap);
                        }
                    }

                    //循环现金记录 合并同操作员同交易日期 同类别的（门诊，住院） his获取，记录应该就是前一天的。
                    HashMap<String,HashMap<Object,Object>> cashMap=new HashMap<>();
                    for (int i = 0; i < cashList.size(); i++) {
                        HashMap<Object, Object> hashMap = cashList.get(i);

                        String hisOperCode = StringDUtil.changeNullToEmpty(hashMap.get("hisOperCode"));
                        String payMethod = StringDUtil.changeNullToEmpty(hashMap.get("payMethod"));
                        String amount = StringDUtil.changeNullToEmpty(hashMap.get("amount"));

                        HashMap<Object, Object> map = cashMap.get(hisOperCode+"_"+payMethod);

                        if (map==null){
                            HashMap<Object,Object> addMap=new HashMap<>();
                            addMap.put("payMethod",payMethod);
                            addMap.put("tradingStatus","");
                            addMap.put("bizType","");
                            addMap.put("payType",cash_code);
                            addMap.put("tradeTime",trade_date+" 00:00:00");
                            addMap.put("hisOperCode",hisOperCode);
                            addMap.put("amount",amount);
                            addMap.put("remarks","");
                            addMap.put("platformTransId","");
                            addMap.put("patientId","");
                            addMap.put("patientName","");
                            addMap.put("trade_date",trade_date);
                            addMap.put("his_wsdl_id",his_wsdl_id);

                            cashMap.put(hisOperCode+"_"+payMethod,addMap);
                        }else {
                            String oldAmount = StringDUtil.changeNullToEmpty(map.get("amount"));
                            String newAmount = new BigDecimal(oldAmount).add(new BigDecimal(amount)).toString();
                            map.put("amount",newAmount);
                        }
                    }

                    //循环map 把记录放入要添加的集合
                    for (String key:cashMap.keySet()){
                        newAddList.add(cashMap.get(key));
                    }

                    //循环支票的记录 和现金相同处理
                    HashMap<String,HashMap<Object,Object>> zhipiaoMap=new HashMap<>();
                    for (int i = 0; i < zhipiaoList.size(); i++) {
                        HashMap<Object, Object> hashMap = zhipiaoList.get(i);

                        String hisOperCode = StringDUtil.changeNullToEmpty(hashMap.get("hisOperCode"));
                        String payMethod = StringDUtil.changeNullToEmpty(hashMap.get("payMethod"));
                        String amount = StringDUtil.changeNullToEmpty(hashMap.get("amount"));
                        String payType = StringDUtil.changeNullToEmpty(hashMap.get("payType"));

                        HashMap<Object, Object> map = zhipiaoMap.get(hisOperCode+"_"+payMethod);

                        if (map==null){
                            HashMap<Object,Object> addMap=new HashMap<>();
                            addMap.put("payMethod",payMethod);
                            addMap.put("tradingStatus","");
                            addMap.put("bizType","");
                            addMap.put("payType",payType);
                            addMap.put("tradeTime",trade_date+" 00:00:00");
                            addMap.put("hisOperCode",hisOperCode);
                            addMap.put("amount",amount);
                            addMap.put("remarks","");
                            addMap.put("platformTransId","");
                            addMap.put("patientId","");
                            addMap.put("patientName","");
                            addMap.put("trade_date",trade_date);
                            addMap.put("his_wsdl_id",his_wsdl_id);

                            zhipiaoMap.put(hisOperCode+"_"+payMethod,addMap);
                        }else {
                            String oldAmount = StringDUtil.changeNullToEmpty(map.get("amount"));
                            String newAmount = new BigDecimal(oldAmount).add(new BigDecimal(amount)).toString();
                            map.put("amount",newAmount);
                        }
                    }

                    //循环map 把记录放入要添加的集合
                    for (String key:zhipiaoMap.keySet()){
                        newAddList.add(zhipiaoMap.get(key));
                    }

                    //存一份his针对要调整的字段修改的
                    hisDetailService.insertHisBillList(newAddList,trade_date,his_wsdl_id);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            errCode="999";
            errMsg="执行定时任务【"+name+"】出错，原因："+e.getMessage();
        }

        //存储记录
        try {
            HashMap<Object,Object> addMap=new HashMap<>();
            addMap.put("trade_date",trade_date);
            addMap.put("quartz_id",id);
            addMap.put("quartz_name",name);
            addMap.put("his_wsdl_id",his_wsdl_id);

            if ("0".equals(errCode)){
                addMap.put("is_ok","1");
            }else {
                addMap.put("is_ok","0");
            }

            addMap.put("modify_time",DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd_HH_mm_ss));
            hisBillLogService.insertHisbillGetinfo(addMap);

        }catch (Exception e){
            e.printStackTrace();
            errCode="999";
            errMsg="保存His获取的记录失败，原因"+e.getMessage();
        }

        if (!"0".equals(errCode)){
            try {
                //记录日志
                LogUtil.error(this.getClass(), errMsg);

            }catch (Exception e){
                e.printStackTrace();
            }
        }

        responseMap.put("errCode",errCode);
        responseMap.put("errMsg",errMsg);
        return responseMap;
    }

}
