package com.hfkj.service.order.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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.RandomUtils;
import com.hfkj.dao.BsOrderSettleMapper;
import com.hfkj.entity.*;
import com.hfkj.pay.HuiPayService;
import com.hfkj.service.merchant.BsMerchantPayConfigService;
import com.hfkj.service.merchant.BsMerchantService;
import com.hfkj.service.order.BsGasChannelConfigService;
import com.hfkj.service.order.BsOrderSettleLedgerService;
import com.hfkj.service.order.BsOrderSettleService;
import com.hfkj.sysenum.merchant.MerchantSourceTypeEnum;
import com.hfkj.sysenum.order.OrderSettleLedgerStatusEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @className: BsOrderSettleServiceImpl
 * @author: HuRui
 * @date: 2024/6/24
 **/
@Service("BsOrderSettleService")
public class BsOrderSettleServiceImpl implements BsOrderSettleService {
    @Resource
    private BsOrderSettleMapper orderSettleMapper;
    @Resource
    private BsMerchantService merchantService;
    @Resource
    private BsOrderSettleLedgerService orderSettleLedgerService;
    @Resource
    private BsMerchantPayConfigService merchantPayConfigService;
    @Resource
    private BsGasChannelConfigService gasChannelConfigService;

    @Override
    public void editData(BsOrderSettle data) {
        data.setUpdateTime(new Date());
        if (data.getId() == null) {
            data.setCreateTime(new Date());
            orderSettleMapper.insert(data);
        } else {
            orderSettleMapper.updateByPrimaryKey(data);
        }
    }

    @Override
    public BsOrderSettle getData(String orderNo) {
        BsOrderSettleExample example = new BsOrderSettleExample();
        example.createCriteria().andOrderNoEqualTo(orderNo);
        List<BsOrderSettle> list = orderSettleMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public void separate(BsOrderSettle orderSettle) {
        // 可分账余额
        BigDecimal canSeparateAmt = HuiPayService.queryAmt(orderSettle).getJSONObject("return_data").getBigDecimal("canSeparateAmt");
        // 总分账金额
        BigDecimal totalLedgerAmount = new BigDecimal("0");
        // 查询商户
        BsMerchant merchant = merchantService.getMerchant(orderSettle.getMerNo());
        if (merchant != null) {
            List<BsOrderSettleLedger> settleLedgerList = new ArrayList<>();
            if (merchant.getSourceType().equals(MerchantSourceTypeEnum.type1.getNumber())) {
                // 查询商户配置
                BsMerchantPayConfig payConfig = merchantPayConfigService.getConfig(orderSettle.getMerNo());
                if (payConfig != null && StringUtils.isNotBlank(payConfig.getLedgerAccountData())) {
                    // 分账接收方数据
                    JSONArray ledgerAccountData = JSONArray.parseArray(payConfig.getLedgerAccountData());
                    for (Object obj : ledgerAccountData) {
                        JSONObject ledgerAccount = (JSONObject) obj;
                        BsOrderSettleLedger settleLedger = new BsOrderSettleLedger();
                        settleLedger.setOrderSettleId(orderSettle.getId());
                        settleLedger.setSharingAmount(orderSettle.getSettleAmount());
                        settleLedger.setRatio(ledgerAccount.getBigDecimal("receiverRatio"));
                        settleLedger.setReceiverMerNo(ledgerAccount.getString("receiverMerNo"));
                        settleLedger.setReceiverMerName(ledgerAccount.getString("receiverMerName"));
                        settleLedger.setReceiverAmount(settleLedger.getSharingAmount().multiply(settleLedger.getRatio().divide(new BigDecimal("100"))).setScale(2, BigDecimal.ROUND_DOWN));
                        settleLedger.setStatus(0);
                        orderSettleLedgerService.editData(settleLedger);
                        settleLedgerList.add(settleLedger);
                        // 累加分账金额
                        totalLedgerAmount = totalLedgerAmount.add(settleLedger.getReceiverAmount());
                    }
                }

            } else if (merchant.getSourceType().equals(MerchantSourceTypeEnum.type2.getNumber())
                || merchant.getSourceType().equals(MerchantSourceTypeEnum.type3.getNumber())) {
                // 查询商户配置
                BsGasChannelConfig gasChannelConfig = gasChannelConfigService.getDetail(MerchantSourceTypeEnum.getDataByType(merchant.getSourceType()));
                if (gasChannelConfig != null && StringUtils.isNotBlank(gasChannelConfig.getLedgerAccountData())) {


                    // 分账接收方数据
                    JSONArray ledgerAccountData = JSONArray.parseArray(gasChannelConfig.getLedgerAccountData());
                    for (Object obj : ledgerAccountData) {
                        JSONObject ledgerAccount = (JSONObject) obj;
                        BsOrderSettleLedger settleLedger = new BsOrderSettleLedger();
                        settleLedger.setOrderSettleId(orderSettle.getId());
                        settleLedger.setSharingAmount(orderSettle.getSettleAmount());
                        settleLedger.setRatio(ledgerAccount.getBigDecimal("receiverRatio"));
                        settleLedger.setReceiverMerNo(ledgerAccount.getString("receiverMerNo"));
                        settleLedger.setReceiverMerName(ledgerAccount.getString("receiverMerName"));
                        settleLedger.setReceiverAmount(settleLedger.getSharingAmount().multiply(settleLedger.getRatio().divide(new BigDecimal("100"))).setScale(2, BigDecimal.ROUND_DOWN));
                        settleLedger.setStatus(0);
                        orderSettleLedgerService.editData(settleLedger);
                        settleLedgerList.add(settleLedger);
                        // 累加分账金额
                        totalLedgerAmount = totalLedgerAmount.add(settleLedger.getReceiverAmount());
                    }
                }
            }
            orderSettle.setLedgerAmount(canSeparateAmt);
            editData(orderSettle);

            // 收款账户也需要设置分账人
            BsOrderSettleLedger settleLedger = new BsOrderSettleLedger();
            settleLedger.setOrderSettleId(orderSettle.getId());
            settleLedger.setSharingAmount(orderSettle.getSettleAmount());
            settleLedger.setReceiverMerNo(orderSettle.getSettleMerNo());
            settleLedger.setReceiverMerName(orderSettle.getSettleMerNo());
            // 可分账余额 - 全部分账接收方总额 = 收款商户金额
            settleLedger.setReceiverAmount(canSeparateAmt.subtract(totalLedgerAmount));
            settleLedger.setStatus(0);
            orderSettleLedgerService.editData(settleLedger);
            settleLedgerList.add(settleLedger);

            // 请求分账
            JSONObject separate = HuiPayService.profitSharingSeparate(orderSettle, settleLedgerList);
            if (separate.getString("return_code").equals("000000")) {
                orderSettle.setLedgerStatus(OrderSettleLedgerStatusEnum.status2.getCode());
                editData(orderSettle);
            }
        }
    }

    @Override
    public void revokeLedger(BsOrderSettle orderSettle) {
        // 请求撤销分账
        orderSettle.setRevokeOrderNo("LC"+ DateUtil.date2String(new Date(), "yyMMddHHmmss") + RandomUtils.number(3, false));
        JSONObject separate = HuiPayService.profitSharingCancel(orderSettle);
        if (separate.getString("return_code").equals("000000")) {
            orderSettle.setLedgerStatus(OrderSettleLedgerStatusEnum.status5.getCode());
            editData(orderSettle);
        } else {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, separate.getString("return_msg"));
        }
    }

    @Override
    public List<BsOrderSettle> getList(Map<String, Object> param) {

        if (MapUtils.getLong(param, "createTimeS") != null) {
            param.put("createTimeS", DateUtil.date2String(new Date(MapUtils.getLong(param, "createTimeS")), DateUtil.Y_M_D_HMS));
        }

        if (MapUtils.getLong(param, "createTimeE") != null) {
            param.put("createTimeE", DateUtil.date2String(new Date(MapUtils.getLong(param, "createTimeE")), DateUtil.Y_M_D_HMS));
        }

        return orderSettleMapper.queryList(param);
    }
}
