package com.seer.teach.pay.app.client.factory;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.seer.teach.common.enums.pay.PayChannelEnum;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.pay.app.client.PayClient;
import com.seer.teach.pay.entity.PayChannelEntity;
import com.seer.teach.pay.service.IPayChannelService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import jakarta.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 支付策略工厂,根据支付渠道编码获取对应的支付策略
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class PayClientFactory {

    private  final List<PayClient> payStrategies;

    private final IPayChannelService payChannelService;

    private static final Map<PayChannelEnum, PayClient> STRATEGY_MAP = new HashMap<>();

    @PostConstruct
    public void init() {
        for (PayClient strategy : payStrategies) {
            STRATEGY_MAP.put(strategy.getChannel(), strategy);
            log.info("注册支付渠道：{} -> {}", strategy.getChannel(), strategy.getClass().getSimpleName());
        }
        List<PayChannelEntity> channels = payChannelService.list(new LambdaUpdateWrapper<>(PayChannelEntity.class).eq(PayChannelEntity::getStatus, 1));
        AssertUtils.notEmpty(channels, ResultCodeEnum.PAY_CHANNEL_IS_NOT_EXIST);
        Integer count = 0;
        for (PayChannelEntity channel : channels) {
            PayClient strategy = STRATEGY_MAP.get(PayChannelEnum.fromCode(channel.getChannelCode()));
            if(Objects.nonNull(strategy) && StringUtils.hasText(channel.getConfigJson())){
                strategy.init(channel.getConfigJson());
                log.info("支付渠道：{} -> {}", channel.getChannelCode(), strategy.getClass().getSimpleName());
            }
        }
        log.info("支付策略工厂初始化完成，共注册{}个策略", count);
    }

    /**
     * 根据支付渠道编码获取支付策略
     * @param channel 支付渠道编码（如：WECHAT、ALIPAY）
     * @return 支付策略
     */
    public PayClient getPayClient(PayChannelEnum channel) {
        PayClient strategy = STRATEGY_MAP.get(channel);
        AssertUtils.notNull(strategy, ResultCodeEnum.PAY_CHANNEL_NOT_SUPPORTED);
        return strategy;
    }

    public PayClient getPayClient(String channelCode) {
        PayChannelEnum channel = PayChannelEnum.fromCode(channelCode);
        AssertUtils.notNull(channel, ResultCodeEnum.PAY_CHANNEL_IS_NOT_EXIST);
        PayClient strategy = STRATEGY_MAP.get(channel);
        AssertUtils.notNull(strategy, ResultCodeEnum.PAY_CHANNEL_NOT_SUPPORTED);
        return strategy;
    }
}