package com.neusoft.smart.pos.payment.service;

import com.alibaba.fastjson.JSON;
import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.dto.payment.request.*;
import com.neusoft.smart.pos.dto.payment.response.*;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.framework.utils.*;
import com.neusoft.smart.pos.payment.constants.PaymentConstants;
import com.neusoft.smart.pos.payment.constants.PaymentErrorCode;
import com.neusoft.smart.pos.payment.persistent.domain.PayOrder;
import com.neusoft.smart.pos.payment.repository.*;
import com.neusoft.smart.pos.payment.utils.LogUtils;
import lombok.val;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


@Service("FumaoPayService")
public class FumaoPayService {

    private final static Logger logger = LoggerFactory.getLogger(PayService.class);

	@Autowired
    private MchPayChannelRepository mchPayChannelRepository;

    @Autowired
    private PayOrderRepository payOrderRepository;

    @Autowired
    private PayTypeDictRepository payTypeDictRepository;

    @Autowired
    private MchPayInfoRepository mchPayInfoRepository;
    
    @Autowired
    FumaoPayRepository fumaoPayRepository;

    /**
     * 绗¬涓夋柟鏀¯浠樺崟鐢熸垚鏂规硶
     * @return
     */
    public PostGenerateOrderResponse createPayOrder(PostGenerateOrderRequest payOrderRequest) {
        //1.鏍规嵁鍟嗘埛鍙锋煡璇㈠晢鎴蜂俊鎭
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(payOrderRequest.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        if(null == mchPayInfo){
            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
        }

        //2.鏍￠獙绛惧悕淇℃伅
        if(!SignUtils.isSignatureValid(MapBeanUtils.beanToMap(payOrderRequest),mchPayInfo.getSecretKey())){
            throw new BusinessCommonException(PaymentErrorCode.SIGN_VALID_ERROR);
        }

        //3.鏍￠獙璁㈠崟澶辨晥鏃堕棿鏄¯鍚﹀悎娉曪紝璁㈠崟澶辨晥鏃堕棿鑷冲皯涓庡綋鍓嶆椂闂撮棿闅5鍒嗛挓,濡備綍涓虹┖鍒欓粯璁よ®剧疆涓º2灏忔椂
        if(StringUtils.isEmpty(payOrderRequest.getTimeExpire())){
            String localDateTime = LocalDateTimeUtils.convertLocalDateTimeToString(LocalDateTimeUtils.plusMinutes(LocalDateTimeUtils.getNow(), PaymentConstants.DEFAULT_TIME_EXPIRE),LocalDateTimeUtils.SIMPLE_DATETIME_FORMAT);
            payOrderRequest.setTimeExpire(localDateTime);
        }else{
            val betweenMinutes = LocalDateTimeUtils.betweenNowMinutes(LocalDateTimeUtils.convertStringToLocalDateTime(payOrderRequest.getTimeExpire(),LocalDateTimeUtils.SIMPLE_DATETIME_FORMAT));
            if(betweenMinutes < 5){
                throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_TIME_EXPIRE_TOO_SHORT);
            }
        }

        //4.鏁寸悊鏀¯浠樺钩鍙伴¢勪粯鍗曚俊鎭
        val tradeId = IdGenerateUtils.generateTradeId();    //褰撳墠鏃堕棿姣«绉掓暟+5浣嶉殢鏈烘暟
        val payOrder = payOrderDataHandle(tradeId,payOrderRequest);

        //5.鏍￠獙鏀¯浠樻垚鍔熷洖璋僽rl
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(payOrder.getMcode(),payOrder.getPayType());
        if(null == mchPayChannel){
            throw new BusinessCommonException(PaymentErrorCode.MCH_THIRD_PLATFORM_NOT_CONFIG);
        }

        //6.鐢熸垚绗¬涓夋柟鏀¯浠樺钩鍙伴¢勪粯鍗曚俊鎭
        if(StringUtils.isEmpty(mchPayChannel.getNotifyUrl()) && StringUtils.isEmpty(payOrder.getNotifyUrl())){
            throw new BusinessCommonException(PaymentErrorCode.MCH_NOTIFY_URL_EMPTY);
        }else if(StringUtils.isEmpty(payOrder.getNotifyUrl())){
            payOrder.setNotifyUrl(mchPayChannel.getNotifyUrl());
        }
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(payOrder.getPayType());
        //鏍规嵁BeanName鑾峰彇spring瀹炵幇绫
        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayRepository.class);
        val thirdPlatformOrder = thirdPayRepository.createPayOrderToThirdPlatform(payOrder,mchPayChannel,payTypeDict);

        //7.鏍规嵁绗¬涓夋柟骞冲彴棰勪粯鍗曚俊鎭¯鏇存柊鏀¯浠樺钩鍙伴¢勪粯鍗曚俊鎭
        payOrder.setOuterOrderNumber(thirdPlatformOrder.getOuterOrderNumber());
        payOrder.setCodeUrl(thirdPlatformOrder.getOuterCodeUrl());
//        payOrder.setOrderStatus(thirdPlatformOrder.getPayStatus());
        payOrderRepository.createPayOrder(payOrder);

        //8.鏁寸悊杩斿洖鏁版嵁骞惰®板綍鐩稿叧鏃ュ織锛屽紓甯镐俊鎭¯鍙¯涓嶈®板綍鏃ュ織锛屽湪鏃ュ織鏂囦欢涓­鍙¯鏌ョ湅
        val postGenerateOrderResponse = new PostGenerateOrderResponse(thirdPlatformOrder.getMcode(),payOrderRequest.getPayType(),thirdPlatformOrder.getOuterCodeUrl(),payOrderRequest.getTimeExpire(),tradeId,thirdPlatformOrder.getOuterOrderNumber(),thirdPlatformOrder.getMOrderNumber(),thirdPlatformOrder.getPayStatus());
        val sign = SignUtils.generateSign(MapBeanUtils.beanToMap(postGenerateOrderResponse),mchPayInfo.getSecretKey());
        postGenerateOrderResponse.setSign(sign);
        LogUtils.saveMchPaymentTradeLog(thirdPlatformOrder.getMcode(),thirdPlatformOrder.getMOrderNumber(),payOrder.getPayType(),LogUtils.LOG_DESCRIPTION_DDSC,JSON.toJSONString(postGenerateOrderResponse), JSON.toJSONString(payOrderRequest),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
        return postGenerateOrderResponse;
    }

    /**
     * 鐢熸垚鑱氬悎骞冲彴棰勪粯鍗曚俊鎭
     * @param tradeId
     * @param payOrderRequest
     */
    private PayOrder payOrderDataHandle(String tradeId, PostGenerateOrderRequest payOrderRequest){
        //1.鏌ヨ¯¢涓氬姟璁㈠崟鏄¯鍚﹀凡缁忕敓鎴
        val payOrderTemp = payOrderRepository.queryPayOrder(payOrderRequest.getMcode(),payOrderRequest.getOrderNumber(),payOrderRequest.getPayType());
        if(null != payOrderTemp){
            throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_REPEAT);
        }
        //2.鏁寸悊璁㈠崟鏁版嵁
        val payOrder = new PayOrder();
        BeanUtils.copyProperties(payOrderRequest,payOrder);
        payOrder.setmOrderNumber(payOrderRequest.getOrderNumber());
        payOrder.setTradeId(tradeId);
        payOrder.setPayIp(payOrderRequest.getIp());
        return payOrder;
    }

    public FumaoMemberInfoRes queryAndCalc(FumaoPayRequest fumaoPayRequest) {
    	return fumaoPayRepository.fumaoMemberInfoToThirdPlatform(fumaoPayRequest);
    }
    
//    public FumaoCheckCouponRes checkCouponOrderForVerify(FumaoPayRequest fumaoPayRequest) {
//    	return fumaoPayRepository.checkCouponOrderForVerify(fumaoPayRequest);
//    }
    
//    public FumaoCouponVerifyRes couponOrderVerify(FumaoPayRequest fumaoPayRequest) {
//    	return fumaoPayRepository.couponOrderVerify(fumaoPayRequest);
//    }

//    public FumaoCardPayRes cardPayPre(FumaoPayRequest fumaoPayRequest) {
//        return fumaoPayRepository.cardPayPre(fumaoPayRequest);
//    }
    
}
