package com.izouma.jiashanxia.service;

import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.izouma.jiashanxia.domain.OrderInfo;
import com.izouma.jiashanxia.domain.User;
import com.izouma.jiashanxia.domain.WxFee;
import com.izouma.jiashanxia.exception.BusinessException;
import com.izouma.jiashanxia.repo.OrderInfoRepo;
import com.izouma.jiashanxia.repo.UserRepo;
import com.izouma.jiashanxia.repo.WxFeeRepo;
import com.izouma.jiashanxia.utils.JsonUtils;
import com.izouma.jiashanxia.utils.SnowflakeIdWorker;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Arrays;

@Service
@Slf4j
@AllArgsConstructor
public class ConsumptionService {
    private UserRepo         userRepo;
    private OrderInfoRepo    orderInfoRepo;
    private Environment      environment;
    private WxPayService     wxPayService;
    private WxFeeRepo        wxFeeRepo;
    private OrderInfoService orderInfoService;

    /*
    微信支付
     */
    public WxPayMpOrderResult payOrder(Long userId, Long orderId) {
        User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
        OrderInfo orders = orderInfoRepo.findById(orderId).orElseThrow(new BusinessException("订单错误"));

        String body = orders.getName();
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
        request.setBody(body);
        //订单号
        request.setOutTradeNo(String.valueOf(new SnowflakeIdWorker(1, 1).nextId()));
        //分为单位
        request.setTotalFee(orders.getPrice().multiply(BigDecimal.valueOf(100)).intValue());
        if (Arrays.stream(environment.getActiveProfiles()).noneMatch(s -> s.equals("prod"))) {
            request.setTotalFee(1);
        }
        if ("oTSu45NiG1dbKC2uYZxZtcd8rjAM".equals(user.getOpenId())
                || "oTSu45GxPRhNkElSROy5W8-eNZgQ".equals(user.getOpenId())
                || "oTSu45Gk2g6Er5YJGkpWOw9yBPWA".equals(user.getOpenId())
                || "oTSu45AGWhJV2L60m0fdeiOXnFsU".equals(user.getOpenId())
                || "oTSu45GvrgMmleC7r9Nh1tv7M-AE".equals(user.getOpenId())) {
            request.setTotalFee(1);
        }
        request.setOpenid(user.getOpenId());
        request.setNotifyUrl(environment.getProperty("wx.pay.notifyUrl"));
        request.setSpbillCreateIp("180.102.110.170");
        request.setTradeType(WxPayConstants.TradeType.JSAPI);
        request.setSignType("MD5");
        request.setAttach(new JsonUtils.Builder()
                .add("type", "consumption")
                .add("orderId", orderId)
                .add("userId", userId)
                .add("amount", orders.getPrice())
                .build());
        try {
            return wxPayService.createOrder(request);
        } catch (WxPayException e) {
            log.info("微信支付异常", e);
            throw new BusinessException(e.getMessage());
        }
    }

    /*
    回调
     */
    public void handleConsumptionNotify(WxPayOrderNotifyResult notifyResult) {
        JSONObject attach = JSONObject.parseObject(notifyResult.getAttach());
        Long orderId = attach.getLong("orderId");
        Long userId = attach.getLong("userId");
        String type = attach.getString("type");
        BigDecimal amount = BigDecimal.valueOf(notifyResult.getTotalFee() * 0.01);
        String transactionId = notifyResult.getTransactionId();

        wxFeeRepo.save(WxFee.builder()
                .amount(amount)
                .isRefund(false)
                .transactionId(transactionId)
                .type(type)
                .userId(userId)
                .orderId(orderId)
                .build());
        orderInfoService.completed(orderId, transactionId);
    }


}
