package com.hfkj.channel.lakala;

import com.alibaba.fastjson.JSONObject;
import com.hfkj.channel.lakala.config.LaKaLaConfig;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.DateUtil;
import com.hfkj.common.utils.HttpsUtils;
import com.hfkj.common.utils.ImageUtils;
import com.hfkj.common.utils.UnionUtils;
import com.hfkj.config.CommonSysConst;
import com.hfkj.entity.*;
import com.hfkj.model.MerBasisModel;
import com.hfkj.service.*;
import com.hfkj.sysenum.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 拉卡拉分账
 * @author hurui
 */
@Service
public class LaKaLaTradeSeparateService {

    private static Logger log = LoggerFactory.getLogger(LaKaLaTradeSeparateService.class);

    @Resource
    private BsTradeOrderService tradeOrderService;
    @Resource
    private BsTradeOrderProfitSharingService tradeOrderProfitSharingService;
    @Resource
    private BsTradeOrderProfitSharingReceiverService tradeOrderProfitSharingReceiverService;
    @Resource
    private BsMerService merService;
    @Resource
    private CommonService commonService;

    /**
     * 发起分账
     * @param profitSharingOrderNo
     * @return
     */
    public BsTradeOrderProfitSharing separate(String profitSharingOrderNo) {
        log.info("========= Start 分账 Start ===========");
        // 交易分账
        BsTradeOrderProfitSharing tradeOrderProfitSharing = tradeOrderProfitSharingService.getDetailByProfitSharingOrderNo(profitSharingOrderNo);
        if (null == tradeOrderProfitSharing) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到交易分账记录");
        }
        if (!tradeOrderProfitSharing.getStatus().equals(ProfitSharingStatusEnum.status0.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "业务不处于待处理状态");
        }
        // 查询交易详情
        BsTradeOrder tradeOrder = tradeOrderService.getOrderByTradeNoId(tradeOrderProfitSharing.getTradeOrderId());
        // 商户
        BsMer mer = merService.getMer(tradeOrder.getMerId());
        // 分账接收方
        List<BsTradeOrderProfitSharingReceiver> profitSharingReceiverList = tradeOrderProfitSharingReceiverService.getReceiverListByProfitSharingId(tradeOrderProfitSharing.getId());

        SecDictionary org = commonService.mappingSysCode("ORG_NO", mer.getOrgNo());
        if (org == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的机构");
        }

        Map<String, Object> commonParam = new HashMap<>();
        commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
        commonParam.put("version", "3.0");

        Map<String, Object> map = new HashMap<>();
        map.put("merchant_no", tradeOrder.getPlatformMerNo());
        map.put("log_no", tradeOrder.getPlatformLogNo());
        map.put("log_date", DateUtil.date2String(tradeOrder.getPayTime(), "yyyyMMdd"));
        map.put("out_separate_no", tradeOrderProfitSharing.getProfitSharingOrderNo());
        map.put("total_amt", tradeOrderProfitSharing.getProfitSharingAmoun().multiply(new BigDecimal("100")).longValue());
        map.put("lkl_org_no", org.getExt1());
        map.put("cal_type", "0");

        List<Map<String,Object>> recvDatasMapList = new ArrayList<>();
        Map<String,Object> recvDatasMap;

        for (BsTradeOrderProfitSharingReceiver receiver : profitSharingReceiverList) {
            if (receiver.getReceiverAmount().compareTo(new BigDecimal("0")) != 0) {
                recvDatasMap = new HashMap<>();
                recvDatasMap.put("recv_no", receiver.getReceiverAccount());
                recvDatasMap.put("separate_value", receiver.getReceiverAmount().multiply(new BigDecimal("100")).longValue());
                recvDatasMapList.add(recvDatasMap);
            }
        }
        map.put("recv_datas", recvDatasMapList);
        commonParam.put("req_data", map);

        Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));
        // 头部参数
        Map<String, Object> heard = new HashMap<>();
        heard.put("Authorization", reqParam.get("Authorization"));

        log.info("请求参数：",JSONObject.toJSONString(commonParam));
        JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/sacs/separate", commonParam, heard);
        log.info("响应参数：", responseBody.toJSONString());
        System.out.println("body：" + JSONObject.toJSONString(commonParam));
        System.out.println("response：" + responseBody.toJSONString());

        if (!responseBody.getString("code").equals("SACS0000")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
        }

        JSONObject respData = responseBody.getJSONObject("resp_data");
        // 	分账状态 处理中：PROCESSING, 已受理：ACCEPTED, 成功：SUCCESS, 失败：FAIL
        String statusCode = respData.getString("status");
        if (statusCode.equals("PROCESSING")) {
            tradeOrderProfitSharing.setStatus(ProfitSharingStatusEnum.status2.getNumber());
        } else if (statusCode.equals("ACCEPTED")) {
            tradeOrderProfitSharing.setStatus(ProfitSharingStatusEnum.status3.getNumber());
        } else if (statusCode.equals("SUCCESS")) {
            tradeOrderProfitSharing.setStatus(ProfitSharingStatusEnum.status1.getNumber());
            tradeOrderProfitSharing.setProfitSharingTime(new Date());
            tradeOrderProfitSharing.setFinishTime(new Date());
        } else if (statusCode.equals("FAIL")) {
            tradeOrderProfitSharing.setStatus(ProfitSharingStatusEnum.status4.getNumber());
        }
        tradeOrderProfitSharing.setPlatformProfitSharingOrderNo(respData.getString("separate_no"));
        tradeOrderProfitSharingService.editData(tradeOrderProfitSharing);

        // 处理接收方数据
        if (tradeOrderProfitSharing.equals(ProfitSharingStatusEnum.status1.getName())) {
            for (BsTradeOrderProfitSharingReceiver receiver : profitSharingReceiverList) {
                receiver.setStatus(ProfitSharingReceiverStatusEnum.status1.getNumber());
                receiver.setProfitSharingTime(new Date());
                receiver.setFinishTime(new Date());
                tradeOrderProfitSharingReceiverService.editData(receiver);
            }
        }
        log.info("========= END 分账 END ===========");
        return tradeOrderProfitSharing;
    }

    public JSONObject queryAmt(String profitSharingOrderNo) {
        // 交易订单分账
        BsTradeOrderProfitSharing tradeOrderProfitSharing = tradeOrderProfitSharingService.getDetailByProfitSharingOrderNo(profitSharingOrderNo);
        if (null == tradeOrderProfitSharing) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "未找到交易分账记录");
        }
        // 查询交易详情
        BsTradeOrder tradeOrder = tradeOrderService.getOrderByTradeNoId(tradeOrderProfitSharing.getTradeOrderId());

        Map<String, Object> commonParam = new HashMap<>();
        commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
        commonParam.put("version", "3.0");

        Map<String, Object> map = new HashMap<>();
        map.put("merchant_no", tradeOrderProfitSharing.getPlatformMerNo());
        map.put("log_no", tradeOrder.getPlatformLogNo());
        map.put("log_date", DateUtil.date2String(tradeOrder.getPayTime(), "yyyyMMdd"));
        commonParam.put("req_data", map);

        Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));
        // 头部参数
        Map<String, Object> heard = new HashMap<>();
        heard.put("Authorization", reqParam.get("Authorization"));

        JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/sacs/queryAmt", commonParam, heard);
        System.out.println("body：" + JSONObject.toJSONString(commonParam));
        System.out.println("response：" + responseBody.toJSONString());
        if (!responseBody.getString("code").equals("SACS0000")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
        }
        tradeOrderProfitSharing.setStatus(ProfitSharingStatusEnum.status2.getNumber());
        tradeOrderProfitSharingService.editData(tradeOrderProfitSharing);
        return responseBody.getJSONObject("resp_data");
    }

    /**
     * 分账撤销
     * @param profitSharingOrderNo
     * @return
     */
    public JSONObject cancel(String profitSharingOrderNo) {
        log.info("========= Start 分账撤销 Start ===========");
        // 交易订单分账
        BsTradeOrderProfitSharing tradeOrderProfitSharing = tradeOrderProfitSharingService.getDetailByProfitSharingOrderNo(profitSharingOrderNo);
        if (null == tradeOrderProfitSharing) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "未找到交易分账记录");
        }
        Map<String, Object> commonParam = new HashMap<>();
        commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
        commonParam.put("version", "3.0");

        Map<String, Object> map = new HashMap<>();
        map.put("merchant_no", tradeOrderProfitSharing.getPlatformMerNo());
        map.put("origin_out_separate_no", tradeOrderProfitSharing.getOriginProfitSharingOrderNo());
        map.put("out_separate_no", tradeOrderProfitSharing.getProfitSharingOrderNo());
        map.put("total_amt", tradeOrderProfitSharing.getProfitSharingAmoun().multiply(new BigDecimal("100")).longValue());
        commonParam.put("req_data", map);

        Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));
        // 头部参数
        Map<String, Object> heard = new HashMap<>();
        heard.put("Authorization", reqParam.get("Authorization"));

        log.info("请求参数：",JSONObject.toJSONString(commonParam));
        JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/sacs/cancel", commonParam, heard);
        log.info("响应参数：", responseBody.toJSONString());
        System.out.println("body：" + JSONObject.toJSONString(commonParam));
        System.out.println("response：" + responseBody.toJSONString());
        if (!responseBody.getString("code").equals("SACS0000")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
        }
        tradeOrderProfitSharing.setStatus(ProfitSharingStatusEnum.status2.getNumber());
        tradeOrderProfitSharing.setPlatformProfitSharingOrderNo(responseBody.getJSONObject("resp_data").getString("separate_no"));
        tradeOrderProfitSharingService.editData(tradeOrderProfitSharing);
        log.info("========= end 分账撤销 end ===========");
        return responseBody.getJSONObject("resp_data");
    }

    /**
     * todo 目前未开发，目前的场景用不到
     * 分账回退
     * @param profitSharingOrderNo 交易订单号
     * @return
     */
    public JSONObject fallback(String profitSharingOrderNo) {
        // 交易订单分账
        BsTradeOrderProfitSharing tradeOrderProfitSharing = tradeOrderProfitSharingService.getDetailByProfitSharingOrderNo(profitSharingOrderNo);
        if (null == tradeOrderProfitSharing) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "未找到交易分账记录");
        }

        Map<String, Object> commonParam = new HashMap<>();
        commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
        commonParam.put("version", "3.0");

        Map<String, Object> map = new HashMap<>();
        map.put("merchant_no", tradeOrderProfitSharing.getPlatformMerNo());
        map.put("origin_out_separate_no", tradeOrderProfitSharing.getProfitSharingOrderNo());
        map.put("out_separate_no", tradeOrderProfitSharing.getProfitSharingOrderNo()+"1");
        map.put("total_amt", "24");

        // 回退分账金额，只能回退一个商户
        List<Map<String, Object>> originRecvDatas = new ArrayList<>();
        Map<String, Object> originRecv = new HashMap<>();
        originRecv.put("recv_no", "SR2023042415050");
        originRecv.put("amt", "24");
        originRecvDatas.add(originRecv);
        map.put("origin_recv_datas", originRecvDatas);
        commonParam.put("req_data", map);

        Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));
        // 头部参数
        Map<String, Object> heard = new HashMap<>();
        heard.put("Authorization", reqParam.get("Authorization"));

        JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/sacs/fallback", commonParam, heard);
        System.out.println("body：" + JSONObject.toJSONString(commonParam));
        System.out.println("response：" + responseBody.toJSONString());
        if (!responseBody.getString("code").equals("SACS0000")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
        }
        tradeOrderProfitSharing.setStatus(ProfitSharingStatusEnum.status2.getNumber());
        tradeOrderProfitSharingService.editData(tradeOrderProfitSharing);
        return responseBody;
    }

    /**
     * 分账结果查询
     * @param profitSharingOrderNo 交易订单号
     * @return
     */
    public JSONObject query(String profitSharingOrderNo) {
        log.info("========= Start 分账结果查询 Start ===========");
        // 交易订单分账
        BsTradeOrderProfitSharing tradeOrderProfitSharing = tradeOrderProfitSharingService.getDetailByProfitSharingOrderNo(profitSharingOrderNo);
        if (null == tradeOrderProfitSharing) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "未找到交易分账记录");
        }

        Map<String, Object> commonParam = new HashMap<>();
        commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
        commonParam.put("version", "3.0");

        Map<String, Object> map = new HashMap<>();
        map.put("merchant_no", tradeOrderProfitSharing.getPlatformMerNo());
        map.put("out_separate_no", tradeOrderProfitSharing.getProfitSharingOrderNo());
        commonParam.put("req_data", map);

        Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));
        // 头部参数
        Map<String, Object> heard = new HashMap<>();
        heard.put("Authorization", reqParam.get("Authorization"));

        log.info("请求参数：",JSONObject.toJSONString(commonParam));
        JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/sacs/query", commonParam, heard);
        log.info("响应参数：", responseBody.toJSONString());
        System.out.println("body：" + JSONObject.toJSONString(commonParam));
        System.out.println("response：" + responseBody.toJSONString());
        if (!responseBody.getString("code").equals("SACS0000")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
        }
        log.info("========= end 分账结果查询 end ===========");
        return responseBody.getJSONObject("resp_data");
    }

}
