package com.neusoft.smart.pos.payorder.repository;

import com.alibaba.fastjson.JSON;
import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.dto.trade.request.DeleteDeletePayChannelRequest;
import com.neusoft.smart.pos.dto.trade.request.PostSavePayChannelRequest;
import com.neusoft.smart.pos.dto.trade.request.PutUpdatePayChannelRequest;
import com.neusoft.smart.pos.dto.trade.response.PostPayApplyMchInfoResponse;
import com.neusoft.smart.pos.framework.utils.MapBeanUtils;
import com.neusoft.smart.pos.order.constants.TradeConstant;
import com.neusoft.smart.pos.order.utils.HttpClientUtils;
import com.neusoft.smart.pos.payorder.persistent.domain.*;
import com.neusoft.smart.pos.payorder.persistent.mapper.PayOrderMapper;
import com.neusoft.smart.pos.utils.RequestHeaderUtil;
import lombok.val;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.DataInputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class PayOrderRepository {

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

    @Resource
    private PayOrderMapper payOrderMapper;
    /**
     * 支付平台订单保存方法
     * @param payOrder
     * @return
     */
    public Integer createPayOrder(PayOrder payOrder){
//		payOrder.setOrderStatus(DictionaryConstant.PAYMENT_ORDER_STATUS_DZF.getCode());
        payOrder.setPayStatus(DictionaryConstant.PAY_STATUS_WFK.getCode());
        if(!StringUtils.isEmpty(RequestHeaderUtil.getUsername())){
            payOrder.setCreatedBy(RequestHeaderUtil.getUsername());
        }
        return payOrderMapper.insertSelective(payOrder);
    }

    /**
     * 订单信息状态方法
     *
     * @param tradeId 支付单编号
     * @return 是否更新成功
     */
    public Boolean updatePayOrderStatusByTradeId(String tradeId, String payStatus) {
        PayOrder payOrder = new PayOrder();
        payOrder.setPayStatus(payStatus);
        payOrder.setUpdatedAt(new Date());
        if(!StringUtils.isEmpty(RequestHeaderUtil.getUsername())){
            payOrder.setUpdatedBy(RequestHeaderUtil.getUsername());
        }
        PayOrderExample example = new PayOrderExample();
        example.createCriteria().andTradeIdEqualTo(tradeId);
        int result = payOrderMapper.updateByExampleSelective(payOrder, example);
        return result > 0 ? true : false;
    }

    /**
     * 支付平台订单更新方法
     * @param tradeId 交易ID
     * @param mOrderNumber 业务系统订单号
     * @param payOrder 更新订单对象
     * @return
     */
    public Boolean updatePayOrder(String tradeId,String mOrderNumber,PayOrder payOrder){
        payOrder.setUpdatedAt(new Date());
        if(!StringUtils.isEmpty(RequestHeaderUtil.getUsername())){
            payOrder.setUpdatedBy(RequestHeaderUtil.getUsername());
        }
        val payOrderExample = new PayOrderExample();
        payOrderExample.createCriteria()
                .andTradeIdEqualTo(tradeId)
                .andMOrderNumberEqualTo(mOrderNumber);
        int count = payOrderMapper.updateByExampleSelective(payOrder,payOrderExample);
        return count > 0 ? true:false;
    }


    /**
     * 支付平台订单更新方法
     * @param mcode 商户号
     * @param tradeId 交易ID
     * @param mOrderNumber 业务系统订单号
     * @param payOrder 更新订单对象
     * @return
     */
    public Boolean updatePayOrder(String mcode,String tradeId,String mOrderNumber,PayOrder payOrder){
        payOrder.setUpdatedAt(new Date());
        if(!StringUtils.isEmpty(RequestHeaderUtil.getUsername())){
            payOrder.setUpdatedBy(RequestHeaderUtil.getUsername());
        }
        val payOrderExample = new PayOrderExample();
        payOrderExample.createCriteria()
                .andMcodeEqualTo(mcode)
                .andTradeIdEqualTo(tradeId)
                .andMOrderNumberEqualTo(mOrderNumber);
        int count = payOrderMapper.updateByExampleSelective(payOrder,payOrderExample);
        return count > 0 ? true:false;
    }


    /**
     * 支付平台订单支付状态更新方法
     * @param mcode 商户号
     * @param payType 支付方式
     * @param mOrderNumber 业务系统订单号
     * @param payOrder 更新订单对象
     * @return
     */
    public Boolean updateOrderPayStatus(PayOrder payOrder,String mcode,String mOrderNumber,String payType){
//		payOrder.setOrderStatus(DictionaryConstant.PAYMENT_ORDER_STATUS_YZF.getCode());
        payOrder.setPayStatus(DictionaryConstant.PAY_STATUS_YFK.getCode());
        payOrder.setUpdatedAt(new Date());
        if(!StringUtils.isEmpty(RequestHeaderUtil.getUsername())){
            payOrder.setUpdatedBy(RequestHeaderUtil.getUsername());
        }
        val payOrderExample = new PayOrderExample();
        payOrderExample.createCriteria()
                .andMcodeEqualTo(mcode)
                .andMOrderNumberEqualTo(mOrderNumber)
                .andPayStatusEqualTo(DictionaryConstant.PAY_STATUS_WFK.getCode())
                .andPayTypeEqualTo(payType);
        int count = payOrderMapper.updateByExampleSelective(payOrder,payOrderExample);
        return count > 0 ? true:false;
    }

    /**
     * 支付平台订单支付状态更新方法
     * @param mcode 商户号
     * @param payType 支付方式
     * @param mOrderNumber 业务系统订单号
     * @param payOrder 更新订单对象
     * @return
     */
    public Boolean updateOrderPayStatus(String orderStatus,PayOrder payOrder,String mcode,String mOrderNumber,String payType){
        payOrder.setPayStatus(orderStatus);
        payOrder.setUpdatedAt(new Date());
        if(!StringUtils.isEmpty(RequestHeaderUtil.getUsername())){
            payOrder.setUpdatedBy(RequestHeaderUtil.getUsername());
        }
        val payOrderExample = new PayOrderExample();
        payOrderExample.createCriteria()
                .andMcodeEqualTo(mcode)
                .andMOrderNumberEqualTo(mOrderNumber)
                .andPayStatusEqualTo(DictionaryConstant.PAY_STATUS_WFK.getCode())
                .andPayTypeEqualTo(payType);
        int count = payOrderMapper.updateByExampleSelective(payOrder,payOrderExample);
        return count > 0 ? true:false;
    }

    /**
     * 订单信息列表查询方法
     * @return
     */
    public List<PayOrder> queryPayOrder(String mcode, String mOrderNumber){
        val example = new PayOrderExample();
        example.createCriteria()
                .andMcodeEqualTo(mcode)
                .andMOrderNumberEqualTo(mOrderNumber);
        val payOrders = payOrderMapper.selectByExample(example);
        return payOrders;
    }


    /**
     * 订单信息查询方法
     * @return
     */
    public PayOrder queryPayOrder(String mcode,String mOrderNumber,String payType){
        val example = new PayOrderExample();
        example.createCriteria()
                .andMcodeEqualTo(mcode)
                .andMOrderNumberEqualTo(mOrderNumber)
                .andPayTypeEqualTo(payType);
        val payOrders = payOrderMapper.selectByExample(example);
        return payOrders.size()>0?payOrders.get(0):null;
    }


    /**
     * 订单信息查询方法
     * @return
     */
    public PayOrder queryPayOrderByNumber(String mOrderNumber,String payType){
        val example = new PayOrderExample();
        example.createCriteria()
                .andMOrderNumberEqualTo(mOrderNumber)
                .andPayTypeEqualTo(payType);
        val payOrders = payOrderMapper.selectByExample(example);
        return payOrders.size()>0?payOrders.get(0):null;
    }

    /**
     * 订单信息查询方法
     * @return
     */
    public PayOrder queryPayOrderByTimeExpire(String mOrderNumber,String timeExpire,String payType){
        val example = new PayOrderExample();
        example.createCriteria()
                .andMOrderNumberEqualTo(mOrderNumber)
                .andTimeExpireEqualTo(timeExpire)
                .andPayTypeEqualTo(payType);
        val payOrders = payOrderMapper.selectByExample(example);
        return payOrders.size()>0?payOrders.get(0):null;
    }

    /**
     * 支付平台订单关闭方法
     * @param mcode 商户号
     * @param mOrderNumber 业务系统订单号
     * @param payType 更新订单支付方式
     * @return
     */
    public Boolean cancelPayOrder(String mcode,String mOrderNumber,String payType){
        val payOrder = new PayOrder();
        payOrder.setUpdatedAt(new Date());
        if(!StringUtils.isEmpty(RequestHeaderUtil.getUsername())){
            payOrder.setUpdatedBy(RequestHeaderUtil.getUsername());
        }
		payOrder.setPayStatus(DictionaryConstant.PAY_STATUS_YQX.getCode());
        val payOrderExample = new PayOrderExample();
        payOrderExample.createCriteria()
                .andMcodeEqualTo(mcode)
                .andPayTypeEqualTo(payType)
                .andMOrderNumberEqualTo(mOrderNumber);
        int count = payOrderMapper.updateByExampleSelective(payOrder,payOrderExample);
        return count > 0 ? true:false;
    }

    public PayOrder getPayOrder(String tradeId) {
        val example = new PayOrderExample();
        example.createCriteria()
                .andTradeIdEqualTo(tradeId);
        val payOrders = payOrderMapper.selectByExample(example);
        return payOrders.size() > 0 ? payOrders.get(0) : null;
    }

    public List<PayOrder> queryPayOrderByOrderNumber(String orderNumber) {
        val example = new PayOrderExample();
        example.createCriteria()
                .andMOrderNumberEqualTo(orderNumber)
                .andPayStatusNotEqualTo(DictionaryConstant.PAY_STATUS_YQX.getCode());
        val payOrders = payOrderMapper.selectByExample(example);
        return payOrders.size() > 0 ? payOrders : null;
    }

    public PayOrder queryPayOrderByTradeId(String tradeId) {
        val example = new PayOrderExample();
        example.createCriteria()
                .andTradeIdEqualTo(tradeId);
        val payOrders = payOrderMapper.selectByExample(example);
        return payOrders.size() >= 1 ? payOrders.get(0) : null;
    }

    /**
     * 第三方支付平台支付渠道添加方法
     * @param tradeMchPayChannel：订单信息
     * @param tradeSettlementInfo：商户聚合支付平台商户号信息
     * @param tradePayTypeDict：系统支付信息
     * @return
     */
    public Boolean savePayChannel(TradeMchPayChannel tradeMchPayChannel, TradeSettlementInfo tradeSettlementInfo, PayTypeDict tradePayTypeDict){
        val savePayChannelRequest = new PostSavePayChannelRequest();
        savePayChannelRequest.setMcode(tradeSettlementInfo.getMcode());
        savePayChannelRequest.setAppid(tradeMchPayChannel.getAppid());
        savePayChannelRequest.setMchId(tradeMchPayChannel.getMchId());
        savePayChannelRequest.setSubAppid(tradeMchPayChannel.getSubAppid());
        savePayChannelRequest.setSubMchId(tradeMchPayChannel.getSubMchId());
        savePayChannelRequest.setPayType(tradePayTypeDict.getPayPlatformType());
        savePayChannelRequest.setNotifyUrl(tradePayTypeDict.getNotifyUrl());
        savePayChannelRequest.setSecretKey(tradeMchPayChannel.getSecretKey());
        savePayChannelRequest.setAppSecretKey(tradeMchPayChannel.getAppSecretKey());
        savePayChannelRequest.setPrivateKey(tradeMchPayChannel.getPrivateKey());
        savePayChannelRequest.setPublicKey(tradeMchPayChannel.getPublicKey());
        savePayChannelRequest.setRefundNotifyUrl(tradePayTypeDict.getRefundNotifyUrl());
        savePayChannelRequest.setCert(tradeMchPayChannel.getCert());

        val resultData = HttpClientUtils.postData(tradePayTypeDict.getPayPlatformDomainUrl() + TradeConstant.PAYMENT_PAY_APPLY_PAY_CHANNEL, JSON.toJSONString(savePayChannelRequest));
        Map resultMap = (Map)JSON.parse(resultData);
        if(("200").equals(resultMap.get("code"))){
            Map dataMap = (Map)resultMap.get("result");
            return (Boolean) dataMap.get("result");
        }else{
            logger.error(" Save Pay Channel error:" + resultData);
        }
        return false;
    }

    /**
     * 第三方支付平台支付渠道添加方法
     * @param tradeMchPayChannel：订单信息
     * @param tradeSettlementInfo：商户聚合支付平台商户号信息
     * @param tradePayTypeDict：系统支付信息
     * @return
     */
    public Boolean updatePayChannel(TradeMchPayChannel tradeMchPayChannel,TradeSettlementInfo tradeSettlementInfo, PayTypeDict tradePayTypeDict){
        val payChannelRequest = new PutUpdatePayChannelRequest();
        payChannelRequest.setMcode(tradeSettlementInfo.getMcode());
        payChannelRequest.setAppid(tradeMchPayChannel.getAppid());
        payChannelRequest.setMchId(tradeMchPayChannel.getMchId());
        payChannelRequest.setSubAppid(tradeMchPayChannel.getSubAppid());
        payChannelRequest.setSubMchId(tradeMchPayChannel.getSubMchId());
        payChannelRequest.setPayType(tradePayTypeDict.getPayPlatformType());
        payChannelRequest.setNotifyUrl(tradePayTypeDict.getNotifyUrl());
        payChannelRequest.setSecretKey(tradeMchPayChannel.getSecretKey());
        payChannelRequest.setAppSecretKey(tradeMchPayChannel.getAppSecretKey());
        payChannelRequest.setPrivateKey(tradeMchPayChannel.getPrivateKey());
        payChannelRequest.setPublicKey(tradeMchPayChannel.getPublicKey());
        payChannelRequest.setRefundNotifyUrl(tradePayTypeDict.getRefundNotifyUrl());
        payChannelRequest.setCert(tradeMchPayChannel.getCert());

        val resultData = HttpClientUtils.putData(tradePayTypeDict.getPayPlatformDomainUrl() + TradeConstant.PAYMENT_PAY_UPDATE_PAY_CHANNEL, JSON.toJSONString(payChannelRequest));
        Map resultMap = (Map)JSON.parse(resultData);
        if(("200").equals(resultMap.get("code"))){
            Map dataMap = (Map)resultMap.get("result");
            return (Boolean) dataMap.get("result");
        }else{
            logger.error(" Save Pay Channel error:" + resultData);
        }
        return false;
    }

    /**
     * 第三方支付平台支付渠道删除方法
     * @param tradeSettlementInfo：商户聚合支付平台商户号信息
     * @param tradePayTypeDict：系统支付信息
     * @return
     */
    public Boolean deletePayChannel(TradeSettlementInfo tradeSettlementInfo, PayTypeDict tradePayTypeDict){
        val payChannelRequest = new DeleteDeletePayChannelRequest();
        payChannelRequest.setMcode(tradeSettlementInfo.getMcode());
        payChannelRequest.setPayType(tradePayTypeDict.getPayPlatformType());

        val resultData = HttpClientUtils.deleteData(tradePayTypeDict.getPayPlatformDomainUrl() + TradeConstant.PAYMENT_PAY_DELETE_PAY_CHANNEL, MapBeanUtils.beanToMap(payChannelRequest));
        Map resultMap = (Map)JSON.parse(resultData);
        if(("200").equals(resultMap.get("code"))){
            Map dataMap = (Map)resultMap.get("result");
            return (Boolean) dataMap.get("result");
        }else{
            logger.error(" Save Pay Channel error:" + resultData);
        }
        return false;
    }

    /**
     * 第三方支付平台商户申请方法
     * @param mchName：商户名称
     * @return
     */
    public PostPayApplyMchInfoResponse applyMch(String mchName, PayTypeDict tradePayTypeDict){
        Map<String,String> params = new HashMap<>();
        params.put("mchName",mchName);
        val resultData = HttpClientUtils.postData(tradePayTypeDict.getPayPlatformDomainUrl() + TradeConstant.PAYMENT_MCH_APPLY_MCH, JSON.toJSONString(params));
        Map resultMap = (Map)JSON.parse(resultData);
        if(("200").equals(resultMap.get("code"))){
            Map dataMap = (Map)resultMap.get("result");
            return MapBeanUtils.mapToBean(dataMap,PostPayApplyMchInfoResponse.class);
        }else{
            logger.error(" Apply Mch Error:" + resultData);
        }
        return null;
    }

    public PayOrder getPayOrderByOuterOrderNumber(String transNo) {
        val example = new PayOrderExample();
        example.createCriteria()
                .andOuterOrderNumberEqualTo(transNo);
        val payOrders = payOrderMapper.selectByExample(example);
        return payOrders.size() >= 1 ? payOrders.get(0) : null;
    }
}
