package org.dromara.mp.config;

import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.redis.JedisWxRedisOps;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 微信公众号配置
 *
 * @author pengles
 *
 * 微信公众号服务端装配：
 * - 读取 wx.mp.* 配置，支持多公众号与可选 Redis 存储
 * - 注入 WxMpService 与消息路由器，用于处理消息、二维码、模板消息等能力
 */
@Configuration
@EnableConfigurationProperties(WxMpProperties.class)
@ConditionalOnClass(WxMpService.class)
@RequiredArgsConstructor
public class WxMpConfiguration {

    private final WxMpProperties properties;

    /**
     * 构建 WxMpService，支持多公众号配置与 Redis 存储
     */
    @Bean
    @ConditionalOnMissingBean
    public WxMpService wxMpService() {
        final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
        if (configs == null || configs.isEmpty()) {
            throw new RuntimeException("请先配置微信公众号相关信息！");
        }

        WxMpService service = new WxMpServiceImpl();
        service.setMultiConfigStorages(configs
                .stream().map(a -> {
                    WxMpDefaultConfigImpl configStorage;
                    if (this.properties.isUseRedis()) {
                        final WxMpProperties.RedisConfig redisConfig = this.properties.getRedisConfig();
                        JedisPoolConfig poolConfig = new JedisPoolConfig();
                        JedisPool jedisPool = new JedisPool(poolConfig, redisConfig.getHost(), redisConfig.getPort(),
                                redisConfig.getTimeout(), redisConfig.getPassword());
                        configStorage = new WxMpRedisConfigImpl(new JedisWxRedisOps(jedisPool), a.getAppId());
                    } else {
                        configStorage = new WxMpDefaultConfigImpl();
                    }

                    configStorage.setAppId(a.getAppId());
                    configStorage.setSecret(a.getSecret());
                    configStorage.setToken(a.getToken());
                    configStorage.setAesKey(a.getAesKey());
                    configStorage.setOauth2RedirectUrl(a.getOauth2RedirectUrl());
                    configStorage.setQrConnectRedirectUrl(a.getQrConnectRedirectUrl());
                    return configStorage;
                }).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
        return service;
    }

    /**
     * 构建消息路由器，按规则分发处理入口消息
     */
    @Bean
    public WxMpMessageRouter messageRouter(WxMpService wxMpService) {
        return new WxMpMessageRouter(wxMpService);
    }
}
