package com.ywt.service.common;


import com.ywt.core.BaseResponse;
import com.ywt.gapi.ordercenter.*;
import com.ywt.params.mg.order.CreateOrderResponse;
import com.ywt.service.ServiceResult;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;


@Service
public class OrderCenterService {

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

    @DubboReference
    private com.ywt.gapi.ordercenter.OrderCenterService orderCenterServiceBlockingStub;

    public ServiceResult wechatPayment(String body, String spbillCreateIp, String openid, int amount,
                                       int terminal, int orderId, int userId) {
        ServiceResult result = new ServiceResult();
        try {
            WechatPaymentRequest request = WechatPaymentRequest.newBuilder()
                    .setBody(body)
                    .setSpbillCreateIp(spbillCreateIp)
                    .setOpenid(openid)
                    .setAmount(amount)
                    .setTerminal(terminal)
                    .setOrderId(orderId)
                    .setUserId(userId)
                    .build();
            WechatPaymentResponse response = orderCenterServiceBlockingStub.wechatPayment(request);
            if (response.getCode() == BaseResponse.SUCCEED) {
                Map<String, Object> map = new HashMap<>();
                map.put("timeStamp", response.getTimeStamp());
                map.put("nonceStr", response.getNonceStr());
                map.put("package", response.getPackage());
                map.put("signType", response.getSignType());
                map.put("paySign", response.getPaySign());
                map.put("appId", response.getAppId());
                result.setData(map);
                return result.succeed("操作成功");
            }
            return result.failed(response.getInfo());
        } catch (Exception e) {
            logger.error("OrderCenterService#wechatPayment(): {}", e.getMessage(), e);
            return result.error(e.getMessage());
        }
    }

    /**
     * 创建订单
     *
     * @param orderType              订单类型
     * @param bizId                  业务订单表ID
     * @param paymentCallbackMethod  grpc的支付回调方法 /com.ywt.gapi.consult.ConsultingService/payConsultingCallback
     * @param paymentCallbackRestUrl rest的支付回调方法 rest://com.ywt.GlassesApiService/mg/order/paymentCallback
     * @param payCode                payCode
     * @param totalPrice             支付金额，单位：分
     * @param payBody                支付标记
     * @return {@link CreateOrderResponse}
     */
    public com.ywt.gapi.ordercenter.CreateOrderResponse createOrder(int orderType, int bizId, String paymentCallbackMethod, String paymentCallbackRestUrl,
                                           String payCode, int totalPrice, String payBody) {
        try {
            com.ywt.gapi.ordercenter.CreateOrderRequest createOrderRequest = CreateOrderRequest.newBuilder()
                    .setOrderType(orderType)
                    .setBizId(bizId)
                    .setPaymentCallbackMethod(paymentCallbackMethod)
                    .setRefundNotifyRestUrl(paymentCallbackRestUrl)
                    .setPayCode(payCode)
                    .setAmount(totalPrice)
                    .setPayBody(payBody)
                    .build();
            return orderCenterServiceBlockingStub.createOrder(createOrderRequest);
        } catch (Exception e) {
            logger.error("OrderCenterService#createOrder(): {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 通过管理员支付
     *
     * @param amount         订单金额，单位：分
     * @param byUserName     收钱人
     * @param paymentChannel 支付渠道，参考{@link com.ywt.mg.domain.models.enums.PaymentChannelEnum}
     * @param orderId        订单ID
     * @param custom         自定义参数
     * @return {@link PayByAdminResponse}
     */
    public PayByAdminResponse payByAdmin(int amount, String byUserName, int paymentChannel, int orderId, String custom) {
        try {
            PayByAdminRequest request = PayByAdminRequest.newBuilder()
                    .setAmount(amount)
                    .setByUserName(byUserName)
                    .setPaymentChannel(paymentChannel)
                    .setOrderId(orderId)
                    .setSpbillCreateIp(InetAddress.getLocalHost().getHostAddress())
                    .setCustom(custom)
                    .build();
            return orderCenterServiceBlockingStub.payByAdmin(request);
        } catch (Exception e) {
            logger.error("OrderCenterService#payByAdmin:{}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 退款
     *
     * @param orderId             订单ID
     * @param orderNo             订单编号
     * @param adminAccount        操作人
     * @param customMapJson       自定义参数
     * @param refundNotifyMethod  grpc退款回调地址 /com.ywt.gapi.consult.ConsultingService/refundConsultingCallback
     * @param refundNotifyRestUrl rest退款回调地址 rest://com.ywt.GlassesApiService/mg/order/refundCallback
     * @return {@link RefundResponse}
     */
    public RefundResponse refund(int orderId, String orderNo, String adminAccount, String customMapJson,
                                 String refundNotifyMethod, String refundNotifyRestUrl) {
        try {
            RefundRequest refundRequest = RefundRequest.newBuilder()
                    .setOrderId(orderId)
                    .setOrderNo(orderNo)
                    .setAmount(0)
                    .setOpBy(adminAccount)
                    .setRefundType(1)
                    .setCustom(customMapJson)
                    .setRefundNotifyMethod(refundNotifyMethod)
                    .setRefundNotifyRestUrl(refundNotifyRestUrl)
                    .build();
            return orderCenterServiceBlockingStub.refund(refundRequest);
        } catch (Exception e) {
            logger.error("OrderCenterService#refund(): {}", e.getMessage(), e);
            return null;
        }
    }


}
