package com.yn.bftl.thirdparty.modules.chinaums.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.yn.bftl.common.common.util.ByxRouteUtil;
import com.yn.bftl.common.modules.company.entity.ChinaumsAuthInfo;
import com.yn.bftl.common.modules.company.entity.Company;
import com.yn.bftl.common.modules.configuration.entity.ThirdPartyPaySet;
import com.yn.bftl.common.modules.relation.entity.BusinessRelations;
import com.yn.bftl.thirdparty.common.exception.YnceErrorException;
import com.yn.bftl.thirdparty.common.repository.BusinessRelationsRepository;
import com.yn.bftl.thirdparty.common.repository.CompanyRepository;
import com.yn.bftl.thirdparty.common.service.ByxTradeWayService;
import com.yn.bftl.thirdparty.modules.business.util.ThirdPartyConfigUtil;
import com.yn.bftl.thirdparty.modules.chinaums.dto.byx.*;
import com.yn.bftl.thirdparty.modules.chinaums.repository.ChinaumsAuthInfoRepository;
import com.yn.bftl.thirdparty.modules.chinaums.service.ProfitSharingService;
import com.yn.bftl.thirdparty.modules.chinaums.util.ByxChinaumsUtil;
import com.yn.bftl.thirdparty.modules.chinaums.vo.byx.ByxChinaumsProfitSharingPartnerDetailVO;
import com.yn.bftl.thirdparty.modules.chinaums.vo.byx.ByxChinaumsProfitSharingPartnerVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

@Slf4j
@Service
public class ProfitSharingServiceImpl implements ProfitSharingService {

    @Resource
    private CompanyRepository companyRepository;

    @Resource
    private ChinaumsAuthInfoRepository chinaumsAuthInfoRepository;

    @Resource
    private ByxTradeWayService byxTradeWayService;

    @Resource
    private ByxChinaumsUtil byxChinaumsUtil;

    @Resource
    private BusinessRelationsRepository businessRelationsRepository;

    @Resource
    private ThirdPartyConfigUtil thirdPartyConfigUtil;

    /**
     * 分账关联方-添加关联方
     * @param byxCreateMemberDTO byxCreateMemberDTO
     */
    @Override
    public void addPartner(ByxCreateMemberDTO byxCreateMemberDTO) {

        Company sourceCompany = companyRepository.findById(byxCreateMemberDTO.getSourceCompanyId()).orElse(null);
        if (ObjectUtil.isNull(sourceCompany)) {
            throw new YnceErrorException("添加关联方失败，参数不正确");
        }
        Company targetCompany = companyRepository.findById(byxCreateMemberDTO.getTargetCompanyId()).orElse(null);
        if (ObjectUtil.isNull(targetCompany)) {
            throw new YnceErrorException("添加关联方失败，参数不正确");
        }
        boolean needIncludesSourceCompany = isNeedIncludesSourceCompany(sourceCompany);
        // 参数
        ProfitSharingPartnerDTO profitSharingPartnerDTO = preparePartnerParams(targetCompany, sourceCompany, needIncludesSourceCompany);
        byxTradeWayService.setTradeWayInCert(profitSharingPartnerDTO, profitSharingPartnerDTO.getMerWalletId());
        JSONObject result = byxChinaumsUtil.execute(ByxRouteUtil.ROUTE_PROFITSHARING_ADD_MERREL, (JSONObject) JSONObject.toJSON(profitSharingPartnerDTO), JSONObject.class);
        byxCheck(result);
    }

    private boolean isNeedIncludesSourceCompany(Company sourceCompany) {
        // 接口查询分账方列表，判断源企业是否在分账方列表里面，若有，则最后不需要将源企业添加至银联，若无，则需要。因银联把源企业也视作分账分，主账为平台
        ByxChinaumsProfitSharingPartnerVO partnerVO = this.queryPartner();
        boolean needIncludesSourceCompany = true;
        if (partnerVO != null) {
            if (partnerVO.getList() != null && partnerVO.getList().size() > 0) {
                for (ByxChinaumsProfitSharingPartnerDetailVO detailVO : partnerVO.getList()) {
                    if (sourceCompany.getWalletId().equals(detailVO.getRelMerWalletId())) {
                        needIncludesSourceCompany = false;
                        break;
                    }
                }
            }
        }
        return needIncludesSourceCompany;
    }

    private void byxCheck(JSONObject result) {
        if (result == null) {
            throw new YnceErrorException("接口返回异常");
        }
        if (result.get("rspCode") == null || !result.get("rspCode").toString().equals("00000")) {
            throw new YnceErrorException("操作失败，异常信息:" + result.get("rspResult"));
        }
    }

    /**
     * 分账关联方-查询关联方
     */
    @Override
    public ByxChinaumsProfitSharingPartnerVO queryPartner() {
        ThirdPartyPaySet thirdPartyPaySet = thirdPartyConfigUtil.getPlatform();
        JSONObject params = new JSONObject();
        params.put("platformWalletId", thirdPartyPaySet.getChinaumsFeeBalanceAcctId());
        return byxChinaumsUtil.execute(ByxRouteUtil.ROUTE_PROFITSHARING_QUERY_MERREL, params, ByxChinaumsProfitSharingPartnerVO.class);
    }

    public void addRules(ByxCreateMemberRuleDTO byxCreateMemberRuleDTO) {
//        Company sourceCompany = companyRepository.findById(byxCreateMemberDTO.getSourceCompanyId()).orElse(null);
//        if (ObjectUtil.isNull(sourceCompany)) {
//            throw new YnceErrorException("添加关联方失败，参数不正确");
//        }
        if (byxCreateMemberRuleDTO == null || ObjectUtil.isEmpty(byxCreateMemberRuleDTO.getTargetCompanyIdList())) {
            throw new YnceErrorException("参数不正确");
        }

        Company tempCompany = companyRepository.findById(byxCreateMemberRuleDTO.getTargetCompanyIdList().get(0)).orElse(null);
        if (tempCompany == null) {
            throw new YnceErrorException("企业信息不存在");
        }
        // 销售公司
        Company sCompany = tempCompany.getMarketingCompany();
        // 销售公司业务关系列表
        List<BusinessRelations> businessRelationsList = businessRelationsRepository.findBySourceCompany(sCompany);
        if (ObjectUtil.isEmpty(businessRelationsList)) {
            throw new YnceErrorException("未查询到关联关系");
        }
        // 是平台公司
        Company platformCompany = companyRepository.findByWalletId(thirdPartyConfigUtil.getPlatform().getChinaumsFeeBalanceAcctId());
        // 协议文件ID 列表
        List<ByxFileIdDTO> fileList = getByxFileIdDTOList();
        BigDecimal totalRateForTarget = BigDecimal.ZERO;
        List<ProfitSharingRuleDetailDTO> settRuleList = new ArrayList<>();
        for (Long companyId: byxCreateMemberRuleDTO.getTargetCompanyIdList()) {
            Company company = companyRepository.findById(companyId).orElse(null);
            if (company == null) {
                throw new YnceErrorException("企业信息不存在");
            }
            BusinessRelations businessRelations = this.findTargetBusinessRelation(businessRelationsList, company);
            ProfitSharingRuleDetailDTO profitSharingRuleDetailDTO = ProfitSharingRuleDetailDTO
                    .builder()
                    .profitSharingWalletId(company.getWalletId())
                    .profitSharingWalletName(company.getName())
                    .settRate(businessRelations.getServiceFee().multiply(new BigDecimal(10000)).longValue())
                    .rateMinSettAmt(businessRelations.getRateMinSettAmt().multiply(new BigDecimal(100)).longValue())
                    .rateMaxSettAmt(businessRelations.getRateMaxSettAmt().multiply(new BigDecimal(100)).longValue())
                    .build();
            settRuleList.add(profitSharingRuleDetailDTO);
            totalRateForTarget.add(businessRelations.getServiceFee());
        }
        BigDecimal salesRate = new BigDecimal(100);
        salesRate = salesRate.subtract(totalRateForTarget);
        ProfitSharingRuleDetailDTO salesRuleDetailDTO = ProfitSharingRuleDetailDTO
                .builder()
                .profitSharingWalletId(sCompany.getWalletId())
                .profitSharingWalletName(sCompany.getName())
                .settRate(salesRate.multiply(new BigDecimal(10000)).longValue())
                .rateMinSettAmt(settRuleList.get(0).getRateMinSettAmt())
                .rateMaxSettAmt(settRuleList.get(0).getRateMaxSettAmt())
                .build();
        settRuleList.add(salesRuleDetailDTO);
        ProfitSharingRuleDTO profitSharingRuleDTO = ProfitSharingRuleDTO
                .builder()
                .merWalletId(platformCompany.getWalletId())
                .merName(platformCompany.getName())
                .bizType("030001") //担保支付类型
                .isInstr(1)
                .settRuleType("01") //01: 新建（待提交）
                .settRuleList(settRuleList)
                .fileList(fileList)
                .build();
        JSONObject result = byxChinaumsUtil.execute(ByxRouteUtil.ROUTE_PROFITSHARING_ADD_RULE, (JSONObject) JSONObject.toJSON(profitSharingRuleDTO), JSONObject.class);
        byxCheck(result);
        if (result.get("id") == null) {
            throw new YnceErrorException("添加分账规则失败, 分账规则id返回为空");
        }
        // 保存规则ID
        for (BusinessRelations businessRelations: businessRelationsList) {
            businessRelations.setApproveStatus("01"); //01: 新建（待提交）
            businessRelations.setChinaumsRuleId(result.get("id").toString());
        }
        businessRelationsRepository.saveAll(businessRelationsList);
    }

    private BusinessRelations findTargetBusinessRelation(List<BusinessRelations> businessRelationsList, Company targetCompany) {
        for (BusinessRelations businessRelations: businessRelationsList) {
            if (businessRelations.getTargetCompany().getId().equals(targetCompany.getId())) {
                return businessRelations;
            }
        }
        throw new YnceErrorException("选择分账方不正确");
    }

//    private List<ProfitSharingRuleDetailDTO> getSettRuleList(Company sourceCompany, List<BusinessRelations> businessRelationsList) {
//        List<ProfitSharingRuleDetailDTO> settRuleList = new ArrayList<>();
//        for (BusinessRelations businessRelations: businessRelationsList) {
//            Company targetCompany = businessRelations.getTargetCompany();
//            ProfitSharingRuleDetailDTO profitSharingRuleDetailDTO = ProfitSharingRuleDetailDTO
//                    .builder()
//                    .profitSharingWalletId(targetCompany.getWalletId())
//                    .profitSharingWalletName(sourceCompany.getName())
//                    .settRate(businessRelations.getServiceFee().multiply(new BigDecimal(10000)).longValue())
//                    .rateMinSettAmt(businessRelations.getRateMinSettAmt().multiply(new BigDecimal(100)).longValue())
//                    .rateMaxSettAmt(businessRelations.getRateMaxSettAmt().multiply(new BigDecimal(100)).longValue())
//                    .build();
//            settRuleList.add(profitSharingRuleDetailDTO);
//        }
//        return settRuleList;
//    }

    private List<ByxFileIdDTO> getByxFileIdDTOList() {
        List<ByxFileIdDTO> fileList = new ArrayList<>();
        ByxFileIdDTO byxFileIdDTO = new ByxFileIdDTO();
        byxFileIdDTO.setFileId("");
        ByxFileIdDTO byxFileIdDTO2 = new ByxFileIdDTO();
        byxFileIdDTO.setFileId("");
        fileList.add(byxFileIdDTO);
        fileList.add(byxFileIdDTO2);
        return fileList;
    }

    @Override
    public void synApproveStatus() {

//        List<BusinessRelations> businessRelationsList = businessRelationsRepository.findAll();
//        if (businessRelationsList.size() < 1) {
//            throw new YnceErrorException("同步分账规则状态失败，未查询到任何关联关系");
//        }
//        // 过滤规则：获取出生效状态的业务关系，05表示生效
//        List<BusinessRelations> filteredList = businessRelationsList.stream().filter(
//                businessRelation -> businessRelation.getApproveStatus() == null || !"05".equals(businessRelation.getApproveStatus()))
//                .collect(Collectors.toList());
//        // filteredList 根据sourceCompany的walletId除重
//        Map<String, BusinessRelations> uniqueByWalletId = businessRelationsList.stream()
//                .collect(Collectors.toMap(
//                        br -> br.getSourceCompany().getWalletId(),
//                        Function.identity(),
//                        (oldValue, newValue) -> oldValue
//                ));
//        // uniqueByWalletId 转 List
//        List<BusinessRelations> uniqueWalletIdList = new ArrayList<>(uniqueByWalletId.values());
//        JSONObject params = new JSONObject();
//        ThirdPartyPaySet thirdPartyPaySet = thirdPartyConfigUtil.getPlatform();
//        params.put("platformWalletId", thirdPartyPaySet.getChinaumsFeeBalanceAcctId());
//        for (BusinessRelations businessRelations: uniqueWalletIdList) {
//            ProfitSharingRuleQueryVO profitSharingRuleQueryVO = byxChinaumsUtil.execute(ByxRouteUtil.ROUTE_PROFITSHARING_QUERY_RULE, params, ProfitSharingRuleQueryVO.class);
//            if (profitSharingRuleQueryVO == null || profitSharingRuleQueryVO.getRuleList() == null || profitSharingRuleQueryVO.getRuleList().size() < 1) {
//                log.error("同步分账规则状态失败, 接口异常");
//                continue;
//            }
//            // 循环遍历， 如果与filteredList中分账规则ID相等，则更新审核状态
//            for (ProfitSharingRuleVO profitSharingRuleVO: profitSharingRuleQueryVO.getRuleList()) {
//                Optional<BusinessRelations> matchingBr = filteredList.stream()
//                        .filter(br2 -> br2.getChinaumsRuleId().equals(profitSharingRuleVO.getId()))
//                        .findFirst();
//                matchingBr.ifPresent(br2 -> br2.setApproveStatus(profitSharingRuleVO.getApproveStatus()));
//            }

//        }
//        businessRelationsRepository.saveAll(filteredList);
    }

    private ProfitSharingPartnerDTO preparePartnerParams( Company targetCompany, Company sourceCompany, boolean needIncludesSourceCompany) {
        ChinaumsAuthInfo targetAuthInfo = chinaumsAuthInfoRepository.findFirstByCompanyId(targetCompany.getId());

        ProfitSharingPartnerDetailDTO profitSharingPartnerDetailDTO = ProfitSharingPartnerDetailDTO
                .builder()
                .relMerWalletId(targetCompany.getWalletId())
                .relMerName(targetCompany.getName())
                .isSettBank("0")
                .bankNo(targetAuthInfo.getSettleAcctBankBranchCode())
                .bankName(targetAuthInfo.getSettleAcctBankName())
                .elecBankNo(targetAuthInfo.getElecBankNo())
                .bankAcctNo(targetAuthInfo.getSettleAcctBankAcctNo())
                .bankAcctName(targetAuthInfo.getSettleAcctName())
                .idCard(targetAuthInfo.getIdCardNumber())
                .bankAcctType(0)
                .companyName(targetCompany.getName())
                .bizLicNo(targetCompany.getTaxpayerIdentificationNumber())
                .build();

        List<ProfitSharingPartnerDetailDTO> list = new ArrayList<>();
        if (needIncludesSourceCompany) {
            ChinaumsAuthInfo sourceAuthInfo = chinaumsAuthInfoRepository.findFirstByCompanyId(sourceCompany.getId());
            ProfitSharingPartnerDetailDTO sourceDetailDTO = ProfitSharingPartnerDetailDTO
                    .builder()
                    .relMerWalletId(sourceCompany.getWalletId())
                    .relMerName(sourceCompany.getName())
                    .isSettBank("0")
                    .bankNo(sourceAuthInfo.getSettleAcctBankBranchCode())
                    .bankName(sourceAuthInfo.getSettleAcctBankName())
                    .elecBankNo(sourceAuthInfo.getElecBankNo())
                    .bankAcctNo(sourceAuthInfo.getSettleAcctBankAcctNo())
                    .bankAcctName(sourceAuthInfo.getSettleAcctName())
                    .idCard(sourceAuthInfo.getIdCardNumber())
                    .bankAcctType(0)
                    .companyName(sourceCompany.getName())
                    .bizLicNo(sourceCompany.getTaxpayerIdentificationNumber())
                    .build();
            list.add(sourceDetailDTO);
        }
        list.add(profitSharingPartnerDetailDTO);
        return ProfitSharingPartnerDTO
                .builder()
                .merWalletId(thirdPartyConfigUtil.getPlatform().getChinaumsFeeBalanceAcctId())
                .merName(targetCompany.getName())
                .bizType("030001")
                .list(list)
                .build();
    }
}
