package com.izouma.dingdong.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.izouma.dingdong.domain.FeeRecord;
import com.izouma.dingdong.domain.OrderInfo;
import com.izouma.dingdong.enums.PayMethod;
import com.izouma.dingdong.exception.BusinessException;
import com.izouma.dingdong.repo.FeeRecordRepo;
import com.izouma.dingdong.repo.OrderInfoRepo;
import com.izouma.dingdong.service.ConsumptionService;
import com.izouma.dingdong.service.OrderInfoService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.web.bind.annotation.*;

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

import static com.alibaba.fastjson.serializer.SerializerFeature.PrettyFormat;

@RestController
@RequestMapping("/pay")
@AllArgsConstructor
@Slf4j
public class PayConsumptionController {
    private ConsumptionService consumptionService;
    private FeeRecordRepo      feeRecordRepo;
    private OrderInfoService   orderInfoService;
    private OrderInfoRepo      orderInfoRepo;

    /**
     * 支付回调
     *
     * @param request
     * @param response
     * @return
     */
    @PostMapping(value = "/notify", produces = "application/json; charset=utf-8")
    public Map<?, ?> notify(HttpServletRequest request, HttpServletResponse response) {
        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("ksher支付回调 {}", JSON.toJSONString(params, PrettyFormat));

        Map<String, String> result = new HashMap<>();

        if (MapUtils.getString(params, "result").equals("SUCCESS")) {
            JSONObject body = JSON.parseObject(params.get("data"));
            //保存到流水
            feeRecordRepo.save(FeeRecord.builder()
                    .channel(body.getString("channel"))
                    .feeType(body.getString("fee_type"))
                    .isRefund(false)
                    .totalFee(body.getInteger("total_fee"))
                    .isPay(true)
                    .mchNo(body.getString("mch_order_no"))
                    .orderId(body.getString("attach"))
                    .dateTime(LocalDateTime.now())
                    .enabled(true)
                    .build());

            orderInfoService.toCompleted(Long.parseLong(body.getString("mch_order_no")));
            result.put("result", "SUCCESS");
            result.put("msg", "OK");
            return result;
        }

        // 注意：必须按这个结构返回
        result.put("result", "FAIL");
        result.put("msg", "OK");
        return result;
    }

    /**
     * 订单支付
     *
     * @param orderId
     */
    @GetMapping(value = "/payOrder")
    public String payOrder(@RequestParam Long orderId) {
        OrderInfo orderInfo = orderInfoRepo.findById(orderId).orElseThrow(new BusinessException("无订单"));
       /* switch (orderInfo.getPayMethod()) {
            case CASH_DELIVERY:
                orderInfoService.toCompleted(orderId);
            case ALI_PAY:
            case WE_CHAT:
                consumptionService.appPay(orderInfo);
                break;
            case CREDIT_CARD:
                consumptionService.cardPay(orderInfo);
                break;
        }*/
        if (!PayMethod.CASH_DELIVERY.equals(orderInfo.getPayMethod())) {
            return consumptionService.cardPay(orderInfo);
        }
        return null;

    }
}
