package com.yonge.cooleshow.biz.dal.service.impl;



import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.microsvc.toolkit.middleware.payment.common.api.BasePaymentService;
import com.microsvc.toolkit.middleware.payment.common.api.PaymentServiceContext;
import com.microsvc.toolkit.middleware.payment.common.api.entity.PaymentMerchant;
import com.yonge.cooleshow.biz.dal.entity.PaymentMerchantConfig;
import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
import com.yonge.cooleshow.biz.dal.mapper.SysAreaMapper;
import com.yonge.cooleshow.biz.dal.service.PaymentMerchantConfigService;
import com.yonge.cooleshow.biz.dal.service.SysConfigService;
import com.yonge.cooleshow.common.constant.SysConfigConstant;
import com.yonge.cooleshow.common.enums.EPayerType;
import com.yonge.toolset.base.exception.BizException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import com.yonge.cooleshow.biz.dal.entity.TenantMember;
import com.yonge.cooleshow.biz.dal.wrapper.TenantMemberWrapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantMemberMapper;
import com.yonge.cooleshow.biz.dal.service.TenantMemberService;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
 * @Author：haonan
 * @Date：2023/8/10 13:41
 * @Filename：TenantMemberServiceImpl
 */



/**
 * 机构子账户表
 * 2023-08-10 13:36:39
 */
@Slf4j
@Service
public class TenantMemberServiceImpl extends ServiceImpl<TenantMemberMapper, TenantMember> implements TenantMemberService {

    @Autowired
    private SysAreaMapper sysAreaMapper;

    @Autowired
    private PaymentServiceContext paymentServiceContext;

    @Autowired
    private PaymentMerchantConfigService paymentMerchantConfigService;

    @Autowired
    private SysConfigService sysConfigService;

    /**
     * 查询详情
     * @param id 详情ID
     * @return TenantMember
     */
    @Override
    public TenantMember detail(Long id) {

        return baseMapper.selectById(id);
    }

    /**
     * 分页查询
     * @param page IPage<TenantMember>
     * @param query TenantMemberWrapper.TenantMemberQuery
     * @return IPage<TenantMember>
     */
    @Override
    public IPage<TenantMemberWrapper.TenantMember> selectPage(IPage<TenantMemberWrapper.TenantMember> page, TenantMemberWrapper.TenantMemberQuery query) {
        List<TenantMemberWrapper.TenantMember> tenantMembers = baseMapper.selectPage(page, query);
        if (tenantMembers.isEmpty()) {
            return page.setRecords(tenantMembers);
        }
//        //设置省市中文名称
//        List<Integer> areaCodeList = tenantMembers.stream().map(next -> {
//            HashSet<Integer> areaCodes = new HashSet<>();
//            areaCodes.add(Integer.valueOf(next.getProvCode()));
//            areaCodes.add(Integer.valueOf(next.getAreaCode()));
//            areaCodes.add(next.getDistrictCode()!= null?Integer.valueOf(next.getDistrictCode()):null);
//            return areaCodes;
//        }).flatMap(Collection::stream).filter(Objects::nonNull).distinct().collect(Collectors.toList());
//        if (!areaCodeList.isEmpty()) {
//            QueryWrapper<SysArea> queryWrapper = new QueryWrapper<>();
//            queryWrapper.lambda().in(SysArea::getCode, areaCodeList);
//
//            Map<Integer, String> codeNameMap = sysAreaMapper.selectList(queryWrapper)
//                    .stream().collect(Collectors.toMap(SysArea::getCode, SysArea::getName));
//
//            tenantMembers.forEach(next -> {
//                next.setProvName(codeNameMap.getOrDefault(Integer.valueOf(next.getProvCode()), ""));
//                next.setAreaName(codeNameMap.getOrDefault(Integer.valueOf(next.getAreaCode()), ""));
//                next.setDistrictName(codeNameMap.getOrDefault(Integer.valueOf(next.getDistrictCode()), ""));
//            });
//        }
        return page.setRecords(tenantMembers);
    }

    /**
     * 添加
     * @param tenantMember TenantMemberWrapper.TenantMember
     * @return Boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(TenantMemberWrapper.InsertOrUpdateTenantMember tenantMember) {

        Integer count = this.lambdaQuery()
            .eq(TenantMember::getTenantId, tenantMember.getTenantId())
            .eq(TenantMember::getPayerName, tenantMember.getPayerName())
            .count();
        if (count > 0) {
            throw new BizException("该机构已创建成功，请核查");
        }

        PaymentMerchant.MerchantConfig merchantConfig = getMerchantConfig(tenantMember.getPayerName());
        tenantMember.setRequestNo(IdWorker.getIdStr());

        // 创建账户
        BasePaymentService paymentService = paymentServiceContext.getPaymentService(tenantMember.getPayerName());
        if (paymentService == null) {
            throw new BizException("支付渠道不存在");
        }

        PaymentMerchant.MerchantMember merchantMember = getMerchantMember(tenantMember);
        try {
            log.info("创建子账户参数:{}", JSON.toJSONString(merchantConfig));
            Map<String, Object> paymentCorpMember = paymentService.createPaymentCorpMember(merchantConfig, merchantMember);
            if (tenantMember.getPayerType().equals(EPayerType.YEEPAY)) {
                tenantMember.setMemberId(paymentCorpMember.get("merchantNo").toString());
//                tenantMember.setRequestNo(paymentCorpMember.get("requestNo").toString());
            }
        }catch (Exception e) {
            log.error("创建子账户失败", e);
            throw new BizException("创建子账户失败:" + e.getMessage());
        }
        tenantMember.setMultipartFile(null);
        TenantMember member = JSON.parseObject(tenantMember.jsonString(), TenantMember.class);
        member.setStatus(AuthStatusEnum.DOING);
        return this.save(member);
    }

    private PaymentMerchant.MerchantMember getMerchantMember(TenantMemberWrapper.InsertOrUpdateTenantMember tenantMember) {
        PaymentMerchant.MerchantMember merchantMember = PaymentMerchant.MerchantMember.builder()
                .memberId(tenantMember.getMemberId())
                .merchantName(tenantMember.getName())
                .merchantType(tenantMember.getMerchantType())
                .provinceCode(tenantMember.getProvCode())
                .cityCode(tenantMember.getAreaCode())
                .districtCode(tenantMember.getDistrictCode())
                .socialCreditCode(tenantMember.getSocialCreditCode())
                .socialCreditCodeExpires(tenantMember.getSocialCreditCodeExpires())
                .businessScope(tenantMember.getBusinessScope())
                .legalName(tenantMember.getLegalPerson())
                .legalLicenceNo(tenantMember.getLegalCertId())
                .legalCertIdExpires(tenantMember.getLegalCertIdExpires())
                .mobile(tenantMember.getLegalMp())
                .legalLicenceType(tenantMember.getLegalLicenceType())
                .legalLicenceFrontUrl(tenantMember.getLegalLicenceFrontUrl())
                .legalLicenceBackUrl(tenantMember.getLegalLicenceBackUrl())
                .address(tenantMember.getAddress())
                .attachFile(tenantMember.getFile())
                .bankCode(tenantMember.getBankCode())
                .bankAccountType(tenantMember.getBankAcctType())
                .bankCardNo(tenantMember.getCardNo())
                .cardName(tenantMember.getCardName())
                .zipCode(tenantMember.getZipCode())
                .requestNo(tenantMember.getRequestNo())
                .licenceNo(tenantMember.getSocialCreditCode())
                .licenceUrl(tenantMember.getLicenceUrl())
                .openAccountLicenceUrl(tenantMember.getOpenAccountLicenceUrl())
                .contactName(tenantMember.getContactName())
                .contactMobile(tenantMember.getContactMobile())
                .contactEmail(tenantMember.getContactEmail())
                .contactLicenceNo(tenantMember.getContactLicenceNo())
                .primaryIndustryCategory("120")
                .secondaryIndustryCategory("120004")
                .settlementDirection("BANKCARD")
                .build();
        if (tenantMember.getPayerType().equals(EPayerType.ADAPAY)) {
            merchantMember.setNotifyUrl(sysConfigService.findConfigValue(SysConfigConstant.SUB_ACCOUNT_CREATE_CALLBACK_URL) +
                    "/" + EPayerType.ADAPAY.getDesc());
        } else if (tenantMember.getPayerType().equals(EPayerType.YEEPAY)) {
            merchantMember.setNotifyUrl(sysConfigService.findConfigValue(SysConfigConstant.SUB_ACCOUNT_CREATE_CALLBACK_URL )+
                    "/" + EPayerType.YEEPAY.getDesc());
        }
        return merchantMember;

    }

    @Override
    public PaymentMerchant.MerchantConfig getMerchantConfig(String paymentVerdor) {
        // 注册对应的子账户
        PaymentMerchantConfig merchantConfig = paymentMerchantConfigService.getByPaymentVendor(paymentVerdor);

        if (merchantConfig == null) {
            throw new BizException("支付渠道不存在");
        }

        return PaymentMerchant.MerchantConfig.builder()
                .payerName(paymentVerdor)
                .appId(merchantConfig.getAppId())
                .merchantKey(merchantConfig.getMerKey())
                .apiKey(merchantConfig.getApiKey())
                .rsaPrivateKey(merchantConfig.getRsaPrivateKey())
                .rsaPublicKey(merchantConfig.getRsaPublicKey())
                .wxAppId(merchantConfig.getWxAppId())
                .wxAppSecret(merchantConfig.getWxAppSecret())
                .alipayAppId(merchantConfig.getAlipayAppId())
                .alipayPublicKey(merchantConfig.getAlipayPublicKey())
                .platformPayeeMemberId(merchantConfig.getPlatformPayeeMemberId())
                .build();
    }

    /**
     * 更新
     * @param tenantMember TenantMemberWrapper.TenantMember
     * @return Boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(TenantMemberWrapper.InsertOrUpdateTenantMember tenantMember){
        Integer count = this.lambdaQuery()
            .eq(TenantMember::getId, tenantMember.getId())
            .count();
        if (count == 0) {
            throw new BizException("商户不存在请核对");
        }


        TenantMember member = this.getById(tenantMember.getId());

        PaymentMerchant.MerchantConfig merchantConfig = getMerchantConfig(tenantMember.getPayerName());

        // 创建账户
        BasePaymentService paymentService = paymentServiceContext.getPaymentService(tenantMember.getPayerName());
        if (paymentService == null) {
            throw new BizException("支付渠道不存在");
        }
        PaymentMerchant.MerchantMember merchantMember = getMerchantMember(tenantMember);

        try {
            if (member.getPayerName().equals(tenantMember.getPayerName())) {
                Boolean aBoolean = paymentService.updatePaymentCorpMember(merchantConfig, merchantMember);
                if (!aBoolean) {
                    throw new BizException("更新子账户失败");
                }
            } else {
                Map<String, Object> paymentCorpMember = paymentService.createPaymentCorpMember(merchantConfig, merchantMember);
            }
        }catch (Exception e) {
            log.error("更新子账户失败", e);
            throw new BizException("更新子账户失败:" + e.getMessage());
        }

        tenantMember.setMultipartFile(null);
        TenantMember object = JSON.parseObject(tenantMember.jsonString(), TenantMember.class);
        object.setStatus(AuthStatusEnum.DOING);
        return this.updateById(object);
    }

    /**
     * 修改结算账户
     * @param tenantMember
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateCount(TenantMemberWrapper.UpdateCount tenantMember) {

        TenantMember member = getById(tenantMember.getId());
        if (member == null) {
            throw new BizException("商户不存在请核对");
        }
        if (!member.getStatus().equals(AuthStatusEnum.PASS)) {
            throw new BizException("商户审核通过，才能绑定结算卡");
        }

        member.setBankCode(tenantMember.getBankCode());
        member.setCardNo(tenantMember.getCardNo());

        PaymentMerchant.MerchantConfig merchantConfig = getMerchantConfig(member.getPayerName());

        // 创建账户
        BasePaymentService paymentService = paymentServiceContext.getPaymentService(member.getPayerName());
        if (paymentService == null) {
            throw new BizException("支付渠道不存在");
        }

        try {
            //删除结算账户
            if (StringUtils.isNotBlank(member.getSettleAccountId())) {
                paymentService.deleteSettleAccount(merchantConfig.getMerchantKey(), merchantConfig.getAppId(), member.getMemberId(), member.getSettleAccountId());
            }

            PaymentMerchant.AccountInfo accountInfo = PaymentMerchant.AccountInfo.builder()
                .memberId(member.getMemberId())
                .cardId(member.getCardNo())
                .cardName(member.getCardName())
                .areaCode(member.getAreaCode())
                .bankAcctType(member.getBankAcctType())
                .bankCode(member.getBankCode())
                .bankName(member.getBankCode())
                .provCode(member.getProvCode())
                .telNo(member.getLegalMp())
                .build();
            //创建结算账户
            String settleAccountId = paymentService.createSettleAccount(merchantConfig, accountInfo);

            member.setSettleAccountId(settleAccountId);
        }catch (Exception e) {
            log.error("更新结算账户失败", e);
            throw new BizException("更新结算账户失败:" + e.getMessage());
        }
        return this.updateById(member);
    }

    @Override
    public TenantMember getByMemberId(String memberId, EPayerType payerType) {
        return this.lambdaQuery()
                .eq(TenantMember::getMemberId, memberId)
                .eq(TenantMember::getPayerName, payerType.name())
                .last("limit 1")
                .one();
    }

    @Override
    public TenantMember getByRequestNo(String requestNo) {
        return this.lambdaQuery()
                .eq(TenantMember::getRequestNo, requestNo)
                .last("limit 1")
                .one();
    }

    @Override
    public TenantMember getByAppIdAndTenantId(String appId, Long tenantId, EPayerType payerType) {
        return this.lambdaQuery()
//                .eq(TenantMember::getAppId, appId)
                .eq(TenantMember::getTenantId, tenantId)
                .eq(TenantMember::getStatus, AuthStatusEnum.PASS)
                .eq(TenantMember::getPayerType, payerType)
                .orderByDesc(TenantMember::getUpdateTime)
                .last("limit 1")
                .one();

    }

    @Override
    public PaymentMerchant.MerchantMember remoteDetail(Long id) {

        TenantMember tenantMember = getById(id);

        TenantMember member = this.getById(tenantMember.getId());

        PaymentMerchant.MerchantConfig merchantConfig = getMerchantConfig(tenantMember.getPayerName());

        // 创建账户
        BasePaymentService paymentService = paymentServiceContext.getPaymentService(tenantMember.getPayerName());
        if (paymentService == null) {
            throw new BizException("支付渠道不存在");
        }
        PaymentMerchant.MerchantMember merchantMember = getMerchantMember(TenantMemberWrapper.InsertOrUpdateTenantMember.from(JSON.toJSONString(tenantMember)));

        return paymentService.getPaymentCorpMember(merchantConfig, merchantMember);

    }

}