package org.springblade.gateway.common_gateway.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springblade.common.enums.AppConstant;
import org.springblade.common.enums.PaymentScene;
import org.springblade.common.enums.PaymentType;
import org.springblade.common.enums.ResCode;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.log.logger.BladeLogger;
import org.springblade.core.tool.api.R;
import org.springblade.payment.callback.inivtation.InvitationCallback;
import org.springblade.payment.entity.PayParam;
import org.springblade.payment.plugin.Payment;
import org.springblade.payment.plugin.PaymentBuilder;
import org.springblade.yeePay.service.YeePayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

/**
 * @author: lianghanqiang
 * @description: 支付模块控制器
 * @since: 7/29/21 -- 1:55 PM
 */
@Api(tags = "支付模块")
@RestController
@RequestMapping("/payment")
public class PaymentController {

	@Autowired
	PaymentBuilder paymentBuilder;

	@Autowired
	YeePayService yeePayService;
	@Autowired
	BladeLogger bladeLogger;

	@ApiOperation("订单支付")
	@GetMapping("/payOrder/{paymentType}/{paymentScene}")
	public R payOrder(
		@PathVariable String paymentType,
		@PathVariable String paymentScene,
		@Validated PayParam payParam
	) {
		//获取支付插件
		Payment payment = pluginBuild(paymentType);
		//解析支付场景
		PaymentScene scene = Optional.of(PaymentScene.valueOf(paymentScene))
			.orElseThrow(() -> new ServiceException(ResCode.PAY_SCENE_ERROR));
		switch (scene) {
			case PAY_CODE:
				return payment.payCode(payParam);
			case SCAN_CODE:
				return payment.nativePay(payParam);
			case TRANSFER:
				return payment.transfer(payParam);
			case MINI_PROGRAM:
				return payment.miniProgram(payParam);
			default:
				return null;
		}
	}

	@GetMapping("support")
	@ApiOperation("获取支付类型列表")
	public R<PaymentType[]> getSupportList() {
		return R.data(PaymentType.values());
	}

	@ApiLog
	@ApiOperation(value = "支付回调")
	@RequestMapping(value = "/callback/{paymentType}", method = {RequestMethod.GET, RequestMethod.POST})
	public String callback(HttpServletRequest request, @PathVariable String paymentType) {
		bladeLogger.info(paymentType + "支付回调", request.getParameterMap().toString());
		//获取支付插件
		Payment payment = pluginBuild(paymentType);
		payment.callback(request);
		return "SUCCESS";
	}

	@ApiLog
	@ApiOperation(value = "清算回调")
	@RequestMapping(value = "/csurl/{paymentType}", method = {RequestMethod.GET, RequestMethod.POST})
	public String csBack(HttpServletRequest request, @PathVariable String paymentType) {
		bladeLogger.info(paymentType + "清算回调", request.getParameterMap().toString());
		//获取支付插件
		Payment payment = pluginBuild(paymentType);
		payment.csUrl(request);
		return "SUCCESS";
	}

	@ApiLog
	@ApiOperation(value = "入驻回调")
	@RequestMapping(value = "/invitation/callback/{invitationType}", method = {RequestMethod.GET, RequestMethod.POST})
	public String invitationCallback(HttpServletRequest request, @PathVariable String invitationType) {
		bladeLogger.info(invitationType + "入驻回调", request.getParameterMap().toString());
		AppConstant.InvitationType type = AppConstant.InvitationType.valueOf(invitationType);
		new InvitationCallback().handle(request, type);
		return "SUCCESS";
	}


	private Payment pluginBuild(String paymentType) {
		return paymentBuilder.fetchPaymentPlugin(
			Optional.of(PaymentType.valueOf(paymentType))
				.orElseThrow(() -> new ServiceException(ResCode.PAY_TYPE_ERROR))
		);
	}

}
