package com.neusoft.smart.pos.fumao.persistent.repository;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotNull;
import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.dto.payment.response.*;
import com.neusoft.smart.pos.dto.trade.request.PostPayOrderRequest;
import com.neusoft.smart.pos.dto.trade.request.PostRefundRequest;
import com.neusoft.smart.pos.dto.trade.request.PostTradeOrderRequest;
import com.neusoft.smart.pos.dto.trade.response.PostOrderResponse;
import com.neusoft.smart.pos.dto.trade.response.PostPayOrderResponse;
import com.neusoft.smart.pos.dto.trade.response.PostRefundResponse;
import com.neusoft.smart.pos.fumao.constants.FumaoConstants;
import com.neusoft.smart.pos.fumao.constants.FumaoErrorCode;
import com.neusoft.smart.pos.fumao.utils.AmountUtils;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.neusoft.smart.pos.dto.fumao.request.PostFumaoTradeOrderRequest;
import com.neusoft.smart.pos.dto.payment.request.FumaoPayRequest;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.fumao.persistent.domain.FumaoTenantInfo;
import com.neusoft.smart.pos.fumao.persistent.domain.FumaoTenantInfoExample;
import com.neusoft.smart.pos.fumao.persistent.ext.domain.FumaoMerchantQueryRequest;
import com.neusoft.smart.pos.fumao.persistent.mapper.FumaoPayChannelMapper;
import com.neusoft.smart.pos.fumao.utils.HttpClientUtils;

import lombok.val;

@Component
public class FumaoBusinessActionRepository {
	private final static Logger logger = LoggerFactory.getLogger(FumaoBusinessActionRepository.class);
	//会员查询
	
	//试算
	
	//支付核销
	
	//支付完成状态同步
	
	//退款

	@Autowired
    private FumaoPayChannelMapper fumaoPayChannelMapper;

	//试算
	public FumaoMemberInfoRes   queryAndCalc(PostFumaoTradeOrderRequest postFumaoTradeOrderRequest){
		val fumaoPayRequest = new FumaoPayRequest();
		fumaoPayRequest.setDeviceSN(postFumaoTradeOrderRequest.getNeuInfo().getSn());
		fumaoPayRequest.setMemPhone(postFumaoTradeOrderRequest.getThirdPartyInfo().getMemberPhoneNumber());
		fumaoPayRequest.setOrderNumber(postFumaoTradeOrderRequest.getParameterforNextStep().getOrderNumber());
		fumaoPayRequest.setOrderAmount(AmountUtils.changeY2F(postFumaoTradeOrderRequest.getParameterforNextStep().getTotalAmount()));
        if(postFumaoTradeOrderRequest.getParameterforNextStep().getPaymentPredictionofTotal() != null
                && postFumaoTradeOrderRequest.getParameterforNextStep().getPaymentPredictionofTotal().getOrder_amount_left() != null) {
            fumaoPayRequest.setOrderAmountLeft(AmountUtils.changeY2F(postFumaoTradeOrderRequest.getParameterforNextStep().getPaymentPredictionofTotal().getAmount_left_after_pay()));
        } else {
            fumaoPayRequest.setOrderAmountLeft(AmountUtils.changeY2F(postFumaoTradeOrderRequest.getParameterforNextStep().getTotalAmount()));
        }
		fumaoPayRequest.setMerchantId(postFumaoTradeOrderRequest.getThirdPartyInfo().getMerchantID());
        fumaoPayRequest.setTenantId(postFumaoTradeOrderRequest.getThirdPartyInfo().getTenantID());
        fumaoPayRequest.setOrderOperatorId(postFumaoTradeOrderRequest.getThirdPartyInfo().getOperatorID());
        if(postFumaoTradeOrderRequest.getThirdPartyInfo().getBusinessType() != null) {
            fumaoPayRequest.setBusinessType(postFumaoTradeOrderRequest.getThirdPartyInfo().getBusinessType());
        } else {
            fumaoPayRequest.setBusinessType("1");
        }
        List<String> couponList = new ArrayList<>();
        if(postFumaoTradeOrderRequest.getParameterforNextStep().getPaymentTypeList() != null
                && postFumaoTradeOrderRequest.getParameterforNextStep().getPaymentTypeList().size() > 0) {
            for(int i = 0; i < postFumaoTradeOrderRequest.getParameterforNextStep().getPaymentTypeList().size(); i++) {
                FumaoPaymentType paymentType = postFumaoTradeOrderRequest.getParameterforNextStep().getPaymentTypeList().get(i);
                if(paymentType.getPaymentTypeId().equals(DictionaryConstant.PAY_TYPE_DISCOUNT.getCode())) {
                    for(int j = 0; j < paymentType.getPaymentData().size(); j++) {
                        FumaoPaymentData paymentData = paymentType.getPaymentData().get(j);
                        if(paymentData.getIsSelected().equals("1") && paymentData.getCuponID() != null) {
                            couponList.add(paymentData.getCuponID());
                        }
                    }
                    break;
                }
            }
        }
        fumaoPayRequest.setCouponOrderIdList(couponList);

		val resultData = HttpClientUtils.postData("http://localhost:2018/fumaoPay/" + "queryAndCalc", JSON.toJSONString(fumaoPayRequest));//TODO
		logger.info("queryAndCalc response:" + resultData);
		Map resultMap = (Map)JSON.parse(resultData);

		FumaoMemberInfoRes result;

		if(("200").equals(resultMap.get("code").toString())){
			JSONObject jsonObject  = JSONObject.fromObject(resultMap.get("result"));
			result = (FumaoMemberInfoRes) JSONObject.toBean(jsonObject, FumaoMemberInfoRes.class);
		}else{
			logger.error( "queryAndCalc error:" + resultData);
//            result.setReturn_code(resultMap.get("code").toString());
//            result.setReturn_msg(resultMap.get("message").toString());
			throw new BusinessCommonException(resultMap.get("code").toString(),resultMap.get("message").toString());
		}
		return result;
	}
	
	public List<FumaoTenantInfo> getList(FumaoMerchantQueryRequest req) {
		FumaoTenantInfoExample fumaoTenantInfoExample = this.FumaoTenantInfoExampleProvider(req);
        return fumaoPayChannelMapper.selectByExample(fumaoTenantInfoExample);
    }
	
	private FumaoTenantInfoExample FumaoTenantInfoExampleProvider(@NotNull FumaoMerchantQueryRequest req) {
		FumaoTenantInfoExample fumaoExample = new FumaoTenantInfoExample();
		FumaoTenantInfoExample.Criteria criteria = fumaoExample.createCriteria();
		if (null != req.getShop_id()) {
            criteria.andShopIdEqualTo(req.getShop_id());
        }
        return fumaoExample;
    }

    //支付核销
	public FumaoParameterforNextStep consume(PostFumaoTradeOrderRequest postFumaoTradeOrderRequest) {
		FumaoParameterforNextStep parameterforNextStepBean = postFumaoTradeOrderRequest.getParameterforNextStep();
		String orderNumber = parameterforNextStepBean.getOrderNumber();

		// 生成订单
		if(null == orderNumber) {
			PostTradeOrderRequest postTradeOrderRequest = new PostTradeOrderRequest();
			postTradeOrderRequest.setSerialNo(postFumaoTradeOrderRequest.getNeuInfo().getSn());
			postTradeOrderRequest.setOrderAmount(new BigDecimal(parameterforNextStepBean.getTotalAmount()));
            List<FumaoPaymentType> paymentTypeList = postFumaoTradeOrderRequest.getParameterforNextStep().getPaymentTypeList();
            if(paymentTypeList != null) {
                if(paymentTypeList.size() > 1) {
                    postTradeOrderRequest.setPayType(DictionaryConstant.PAY_TYPE_MULTY_COMBINED.getCode()); // 组合支付
                } else {
                    postTradeOrderRequest.setPayType(paymentTypeList.get(0).getPaymentTypeId());
                }
            } else {
                throw new BusinessCommonException(FumaoErrorCode.PAY_TYPE_EMPTY);
            }
			val resultData = HttpClientUtils.postData("http://localhost:2008/order/" + "order", JSON.toJSONString(postTradeOrderRequest));//TODO
            logger.info("orderResultData:"+resultData);
            Map resultMap = (Map)JSON.parse(resultData);
            PostOrderResponse orderResponse;
            if(("200").equals(resultMap.get("code").toString())){
                JSONObject jsonObject  = JSONObject.fromObject(resultMap.get("result"));
                orderResponse = (PostOrderResponse) JSONObject.toBean(jsonObject, PostOrderResponse.class);
            }else{
                logger.error( "postOrder error:" + resultData);
                throw new BusinessCommonException(resultMap.get("code").toString(),resultMap.get("message").toString());
            }
            orderNumber = orderResponse.getOrderNumber();
            parameterforNextStepBean.setOrderNumber(orderNumber);
            logger.info("orderNum:"+parameterforNextStepBean.getOrderNumber());
		}

		// 生成预付单
		List<FumaoPaymentType> paymentTypeList = parameterforNextStepBean.getPaymentTypeList();
		Long totalPayAmount = 0L;
        for (int i = 0; i < paymentTypeList.size(); i++) {
            PostPayOrderRequest postPayOrderRequest = new PostPayOrderRequest();
            postPayOrderRequest.setSerialNo(postFumaoTradeOrderRequest.getNeuInfo().getSn());
            postPayOrderRequest.setOrderNumber(orderNumber);
            postPayOrderRequest.setPayType(paymentTypeList.get(i).getPaymentTypeId());
            List<FumaoPaymentData> paymentDataList = paymentTypeList.get(i).getPaymentData();
            if (paymentDataList != null && paymentDataList.size() > 0) {
                postPayOrderRequest.setScanCode(paymentDataList.get(0).getScanCode());
            }
            FumaoPaymentPrediction paymentPredictionbyType = paymentTypeList.get(i).getPaymentPredictionbyType();
            if (paymentPredictionbyType != null && paymentPredictionbyType.getPromotion_amount() != null) { // 若请求中没有支付金额，参数不填
                postPayOrderRequest.setPayAmount(AmountUtils.changeF2YDouble(paymentPredictionbyType.getPromotion_amount()));//单位:元
            }
            JSONObject payInfoJsonObject = new JSONObject();
            if(paymentTypeList.get(i).getPaymentTypeId().equals(DictionaryConstant.PAY_TYPE_DISCOUNT.getCode())
                    || paymentTypeList.get(i).getPaymentTypeId().equals(DictionaryConstant.PAY_TYPE_FM_COUPON.getCode())) {
                payInfoJsonObject.put("merchant_id",postFumaoTradeOrderRequest.getThirdPartyInfo().getMerchantID());
                payInfoJsonObject.put("tenant_id",postFumaoTradeOrderRequest.getThirdPartyInfo().getTenantID());
                payInfoJsonObject.put("order_amount",AmountUtils.changeY2F(parameterforNextStepBean.getTotalAmount()));// 单位：分
                payInfoJsonObject.put("order_operator_id", postFumaoTradeOrderRequest.getThirdPartyInfo().getOperatorID());
                String memPhoneNum = postFumaoTradeOrderRequest.getThirdPartyInfo().getMemberPhoneNumber()==null ? "" : postFumaoTradeOrderRequest.getThirdPartyInfo().getMemberPhoneNumber();
                payInfoJsonObject.put("mem_phone_number", memPhoneNum);
                String memId = postFumaoTradeOrderRequest.getThirdPartyInfo().getMemberID()==null ? "" : postFumaoTradeOrderRequest.getThirdPartyInfo().getMemberID();
                payInfoJsonObject.put("mem_id", memId);
                if (postFumaoTradeOrderRequest.getThirdPartyInfo().getBusinessType() != null) {
                    payInfoJsonObject.put("business_type", postFumaoTradeOrderRequest.getThirdPartyInfo().getBusinessType());
                } else {
                    payInfoJsonObject.put("business_type", "1");
                }
                List<String> couponList = new ArrayList<>();
                if (paymentTypeList.get(i).getPaymentTypeId().equals(DictionaryConstant.PAY_TYPE_DISCOUNT.getCode())) { // 优惠券参数
                    for (int j = 0; j < paymentTypeList.get(i).getPaymentData().size(); j++) {
                        FumaoPaymentData paymentData = paymentTypeList.get(i).getPaymentData().get(j);
                        if (paymentData.getIsSelected().equals("1") && paymentData.getCuponID() != null) {
                            couponList.add(paymentData.getCuponID());
                        }
                    }
                    payInfoJsonObject.put("coupon_list",couponList);
                } else { // 消费卡参数
                    List<FumaoPaymentData> paymentDataListC = paymentTypeList.get(i).getPaymentData();
                    if(paymentDataListC == null || paymentDataListC.size() < 1 || paymentDataListC.get(0).getScanCode() == null) {
                        throw new BusinessCommonException(FumaoErrorCode.CARD_PAY_CARD_ID_EMPTY);
                    }
                    payInfoJsonObject.put("card_id",paymentDataListC.get(0).getScanCode());
                }
            }
            postPayOrderRequest.setPayInfoJsonString(payInfoJsonObject.toString());

            val payResultData = HttpClientUtils.postData("http://localhost:2008/order/" + "payOrder", JSON.toJSONString(postPayOrderRequest));//TODO
            logger.info("payResultData:" + payResultData);
            Map resultMap = (Map) JSON.parse(payResultData);
            PostPayOrderResponse postPayOrderResponse;
            if (("200").equals(resultMap.get("code").toString())) {
                JSONObject jsonObject = JSONObject.fromObject(resultMap.get("result"));
                postPayOrderResponse = (PostPayOrderResponse) JSONObject.toBean(jsonObject, PostPayOrderResponse.class);
            } else {
                logger.error("postPayOrder error:" + payResultData);
                throw new BusinessCommonException(resultMap.get("code").toString(), resultMap.get("message").toString());
            }
            logger.info("PayCode:" + postPayOrderResponse.getPayCode());
            logger.info("orderNumber" + postPayOrderResponse.getOrderNumber());
            logger.info("PayStatus" + postPayOrderResponse.getPayStatus());
            logger.info("OrderAmount" + postPayOrderResponse.getOrderAmount());
            logger.info("RealPayAmount" + postPayOrderResponse.getRealPayAmount());
            logger.info("PaidTime" + postPayOrderResponse.getPaidTime());
            // .....赋值
            parameterforNextStepBean.getPaymentTypeList().get(i).setPaymentStatus(postPayOrderResponse.getPayStatus());
            parameterforNextStepBean.getPaymentTypeList().get(i).setTradeId(postPayOrderResponse.getTradeId());
            totalPayAmount += postPayOrderResponse.getOrderAmount().longValue();
        }
        FumaoPaymentPrediction predictionTotal = new FumaoPaymentPrediction();
        predictionTotal.setOrder_amount(Long.parseLong(AmountUtils.changeY2F(parameterforNextStepBean.getTotalAmount())));
        predictionTotal.setOrder_amount_left(parameterforNextStepBean.getPaymentTypeList().get(0).getPaymentPredictionbyType().getOrder_amount_left());
        predictionTotal.setPromotion_amount(totalPayAmount);//TODO 填支付成功的金额，还是该请求所带的所有金额？？
        long leftAmount = parameterforNextStepBean.getPaymentTypeList().get(0).getPaymentPredictionbyType().getOrder_amount_left() - totalPayAmount;
        predictionTotal.setAmount_left_after_pay(leftAmount);
        if(leftAmount == 0) {
            parameterforNextStepBean.setNextStep(FumaoConstants.STEP_NAME_NEXT);
        } else {
            parameterforNextStepBean.setNextStep(FumaoConstants.STEP_NAME_KEEP);
        }
		return parameterforNextStepBean;
	}

    //支付完成
    public FumaoParameterforNextStep paySuccess(PostFumaoTradeOrderRequest postFumaoTradeOrderRequest) {
        FumaoParameterforNextStep parameterforNextStepBean = postFumaoTradeOrderRequest.getParameterforNextStep();
        String orderNumber = parameterforNextStepBean.getOrderNumber();
        // TODO
        return parameterforNextStepBean;
    }

    //支付状态查询
    public FumaoParameterforNextStep queryPayStatus(PostFumaoTradeOrderRequest postFumaoTradeOrderRequest) {
        FumaoParameterforNextStep parameterforNextStepBean = postFumaoTradeOrderRequest.getParameterforNextStep();
        String orderNumber = parameterforNextStepBean.getOrderNumber();
        // TODO
        return parameterforNextStepBean;
    }

    //退款
    public FumaoParameterforNextStep refund(PostFumaoTradeOrderRequest postFumaoTradeOrderRequest) {
        FumaoParameterforNextStep parameterforNextStepBean = postFumaoTradeOrderRequest.getParameterforNextStep();

        PostRefundRequest postRefundRequest = new PostRefundRequest();
        postRefundRequest.setOrderNumber(parameterforNextStepBean.getOrderNumber());
        postRefundRequest.setSerialNo(postFumaoTradeOrderRequest.getNeuInfo().getSn());
        JSONObject payInfoJsonObject = new JSONObject();
        payInfoJsonObject.put("merchant_id",postFumaoTradeOrderRequest.getThirdPartyInfo().getMerchantID());
        payInfoJsonObject.put("tenant_id",postFumaoTradeOrderRequest.getThirdPartyInfo().getTenantID());
//        payInfoJsonObject.put("order_amount",AmountUtils.changeY2F(parameterforNextStepBean.getTotalAmount()));// 单位：分
        payInfoJsonObject.put("order_operator_id", postFumaoTradeOrderRequest.getThirdPartyInfo().getOperatorID());
        String memPhoneNum = postFumaoTradeOrderRequest.getThirdPartyInfo().getMemberPhoneNumber()==null ? "" : postFumaoTradeOrderRequest.getThirdPartyInfo().getMemberPhoneNumber();
        payInfoJsonObject.put("mem_phone_number", memPhoneNum);
        String memId = postFumaoTradeOrderRequest.getThirdPartyInfo().getMemberID()==null ? "" : postFumaoTradeOrderRequest.getThirdPartyInfo().getMemberID();
        payInfoJsonObject.put("mem_id", memId);
        if (postFumaoTradeOrderRequest.getThirdPartyInfo().getBusinessType() != null) {
            payInfoJsonObject.put("business_type", postFumaoTradeOrderRequest.getThirdPartyInfo().getBusinessType());
        } else {
            payInfoJsonObject.put("business_type", "1");
        }
        if (parameterforNextStepBean.getPaymentTypeList().get(0).getPaymentTypeId().equals(DictionaryConstant.PAY_TYPE_FM_COUPON.getCode())) { // 优惠券参数
            payInfoJsonObject.put("coupon_id", parameterforNextStepBean.getPaymentTypeList().get(0).getPaymentData().get(0).getCuponID()); //TODO for循环遍历PaymentData？？
        }
        postRefundRequest.setThirdPartyInfoJsonString(payInfoJsonObject.toString());
        val resultData = HttpClientUtils.postData("http://localhost:2008/orderRefund/" + "refund", JSON.toJSONString(postRefundRequest)); //TODO
        logger.info("orderRefundResultData:"+resultData);
        Map resultMap = (Map)JSON.parse(resultData);
        PostRefundResponse orderRefundResponse;
        if(("200").equals(resultMap.get("code").toString())){
            JSONObject jsonObject  = JSONObject.fromObject(resultMap.get("result"));
            orderRefundResponse = (PostRefundResponse) JSONObject.toBean(jsonObject, PostRefundResponse.class);
        }else{
            logger.error( "postOrderRefund error:" + resultData);
            throw new BusinessCommonException(resultMap.get("code").toString(),resultMap.get("message").toString());
        }
        // TODO 返回值??
        return parameterforNextStepBean;
    }

    //订单同步
    public FumaoParameterforNextStep complete(PostFumaoTradeOrderRequest postFumaoTradeOrderRequest) {
        FumaoParameterforNextStep parameterforNextStepBean = postFumaoTradeOrderRequest.getParameterforNextStep();
        // TODO
        return parameterforNextStepBean;
    }


//    /**
//     * 富茂POS订单同步数据整理方法
//     * @param payOrder 订单同步请求
//     * @return String
//     */
//    private String fumaoCouponOrderRequestDataHandle(PayOrder payOrder){
//        Map<String, String> reqObj = new HashMap<>();
//        reqObj.put("dev_id", FumaoPayConstants.BUSINESS_ID);
//        reqObj.put("nonce_str", WXPayUtils.generateNonceStr());//"123456789");
//        String payInfoString = payOrder.getPayInfoJsonString();
//        logger.info("fumaoCouponOrderRequestDataHandle::payInfoString="+payInfoString);
//        JSONObject payInfoJsonObject  = JSONObject.fromObject(payInfoString);
//        try {
//            reqObj.put("merchant_id", payInfoJsonObject.getString("merchant_id"));
//            reqObj.put("tenant_id", payInfoJsonObject.getString("tenant_id"));
//            reqObj.put("order_amount", payInfoJsonObject.getString("order_amount"));
//            reqObj.put("order_operation_id", payInfoJsonObject.getString("order_operator_id"));
//            if(!payInfoJsonObject.getString("mem_phone_number").equals("")) {
//                reqObj.put("mem_phone_number", payInfoJsonObject.getString("mem_phone_number"));
//            }
//            if(!payInfoJsonObject.getString("mem_id").equals("")) {
//                reqObj.put("mem_id", payInfoJsonObject.getString("mem_id"));
//            }
//            reqObj.put("business_type", payInfoJsonObject.getString("business_type"));
//            List<String> couponList = (List<String>)payInfoJsonObject.get("coupon_list");
//            if(couponList != null) {
//                reqObj.put("coupon_list", "[".concat(String.join(",", couponList)).concat("]"));
//            } else {
//                reqObj.put("coupon_list", "[]");
//            }
//        } catch (Exception e) {
//            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_INFO_NOT_EMPTY);
//        }
//        reqObj.put("order_amount_left", payOrder.getLeftAmount().toString());
//        reqObj.put("order_number_of_platform", payOrder.getmOrderNumber());
//        reqObj.put("order_create_sn", payOrder.getDeviceId());
//        reqObj.put("sign", WXPayUtils.generateSignature(reqObj, FumaoPayConstants.DEV_REQ_KEY, SignType.HMACSHA256));
//        JSONObject jsonObject = JSONObject.fromObject(reqObj);
//        return jsonObject.toString();
//    }
}
