package com.izouma.nineth.web;

import com.alibaba.fastjson.JSON;
import com.izouma.nineth.config.Constants;
import com.izouma.nineth.dto.PayQuery;
import com.izouma.nineth.exception.BusinessException;
import com.izouma.nineth.service.HMPayService;
import com.izouma.nineth.service.OrderPayService;
import com.izouma.nineth.service.PayEaseService;
import com.izouma.nineth.service.SandPayService;
import com.izouma.nineth.utils.SnowflakeIdWorker;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/payChannelMgmt")
@AllArgsConstructor
public class PayChannelMgmtController {
    private final SandPayService    sandPayService;
    private final HMPayService      hmPayService;
    private final SnowflakeIdWorker snowflakeIdWorker;
    private final PayEaseService    payEaseService;
    private final OrderPayService   orderPayService;

    @PostMapping(value = "/pay")
    @PreAuthorize("hasRole('ADMIN')")
    public Object pay(@RequestParam String channel, @RequestParam String orderId, String userId, String bindCardId,
                      BigDecimal amount) {
        if (amount == null) {
            amount = new BigDecimal("0.01");
        }
        switch (channel) {
            case "sandQuick":
                return sandPayService.payQuick(orderId, "测试", amount,
                        LocalDateTime.now().plusMinutes(3), "test", "https://www.baidu.com");
            case Constants.PayChannel.SAND:
                return sandPayService.pay(orderId, "测试", amount,
                        LocalDateTime.now().plusMinutes(3), "test");
            case Constants.PayChannel.HM:
                return hmPayService.requestAlipay(orderId, amount, "测试",
                        HMPayService.getTimeout(180), "test", "https://www.baidu.com");
            case Constants.PayChannel.PE:
                return payEaseService.pay("测试", orderId, amount, userId, bindCardId, "test");
        }
        throw new BusinessException("不支持此渠道");
    }

    @GetMapping(value = "/transfer")
    @PreAuthorize("hasRole('ADMIN')")
    public String testTransfer(@RequestParam String name, @RequestParam String bank, @RequestParam BigDecimal amount,
                               @RequestParam(required = false) String phone, @RequestParam String channel) {
        if (Constants.PayChannel.SAND.equals(channel)) {
            return JSON.toJSONString(sandPayService.transfer(snowflakeIdWorker.nextId() + "", name, bank, amount, phone),
                    true);
        } else if (Constants.PayChannel.PE.equals(channel)) {
            return JSON.toJSONString(payEaseService.transfer(snowflakeIdWorker.nextId() + "", name, bank, amount, phone),
                    true);
        }
        throw new BusinessException("unsupported channel");
    }

    @PostMapping(value = "/refund")
    @PreAuthorize("hasRole('ADMIN')")
    public Object refund(@RequestParam String channel, @RequestParam String orderId, String transactionId,
                         @RequestParam BigDecimal amount) {
        return orderPayService.refund(orderId, transactionId, amount, channel);
    }

    @GetMapping(value = "/query")
    @PreAuthorize("hasRole('ADMIN')")
    public PayQuery query(@RequestParam String orderId) {
        return orderPayService.query(orderId);
    }

    @GetMapping("/queryTransfer")
    @PreAuthorize("hasRole('ADMIN')")
    public String queryTransfer(@RequestParam String tranTime, @RequestParam String orderId) {
        return JSON.toJSONString(sandPayService.queryTransfer(tranTime, orderId), true);
    }

    @GetMapping("/balance")
    public Map<String, Object> balance() {
        Map<String, Object> map = new HashMap<>();
        map.put("sand", sandPayService.balance());
        map.put("payEase", payEaseService.balance());
        return map;
    }
}
