package com.fs.huifuPay.sdk.opps.core.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fs.common.utils.StringUtils;
import com.fs.common.utils.spring.SpringUtils;
import com.fs.company.domain.CompanyDivItem;
import com.fs.company.mapper.CompanyDivConfigMapper;
import com.fs.company.param.CompanyAcctInfo;
import com.fs.company.service.ICompanyDivConfigService;
import com.fs.company.service.ICompanyDivItemService;
import com.fs.company.service.impl.CompanyDivConfigServiceImpl;
import com.fs.company.vo.CompanyDivConfigVo;
import com.fs.his.domain.FsPackageOrder;
import com.fs.his.domain.FsPayConfig;
import com.fs.his.domain.FsStoreOrder;
import com.fs.his.domain.FsStorePayment;
import com.fs.huifuPay.domain.HuiFuCreateOrder;
import com.fs.system.domain.SysConfig;
import com.fs.system.mapper.SysConfigMapper;
import com.google.gson.Gson;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HuiFuUtils {
    private static ICompanyDivConfigService companyDivConfigService = SpringUtils.getBean(ICompanyDivConfigService.class);
    private static ICompanyDivItemService companyDivItemService = SpringUtils.getBean(ICompanyDivItemService.class);

    /**
     *  处理分账
     * @param huiFuCreateOrder
     * @param companyId
     */
    public static void doDiv(HuiFuCreateOrder huiFuCreateOrder, Long companyId) throws Exception {
        //默认汇付账户
        SysConfigMapper sysConfigMapper= SpringUtils.getBean(SysConfigMapper.class);
        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
        String defaultHuifuId = fsPayConfig.getHuifuId();
        //查询是否开启分账
        if (companyId !=null){

            CompanyDivConfigVo configVo = companyDivConfigService.selectCompanyDivConfigByCompanyId(companyId);
            if (configVo != null){
                Integer divFlag = configVo.getDivFlag();
                if (divFlag != null && divFlag == 1){
                    //开启分账
                    //汇付传参
                    Map<String, Object> acctSplitBunchMap = new HashMap<>();
                    List<Map<String,Object>> acctInfos = new ArrayList();
                    List<CompanyAcctInfo> acctInfoVos = configVo.getAcctInfos();
                    if (acctInfoVos != null && !acctInfoVos.isEmpty()){
                        String delayAcctFlag = configVo.getDelayAcctFlag();
                        String percentageFlag = configVo.getPercentageFlag();
                        if (StringUtils.isNotBlank(delayAcctFlag) && delayAcctFlag.equals("N")){
                            //实时分账
                            if (StringUtils.isNotBlank(percentageFlag) && percentageFlag.equals("Y")){
                                acctSplitBunchMap.put("percentage_flag","Y");
                                Float total = 0f;
                                //百分比分账
                                for (CompanyAcctInfo acctInfo : acctInfoVos) {
                                    Map<String, Object> map = new HashMap<>();
                                    Float percentageDiv = acctInfo.getPercentageDiv();
                                    if (percentageDiv == null || percentageDiv <= 0){
                                        continue;
                                    }
                                    map.put("percentage_div", String.format("%.2f", percentageDiv));
                                    if (percentageDiv > 100){
                                        acctInfos = null;
                                        break;
                                    }
                                    total = total + percentageDiv;
                                    if (total>100){
                                        acctInfos = null;
                                        break;
                                    }
                                    if (StringUtils.isBlank(acctInfo.getAcctId())){
                                        acctInfo.setAcctId(null);
                                    }
                                    map.put("huifu_id", acctInfo.getHuifuId());
                                    acctInfos.add(map);
                                }
                                if (acctInfos != null && !acctInfos.isEmpty()){
                                    Map<String, Object> defaultAccount = new HashMap<>();
                                    defaultAccount.put("percentage_div", String.format("%.2f", 100f - total));
                                    defaultAccount.put("huifu_id", defaultHuifuId);
                                    acctInfos.add(defaultAccount);
                                }


                            } else {
                                acctSplitBunchMap.put("percentage_flag","N");
                                // 固定金额
                                BigDecimal amtTotal = BigDecimal.ZERO;
                                //支付金额
                                BigDecimal initTotal = new BigDecimal(huiFuCreateOrder.getTransAmt()).setScale(2, RoundingMode.FLOOR);
                                for (CompanyAcctInfo acctInfo : acctInfoVos) {
                                    Map<String, Object> map = new HashMap<>();
                                    BigDecimal divAmt = acctInfo.getDivAmt().setScale(2, RoundingMode.FLOOR);
                                    if (divAmt.compareTo(BigDecimal.ZERO) <= 0){
                                        continue;
                                    }
                                    map.put("div_amt",divAmt.toString());
                                    amtTotal = amtTotal.add(divAmt);
                                    if (amtTotal.compareTo(initTotal) > 0){
                                        acctInfos = null;
                                        break;
                                    }
                                    if (StringUtils.isBlank(acctInfo.getAcctId())){
                                        acctInfo.setAcctId(null);
                                    }
                                    map.put("huifu_id", acctInfo.getHuifuId());
                                    acctInfos.add(map);
                                }
                                if (acctInfos != null && !acctInfos.isEmpty()){
                                    if (initTotal.compareTo(amtTotal)<0){
                                        acctInfos = null;
                                    } else {
                                        Map<String, Object> defaultAccount = new HashMap<>();
                                        defaultAccount.put("div_amt", String.valueOf(initTotal.subtract(amtTotal).setScale(2, RoundingMode.FLOOR)));
                                        defaultAccount.put("huifu_id", defaultHuifuId);
                                        acctInfos.add(defaultAccount);
                                    }
                                }

                            }

                            if (acctInfos != null){
                                acctSplitBunchMap.put("is_clean_split", configVo.getIsCleanSplit());
                                acctSplitBunchMap.put("acct_infos", acctInfos);
                                huiFuCreateOrder.setAcctSplitBunch( JSON.toJSONString(acctSplitBunchMap));
                            }
                        } else if (StringUtils.isNotBlank(delayAcctFlag) && delayAcctFlag.equals("Y")){
                            //延时分账 确认交易时传参
                            huiFuCreateOrder.setDelayAcctFlag("Y");
                        }

                    }
                }
            }
        }
    }

    public static void saveDivItem(HuiFuCreateOrder o, String orderCode, String payCode) {
        CompanyDivItem companyDivItem = new CompanyDivItem();
        if (StringUtils.isNotBlank(o.getAcctSplitBunch())){
            companyDivItem.setOrderCode(orderCode);
            companyDivItem.setPayCode(payCode);
            companyDivItem.setDetail(o.getAcctSplitBunch());
            companyDivItem.setIsRefund(0); //支付
            companyDivItem.setIsDelay(0); //延迟分账
            companyDivItemService.insertCompanyDivItem(companyDivItem);
        }
    }

    /**
     * 回调修改分账明细状态
     * @param payCode
     */
    public static void updateDivItem(String payCode) {
        //修改分账状态
        CompanyDivItem companyDivItem = companyDivItemService.selectCompanyDivItemByPayCode(payCode);
        if (companyDivItem != null) {
            companyDivItem.setIsPay(1);
            companyDivItemService.updateCompanyDivItem(companyDivItem);
        }
    }



    /**
     * 处理分账退款
     *
     * @param reMoney
     * @param payment
     * @param extendInfoMap
     */
    public static CompanyDivItem doRefundDiv(BigDecimal payPrice,BigDecimal reMoney, FsStorePayment payment, Map<String, Object> extendInfoMap) {
        CompanyDivItem companyDivItem = null;
        companyDivItem = companyDivItemService.selectCompanyDivItemByPayCode(payment.getPayCode());
        if (companyDivItem != null) {
            if (payPrice.compareTo(reMoney) > 0) {
                //部分退款
                if (companyDivItem != null) {
                    SysConfigMapper sysConfigMapper = SpringUtils.getBean(SysConfigMapper.class);
                    SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
                    FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
                    String defaultHuiFuId = fsPayConfig.getHuifuId(); //默认汇付id

                    String detail = companyDivItem.getDetail();
                    if (StringUtils.isNotBlank(detail)) {
                        JSONObject acctSplitBunch = JSONObject.parseObject(detail);
                        if (acctSplitBunch.get("percentage_flag") != null) {
                            List<Map<String, Object>> param = new ArrayList(); //传入汇付参数

                            String percentageFlag = acctSplitBunch.get("percentage_flag").toString();
                            Object acctInfosObj = acctSplitBunch.get("acct_infos");
                            if (acctInfosObj != null) {
                                if ("Y".equals(percentageFlag)) {
                                    // 百分比分账
                                    List<Map> acctInfos = JSON.parseArray(acctInfosObj.toString(), Map.class);
                                    if (acctInfos != null && !acctInfos.isEmpty()) {
                                        BigDecimal remainMoney = reMoney;

                                        for (Map acctInfo : acctInfos) {
                                            String percentageDiv = acctInfo.get("percentage_div").toString();
                                            BigDecimal divAmt = reMoney.multiply(BigDecimal.valueOf(Float.valueOf(percentageDiv)).multiply(BigDecimal.valueOf(0.01))).setScale(2, BigDecimal.ROUND_HALF_UP);
                                            if (divAmt.compareTo(BigDecimal.ZERO) <= 0) {
                                                continue;
                                            }
                                            remainMoney = remainMoney.subtract(divAmt);
                                            String huiFuId = acctInfo.get("huifu_id").toString();
                                            Map<String, Object> map = new HashMap<>();
                                            map.put("div_amt", divAmt);
                                            map.put("huifu_id", huiFuId);
//                                                part_loan_amt	垫资金额
                                            param.add(map);
                                            if (remainMoney.compareTo(BigDecimal.ZERO) >= 0) {
                                                break;
                                            }
                                        }
                                        if (remainMoney.compareTo(BigDecimal.ZERO) >= 0) {
                                            BigDecimal divAmt = reMoney.subtract(remainMoney).setScale(2, BigDecimal.ROUND_HALF_UP);
                                            Map<String, Object> map = new HashMap<>();
                                            map.put("div_amt", divAmt);
                                            map.put("huifu_id", defaultHuiFuId);
                                            param.add(map);
                                        }
                                    }

                                } else if ("N".equals(percentageFlag)) {
                                    // 金额分账 目前按照排序从第一个开始扣 扣到满足退款金额
                                }
                                if (!param.isEmpty()) {
                                    extendInfoMap.put("acct_split_bunch", JSON.toJSONString(param));
                                }
                            }

                        }


                    }
                }
            }
        }
        return companyDivItem;

    }
}
