package com.ruoyi.cai.pay;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ijpay.alipay.AliPayApiConfig;
import com.ijpay.alipay.AliPayApiConfigKit;
import com.ruoyi.cai.domain.PayConfig;
import com.ruoyi.cai.domain.PayTotal;
import com.ruoyi.cai.service.PayConfigService;
import com.ruoyi.cai.service.PayTotalService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Component
@Slf4j
public class PayConfigManager {
    private static final Map<Long,PayConfig> PAY_CONFIGS_MAP = new ConcurrentHashMap<>();
    @Autowired
    private PayConfigService payConfigService;
    @Autowired
    private PayTotalService payTotalService;

    @PostConstruct
    public void init(){
        List<PayConfig> list = payConfigService.list(Wrappers.lambdaQuery(PayConfig.class));
        for (PayConfig payConfig : list) {
            PAY_CONFIGS_MAP.put(payConfig.getId(), payConfig);
        }
    }

    public Collection<PayConfig> getAllPayConfig(){
        return PAY_CONFIGS_MAP.values();
    }

    // 1支付宝2微信
    public void addPayConfig(PayConfig payConfig) {
        PAY_CONFIGS_MAP.put(payConfig.getId(),payConfig);
    }

    public void updatePayConfig(PayConfig payConfig) {
        PAY_CONFIGS_MAP.put(payConfig.getId(),payConfig);
        if(PayTypeEnum.ALI.getCode().equals(payConfig.getPayType())){
            AliPayApiConfigKit.removeApiConfig(payConfig.getAppid());
        }
    }

    public void deletePayConfig(PayConfig payConfig) {
        PAY_CONFIGS_MAP.remove(payConfig.getId());
        if(PayTypeEnum.ALI.getCode().equals(payConfig.getPayType())){
            AliPayApiConfigKit.removeApiConfig(payConfig.getAppid());
        }
    }

    public PayConfig getWxConfig(){
        Collection<PayConfig> values = PAY_CONFIGS_MAP.values();
        Map<String,PayConfig> using = new HashMap<>();
        for (PayConfig value : values) {
            if(PayTypeEnum.WX.getCode().equals(value.getPayType())){
                using.put(value.getWxMcid(),value);
            }
        }
        if(using.isEmpty()){
            return null;
        }
        Set<String> aliAppIds = using.keySet();
        List<PayTotal> totals = payTotalService.listByWxMcid(aliAppIds);
        List<String> payIds = totals.stream()
                .sorted(Comparator.comparing(PayTotal::getMoney))
                .map(PayTotal::getPayId).collect(Collectors.toList());
        for (String aliAppId : aliAppIds) {
            if(!payIds.contains(aliAppId)){
                return using.get(aliAppId);
            }
        }
        return using.get(payIds.get(0));
    }

    public PayConfig getAliConfig(){
        Collection<PayConfig> values = PAY_CONFIGS_MAP.values();
        Map<String,PayConfig> using = new HashMap<>();
        for (PayConfig value : values) {
            if(PayTypeEnum.ALI.getCode().equals(value.getPayType())){
                using.put(value.getWxMcid(),value);
            }
        }
        if(using.isEmpty()){
            return null;
        }
        Set<String> wxMcidSet = using.keySet();
        List<PayTotal> totals = payTotalService.listByAliAppId(wxMcidSet);
        List<String> payIds = totals.stream()
                .sorted(Comparator.comparing(PayTotal::getMoney))
                .map(PayTotal::getPayId).collect(Collectors.toList());
        for (String wxMcid : wxMcidSet) {
            if(!payIds.contains(wxMcid)){
                return using.get(wxMcid);
            }
        }
        return using.get(payIds.get(0));
    }


    public boolean initAliPay() {
        PayConfig payConfig = this.getAliConfig();
        if(payConfig == null){
            return false;
        }
        AliPayApiConfig aliPayApiConfig;
        try {
            aliPayApiConfig = AliPayApiConfigKit.getApiConfig(payConfig.getAppid());
        } catch (Exception e) {
            log.error("实例化AliPayApiConfig...");
            // 如果Map中没有当前支付宝的实例就初始化并添加到Map中
            aliPayApiConfig = AliPayApiConfig.builder()
                    .setAppId(payConfig.getAppid())
                    .setAliPayPublicKey(payConfig.getPublicKey())
                    .setCharset("UTF-8")
                    .setPrivateKey(payConfig.getPrivateKey())
                    .setServiceUrl(payConfig.getNotifyUrl())
                    .setSignType("RSA2")
                    .build();
        }
        AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig);
        return true;
    }

    public PayConfig getAliConfigByAppId(String appId) {
        Collection<PayConfig> values = PAY_CONFIGS_MAP.values();
        for (PayConfig value : values) {
            if(value.getAppid() != null && value.getAppid().equals(appId)){
                return value;
            }
        }
        return null;
    }

    public PayConfig getWxConfigByMchId(String mchId) {
        Collection<PayConfig> values = PAY_CONFIGS_MAP.values();
        for (PayConfig value : values) {
            if(value.getWxMcid() != null && value.getWxMcid().equals(mchId)){
                return value;
            }
        }
        return null;
    }
}
