package com.xingxi.unifiedpay.open;

import com.xingxi.unifiedpay.bean.BaseBiandanUnifiedpayRequest;
import com.xingxi.unifiedpay.bean.BaseBiandanUnifiedpayResponse;
import com.xingxi.unifiedpay.domain.MercUnifiedpayDTO;
import com.xingxi.unifiedpay.repository.XingxiUnifiedpayRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;


@Slf4j
@Component
@RequiredArgsConstructor
class XingxiUnifiedpayServiceImpl implements XingxiUnifiedpayServiceI {
    private final XingxiUnifiedpayRepository biandanUnifiedpayRepository;
    private final ApplicationContext applicationContext;

    @SuppressWarnings("unchecked")
    @Override
    public <T extends BaseBiandanUnifiedpayResponse> T getResponse(BaseBiandanUnifiedpayRequest<T> request) throws Exception {
        Long sellerId = request.getSellerId();
        MercUnifiedpayDTO mercUnifiedpayDTO = getMercUnifiedpayDTOByMercId(sellerId);
        String unifiedPayMethod = mercUnifiedpayDTO.getUnifiedPayMethod();

        Object unifiedpayServiceI = null;

        try {
            unifiedpayServiceI = applicationContext.getBean(unifiedPayMethod);
        } catch (BeansException e) {
            log.debug("支付服务[" + unifiedPayMethod + "]不存在");
            throw new RuntimeException("支付服务不存在");
        }

        String callMethod = request.getCallMethod();
        Method invokeMethod = ReflectionUtils.findMethod(unifiedpayServiceI.getClass(), callMethod, MercUnifiedpayDTO.class, request.getClass());
        if (ObjectUtils.isEmpty(invokeMethod)) {
            log.debug("接口[" + callMethod + "]不支持");
            throw new RuntimeException("接口不支持");
        }

        ReflectionUtils.makeAccessible(invokeMethod);
        return (T) ReflectionUtils.invokeMethod(
                invokeMethod,
                unifiedpayServiceI,
                mercUnifiedpayDTO,
                request
        );
    }


    private MercUnifiedpayDTO getMercUnifiedpayDTOByMercId(Long sellerId) {
        Assert.notNull(sellerId, "[sellerId]不能为空");
        // todo
        MercUnifiedpayDTO mercUnifiedpayDTO = new MercUnifiedpayDTO();
//        MercUnifiedpayDTO mercUnifiedpayDTO = biandanUnifiedpayRepository.selectMercUnifiedpayDTOByMercId(sellerId);
//        log.debug("[{}]", mercUnifiedpayDTO);
        return mercUnifiedpayDTO;
    }


}
