package com.saye.hospitalgd.scheduler.jobMethod;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
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.entity.BankbillHistory;
import com.saye.hospitalgd.service.BankbillGetinfoService;
import com.saye.hospitalgd.service.BankbillHistoryService;
import com.saye.hospitalgd.service.ThirdSftpConfigService;
import com.saye.hospitalgd.service.impl.BankbillGetinfoServiceImpl;
import com.saye.hospitalgd.service.impl.BankbillHistoryServiceImpl;
import com.saye.hospitalgd.service.impl.ThirdSftpConfigServiceImpl;
import com.saye.hospitalgd.service.system.ServiceParamsService;
import com.saye.hospitalgd.service.system.impl.ServiceParamsServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * @author thuang
 * @version 1.0
 * @description: 获取商户POS通对账单 调用dmz服务器部署的接口
 * @date 2021/9/13 14:46
 */
@Slf4j
public class BankGetDataMethodByJHLZF {

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

        BankbillHistoryService bankbillHistoryService = GetBeanUtil.getBean(BankbillHistoryServiceImpl.class);

        BankbillGetinfoService bankbillGetinfoService = GetBeanUtil.getBean(BankbillGetinfoServiceImpl.class);

        ServiceParamsService serviceParamsService = GetBeanUtil.getBean(ServiceParamsServiceImpl.class);
        ThirdSftpConfigService thirdSftpConfigService = GetBeanUtil.getBean(ThirdSftpConfigServiceImpl.class);

        boolean isOk = false;


        //重新执行最多10次 还没获取到肯定有问题 不执行了
        //如果有传入时间 那就只执行一次 获取不到就还是获取不到
        int num = "".equals(trade_date) ? 0 : 9;
        while (!isOk && num < 10) {
            num++;

            String dateStr = "";
            //如果有传入时间 那就使用传入时间
            if ("".equals(trade_date)) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(new Date());
                calendar.add(Calendar.DATE, -1);
                Date time = calendar.getTime();

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


            //开始请求海南外联接口，生成账单文件

            String cust_id = StringDUtil.changeNullToEmpty(map.get("CUST_ID"));
            String user_id = StringDUtil.changeNullToEmpty(map.get("USER_ID"));
            String tx_code = StringDUtil.changeNullToEmpty(map.get("TX_CODE"));
            String password = StringDUtil.changeNullToEmpty(map.get("PASSWORD"));
            String language = StringDUtil.changeNullToEmpty(map.get("LANGUAGE"));
            String wlip = StringDUtil.changeNullToEmpty(map.get("WLIP"));
            String wlport = StringDUtil.changeNullToEmpty(map.get("WLPORT"));

            String requset_sn_sc = String.valueOf(System.currentTimeMillis());

            log.info("传去的时间是dateStr：" + dateStr);
            String requestXml = "<?xml version=\"1.0\" encoding=\"GB2312\" standalone=\"yes\" ?>  \n" +
                    "<TX>   \n" +
                    "  <REQUEST_SN>" + requset_sn_sc + "</REQUEST_SN>  \n" +
                    "  <CUST_ID>" + cust_id + "</CUST_ID>  \n" +
                    "  <USER_ID>" + user_id + "</USER_ID>  \n" +
                    "  <PASSWORD>" + password + "</PASSWORD>  \n" +
                    "  <TX_CODE>" + tx_code + "</TX_CODE>  \n" +
                    "  <LANGUAGE>" + language + "</LANGUAGE>  \n" +
                    "  <TX_INFO>  \n" +
                    "    <DATE>" + dateStr + "</DATE>  \n" +
                    "    <KIND>1</KIND>  \n" +
                    "    <FILETYPE>1</FILETYPE>  \n" +
                    "    <TYPE></TYPE>  \n" +
                    "    <NORDERBY></NORDERBY>  \n" +
                    "    <POS_CODE></POS_CODE>  \n" +
                    "    <ORDER></ORDER>  \n" +
                    "    <STATUS></STATUS>  \n" +
                    "    <BILL_FLAG></BILL_FLAG>  \n" +
                    "    <Mrch_No></Mrch_No>  \n" +
                    "    <GROUP_FLAG></GROUP_FLAG>  \n" +
                    "    <TXN_TPCD></TXN_TPCD>  \n" +
                    "  </TX_INFO>  \n" +
                    "</TX> ";
            String params = "requestXml=" + requestXml;
            String ipAdress = wlip + ":" + wlport;
            log.info("拼接的ip是：" + ipAdress);
            String fileName = "";

            try {
                URI uri = new URI(ipAdress.trim());
                CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
                HttpPost httpPost = new HttpPost(uri);
                httpPost.setHeader("content-type", "application/x-www-form-urlencoded");
                httpPost.setHeader("Connection", "close");
                StringEntity entity = new StringEntity(params, "GB18030");
                log.info("发送的数据是entity：" + entity);
                httpPost.setEntity(entity);

                CloseableHttpResponse response = closeableHttpClient.execute(httpPost);
                String s = EntityUtils.toString(response.getEntity(), "GB18030");
                log.info("接受到的数据是s：" + s);
                Document document = DocumentHelper.parseText(s);

                Iterator iterator = document.nodeIterator();


                Element tx = (Element) iterator.next();
                Element return_code_F = tx.element("RETURN_CODE");
                Element return_msg_F = tx.element("RETURN_MSG");
                if (return_code_F != null) {
                    if (!return_code_F.getText().equals("000000")) {
                        errCode = "999";
                        errMsg = return_msg_F.getText();
                        log.info("获取到的返回code是" + return_code_F);
                    } else {
                        Iterator tx_info = tx.elementIterator("TX_INFO");
                        Element txInfo = (Element) tx_info.next();

                        Element file_name = txInfo.element("FILE_NAME");
                        fileName = file_name.getText();

                        boolean exist = FileUtil.exist("C:" + File.separator + "CCB_EBSClient" + File.separator + "download" + File.separator + fileName);

                        Boolean fileIsExist = false;

                        if (!exist) { //文件不存在开始下载
                            HashMap<Object, Object> searchMap = new HashMap<>();
                            searchMap.put("FUBS", "2");
                            List<HashMap<Object, Object>> wlConfigList = thirdSftpConfigService.findWLIF(searchMap);
                            HashMap<Object, Object> configMap = wlConfigList.get(0);
                            String txCode = StringDUtil.changeNullToEmpty(configMap.get("TX_CODE"));
                            String filepath = StringDUtil.changeNullToEmpty(configMap.get("FILEPATH"));
                            String requset_sn_xz = String.valueOf(System.currentTimeMillis());
                            String re = "<?xml version=\"1.0\" encoding=\"GB2312\" standalone=\"yes\" ?> \n" +
                                    "<TX> \n" +
                                    "  <REQUEST_SN>" + requset_sn_xz + "</REQUEST_SN>  \n" +
                                    "  <CUST_ID>" + cust_id + "</CUST_ID>  \n" +
                                    "  <USER_ID>" + user_id + "</USER_ID>  \n" +
                                    "  <PASSWORD>" + password + "</PASSWORD>  \n" +
                                    "  <TX_CODE>" + txCode + "</TX_CODE>  \n" +
                                    "  <LANGUAGE>CN</LANGUAGE>  \n" +
                                    "  <TX_INFO> \n" +
                                    "    <SOURCE>" + fileName + "</SOURCE>  \n" +
                                    "    <FILEPATH>" + filepath + "</FILEPATH>  \n" +
                                    "    <LOCAL_REMOTE>0</LOCAL_REMOTE>  \n" +
                                    "  </TX_INFO> \n" +
                                    "</TX> \n";
                            String ps = "requestXml=" + re;

                            Element return_code = null;
                            Element return_msg = null;
                            URI uri_d = new URI(ipAdress.trim());
                            CloseableHttpClient closeableHttpClientD = HttpClients.createDefault();
                            HttpPost httpPostD = new HttpPost(uri_d);
                            httpPostD.setHeader("content-type", "application/x-www-form-urlencoded");
                            httpPostD.setHeader("Connection", "close");
                            StringEntity entityD = new StringEntity(ps, "GB18030");
                            httpPost.setEntity(entityD);

                            CloseableHttpResponse responseD = closeableHttpClientD.execute(httpPost);
                            String s_d = EntityUtils.toString(responseD.getEntity(), "GB18030");
                            log.info("s_d is :" + s_d);
                            Document documentD = DocumentHelper.parseText(s_d);
                            Iterator iteratorD = documentD.nodeIterator();
                            Element txD = (Element) iteratorD.next();
                            return_code = txD.element("RETURN_CODE");
                            return_msg = txD.element("RETURN_MSG");
                            if (return_code != null) {
                                if (!return_code.getText().equals("000000")) {
                                    errCode = "999";
                                    errMsg = return_msg.getText();
                                    log.info("获取到的返回code是" + return_code);
                                } else {//下载成功了
                                    fileIsExist = true;
                                }
                            }
                        }
                        if (fileIsExist || exist) { //确定文件存在，开始读取数据
                            String filePath = "C:" + File.separator + "CCB_EBSClient" + File.separator + "download" + File.separator + fileName;
                            List<String> txtList = null;
                            FileInputStream stream = new FileInputStream(filePath);

                            ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(stream), Charset.forName("GBK"));

//                            ZipEntry ze = null;

                            ZipEntry nextEntry = zipInputStream.getNextEntry();
                            log.info("读取的文件是" + nextEntry);

                            BufferedReader br = new BufferedReader(new InputStreamReader(zipInputStream, StandardCharsets.UTF_8));

                            String line;
                            txtList = new ArrayList<>();
                            //内容不为空，输出
                            while ((line = br.readLine()) != null) {
                                txtList.add(line);
                            }
                            log.info("继续执行程序3");
                            List<BankbillHistory> bankbillHistoryList = new ArrayList<>();
                            for (int i = 2; i < txtList.size(); i++) {
                                String d = txtList.get(i);

                                String[] s1 = d.split("\t");

                                if (!StrUtil.contains(s1[4].trim(), "ZZJ")) {
                                    continue;
                                }

                                BankbillHistory bankbillHistory = new BankbillHistory();

                                String[] split = s1[0].split(" ");

                                // 设置BankbillHistory的字段
                                bankbillHistory.setCJyrq(split[0]);                    // 交易日期
                                bankbillHistory.setCJysj(split[1]);                    // 交易时间
                                bankbillHistory.setCQsrq(s1[1]);                      // 清算日期
                                bankbillHistory.setCLsh(s1[2]);                       // 流水号
                                bankbillHistory.setCShddh(s1[3]);                     // 商户订单号
                                bankbillHistory.setCYsddh(s1[4]);                     // 银商订单号
                                bankbillHistory.setCJyje(s1[9]);                      // 交易金额
                                bankbillHistory.setCSxf(s1[10]);                      // 手续费
                                bankbillHistory.setCJylx(s1[15]);                     // 交易类型
                                
                                // 设置默认值
                                bankbillHistory.setCQsje(s1[9]);                      // 清算金额 = 交易金额
                                bankbillHistory.setCSjzfje(s1[9]);                    // 实际支付金额 = 交易金额
                                bankbillHistory.setCCkh(s1[2]);                       // 参考号 = 流水号
                                bankbillHistory.setCCard("");                         // 卡号（空）
                                bankbillHistory.setCKlx("");                         // 卡类型（空）
                                bankbillHistory.setCFkh(s1[13]);                     // 发卡行 = 付款行
                                bankbillHistory.setCZffs("建行龙支付");                // 支付方式
                                bankbillHistory.setCBzzd("");                        // 备注字段（空）
                                bankbillHistory.setCQbyhje("0");                     // 钱包优惠金额
                                bankbillHistory.setCShyhje("0");                     // 商户优惠金额
                                bankbillHistory.setCYjylsh("");                      // 原交易流水号（空）
                                bankbillHistory.setCFqqs("");                        // 分期期数（空）
                                bankbillHistory.setCFqsxf("0");                      // 分期手续费
                                bankbillHistory.setCFqfwf("");                       // 分期服务方（空）
                                bankbillHistory.setCFqfxf("");                       // 分期付息方（空）
                                bankbillHistory.setCQtyhje("0");                     // 其他优惠金额
                                bankbillHistory.setCThddh("");                       // 退货订单号（空）
                                bankbillHistory.setCFkfy("");                        // 付款附言（空）
                                bankbillHistory.setCFdjc("");                        // 分店简称（空）
                                bankbillHistory.setCZddh("");                        // 子订单号（空）
                                bankbillHistory.setBillTableName("建行龙支付对账单");   // 对账表名

                                bankbillHistoryList.add(bankbillHistory);
                            }
                            if (!CollectionUtils.isEmpty(bankbillHistoryList)) {
                                // 先存一份原始的 这份只是留底查询
                                bankbillHistoryService.insertBankBillOriginal(bankbillHistoryList, trade_date, "建行龙支付对账单");
                                // 再存一份修改的用于对账
                                bankbillHistoryService.insertAllBankHistory(bankbillHistoryList, trade_date, "建行龙支付对账单");
                                isOk = true;
                            } else {
                                errCode = "999";
                                errMsg = "未查询到数据";
                                isOk = false;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                errCode = "999";
                if (StringUtils.isEmpty(errMsg)) {
                    errMsg = "外联平台接口调用失败！！！";
                }
                e.printStackTrace();
            }
            //海南外联接口调用成功后会生成账单文件，在请求一次外联接口下载到服务器。
            log.info("继续执行程序4");
            //记录数据获取记录
            HashMap<Object, Object> addMap = new HashMap<>();
            addMap.put("trade_date", trade_date);
            addMap.put("quartz_id", id);
            addMap.put("quartz_name", name);
            addMap.put("bill_table_name", fileName);
            addMap.put("thirdConfigId", "999");

            if (isOk) {
                addMap.put("is_ok", "1");
            } else {
                addMap.put("is_ok", "0");
            }
            addMap.put("modify_time", DateDUtil.getCurrentDate(DateDUtil.yyyy_MM_dd_HH_mm_ss));
            bankbillGetinfoService.insertBankbillGetinfo(addMap);

            //判断是否成功 如果失败 执行休眠一小时
            if (!isOk && num < 10) {
                try {
                    //记录日志
                    LogUtil.error(this.getClass(), errMsg);

                    System.out.println("获取对账记录没有成功，1小时后重新执行");
                    Thread.sleep(1000 * 60 * 60);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        resultMap.put("errCode", errCode);
        resultMap.put("errMsg", errMsg);

        return resultMap;
    }


}
