package com.ruoyi.ss.channel.service.impl;

import com.ruoyi.common.auth.ali.AliConfig;
import com.ruoyi.common.pay.tm.config.TmPayConfig;
import com.ruoyi.common.pay.wx.config.WxPayConfig;
import com.ruoyi.common.pay.xy.config.XyPayConfig;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.ss.app.domain.AppConfig;
import com.ruoyi.ss.app.domain.AppVO;
import com.ruoyi.ss.app.service.AppService;
import com.ruoyi.ss.channel.domain.ChannelConfig;
import com.ruoyi.ss.channel.domain.ChannelVO;
import com.ruoyi.ss.channel.domain.enums.ChannelApiType;
import com.ruoyi.ss.channel.service.ChannelConverter;
import com.ruoyi.ss.channel.service.ChannelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author wjh
 * 2025/1/7
 */
@Service
@Slf4j
public class ChannelConverterImpl implements ChannelConverter {

    @Autowired
    private ChannelService channelService;

    @Autowired
    private AppService appService;

    private static final String WX_NOTIFY_URL = SpringUtils.getRequiredProperty("wx.pay.notifyUrl");
    private static final String WX_REFUND_NOTIFY_URL = SpringUtils.getRequiredProperty("wx.pay.refundNotifyUrl");
    private static final String ALI_NOTIFY_URL = SpringUtils.getRequiredProperty("ali.notifyUrl");
    private static final String ALI_TRANSFER_NOTIFY_URL = SpringUtils.getRequiredProperty("ali.transferNotifyUrl");
    private static final String TM_NOTIFY_URL = SpringUtils.getRequiredProperty("tm.notifyUrl");
    private static final String XY_NOTIFY_URL = SpringUtils.getRequiredProperty("xy.notifyUrl");

    @Override
    public Object toConfig(ChannelVO channel, AppVO app) {
        if (channel == null || channel.getChannelConfig() == null) {
            return null;
        }
        if (app == null) {
            app = new AppVO();
        }

        // 微信
        if (ChannelApiType.WECHAT.getType().equals(channel.getApiType())) {
            return toWxPayConfig(channel, app);
        }
        // 支付宝
        else if (ChannelApiType.ALI.getType().equals(channel.getApiType())) {
            return toAliConfig(app);
        }
        // 太米
        else if (ChannelApiType.TM_WX.getType().equals(channel.getApiType())) {
            return toTmPayConfig(channel);
        }
        // 国通星驿
        else if (ChannelApiType.XY_WX.getType().equals(channel.getApiType())) {
            return toXyPayConfig(channel, app);
        }

        return null;
    }

    private XyPayConfig toXyPayConfig(ChannelVO channel, AppVO app) {
        XyPayConfig config = new XyPayConfig();

        if (channel != null) {
            config.setNotifyUrl(XY_NOTIFY_URL + "/" + channel.getChannelId());
        }
        if (channel != null && channel.getChannelConfig() != null) {
            ChannelConfig channelConfig = channel.getChannelConfig();
            config.setPublicKey(channelConfig.getPublicKey());
            config.setAgetId(channelConfig.getAgetId());
            config.setCustId(channelConfig.getCustId());
            config.setHost(channelConfig.getHost());
        }
        if (app != null && app.getConfig() != null) {
            AppConfig appConfig = app.getConfig();
            config.setAppId(appConfig.getAppId());
        }
        return config;
    }

    private TmPayConfig toTmPayConfig(ChannelVO channel) {
        TmPayConfig config = new TmPayConfig();
        if (channel != null) {
            config.setNotifyUrl(TM_NOTIFY_URL + "/" + channel.getChannelId());
        }
        if (channel != null && channel.getChannelConfig() != null) {
            ChannelConfig channelConfig = channel.getChannelConfig();
            config.setDeveloperId(channelConfig.getDeveloperId());
            config.setShopId(channelConfig.getShopId());
            config.setSignKey(channelConfig.getSignKey());
            config.setHttpUrl(channelConfig.getHttpUrl());
            config.setSn(channelConfig.getSn());
        }
        return config;
    }

    private AliConfig toAliConfig(AppVO app) {
        AliConfig config = new AliConfig();

        if (app != null) {
            config.setNotifyUrl(ALI_NOTIFY_URL + "/" + app.getId());
            config.setTransferNotifyUrl(ALI_TRANSFER_NOTIFY_URL + "/" + app.getId());
            if (app.getConfig() != null) {
                AppConfig appConfig =  app.getConfig();
                config.setAppId(appConfig.getAppId());
                config.setPrivateKey(appConfig.getPrivateKey());
                config.setAesPrivateKey(appConfig.getAesPrivateKey());
                config.setAppCertPath(appConfig.getAppCertPath());
                config.setAlipayCertPath(appConfig.getAlipayCertPath());
                config.setAlipayRootCertPath(appConfig.getAlipayRootCertPath());
            }
        }
        return config;
    }

    @Override
    public WxPayConfig toWxPayConfig(Long channelId, Long appId) {
        ChannelVO channel = channelService.selectSmChannelByChannelId(channelId);
        if (channel == null) {
            log.error("ID为{}的支付渠道不存在", channelId);
            return null;
        }

        AppVO app = appService.selectAppById(appId);
        if (app == null) {
            log.error("ID为{}的APP不存在", appId);
            return null;
        }

        return this.toWxPayConfig(channel, app);
    }

    @Override
    public WxPayConfig toWxPayConfig(ChannelVO channel, AppVO app) {
        WxPayConfig config = new WxPayConfig();

        if (channel != null && app != null) {
            config.setNotifyUrl(WX_NOTIFY_URL + "/" + channel.getChannelId() + "/" + app.getId());
            config.setRefundNotifyUrl(WX_REFUND_NOTIFY_URL + "/" + channel.getChannelId() + "/" + app.getId());
        }
        if (channel != null && channel.getChannelConfig() != null) {
            ChannelConfig channelConfig = channel.getChannelConfig();
            config.setMerchantId(channelConfig.getMerchantId());
            config.setApiV3Key(channelConfig.getApiV3Key());
            config.setPrivateKeyPath(channelConfig.getPrivateKeyPath());
            config.setMerchantSerialNumber(channelConfig.getMerchantSerialNumber());
        }
        if (app != null && app.getConfig() != null) {
            AppConfig appConfig = app.getConfig();
            config.setAppId(appConfig.getAppId());
        }

        return config;
    }
}
