package com.izouma.nineth.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.izouma.nineth.config.AlipayProperties;
import com.izouma.nineth.config.GeneralProperties;
import com.izouma.nineth.enums.PayMethod;
import com.izouma.nineth.event.OrderNotifyEvent;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@RestController
@Slf4j
@AllArgsConstructor
public class AlipayNotifyController {
    private AlipayProperties  alipayProperties;
    private GeneralProperties generalProperties;
    private RocketMQTemplate  rocketMQTemplate;

    @PostMapping("/alipay/notify")
    @ResponseBody
    public String notify(HttpServletRequest request) throws AlipayApiException {
        Map<String, String> params = new HashMap<>();
        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                params.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                params.put(name, sb.toString().substring(1));
            } else {
                params.put(name, "");
            }
        }
        log.info("支付宝回调 {}", JSON.toJSONString(params, true));
        AlipaySignature.rsaCheckV1(params, alipayProperties.getAliPublicKey(), "UTF-8", "RSA2");
        if (MapUtils.getString(params, "trade_status").equals("TRADE_SUCCESS")) {
            JSONObject body = JSON.parseObject(params.get("body"));
            String type = body.getString("type");
            Long orderId = body.getLong("orderId");
            String tradeNo = params.get("trade_no");
            switch (type) {
                case "order":
                    rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
                            new OrderNotifyEvent(orderId, PayMethod.ALIPAY,
                                    tradeNo, System.currentTimeMillis()));
                    break;
                case "gift":
                    rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
                            new OrderNotifyEvent(orderId, PayMethod.ALIPAY, tradeNo,
                                    System.currentTimeMillis(), OrderNotifyEvent.TYPE_GIFT_ORDER));
                    break;
                case "mintOrder":
                    rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
                            new OrderNotifyEvent(orderId, PayMethod.ALIPAY, tradeNo,
                                    System.currentTimeMillis(), OrderNotifyEvent.TYPE_MINT_ORDER));
                    break;
                case "recharge":
                    rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
                            new OrderNotifyEvent(orderId, PayMethod.ALIPAY, tradeNo,
                                    System.currentTimeMillis(), OrderNotifyEvent.TYPE_RECHARGE));
                    break;
                case "auctionOrder":
                    rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
                            new OrderNotifyEvent(orderId, PayMethod.ALIPAY, tradeNo,
                                    System.currentTimeMillis(), OrderNotifyEvent.TYPE_AUCTION_ORDER));
                    break;
            }
        }
        return "success";
    }
}
