package org.springblade.gateway.goods_gateway.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.GifCaptcha;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.generator.MathGenerator;
import cn.hutool.captcha.generator.RandomGenerator;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.log.logger.BladeLogger;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.tool.api.R;
import org.springblade.gateway.goods_gateway.constant.HelpGoodsConstant;
import org.springblade.gateway.goods_gateway.service.AppHelpGoodsService;
import org.springblade.gateway.goods_gateway.util.HelpGoodsUtil;
import org.springblade.payment.cmcc.request.CmccDectOrderRequest;
import org.springblade.payment.cmcc.request.CmccPlaceOrderRequest;
import org.springblade.payment.cmcc.util.CmccUtil;
import org.springblade.sing.active.entity.ActiveRecord;
import org.springblade.sing.active.service.IActiveRecordService;
import org.springblade.sing.goods.entity.HelpGoods;
import org.springblade.sing.goods.service.IHelpGoodsService;
import org.springblade.sing.goods.vo.HelpGoodsVO;
import org.springblade.sing.goods.wrapper.HelpGoodsWrapper;
import org.springblade.sing.point.entity.CmccPointRecord;
import org.springblade.sing.yeepay.entity.YeepayOrder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;

/**
 * @Author: Silent
 * @Description
 * @Date: Created in 14:12 2021/11/10
 * @Modified By:
 */
@RestController
@AllArgsConstructor
@RequestMapping("app/help/goods")
@Api(value = "助力商场", tags = "助力商场接口")
@Slf4j
public class AppHelpGoodsController {
	private final AppHelpGoodsService appHelpGoodsService;
	private final IHelpGoodsService helpGoodsService;
	private final IActiveRecordService activeRecordService;
	private final BladeLogger bladeLogger;
	private final BladeRedis bladeRedis;


	/**
	 * 兑换道具
	 */
	@ApiLog("兑换道具")
	@PostMapping("/exchangeProps")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "兑换道具")
	public R<String> exchangeProps(@ApiParam(value = "道具ID", required = true) @RequestParam Long helpGoodsId,
								   @ApiParam(value = "用户ID", required = true) @RequestParam Long userId,
								   @ApiParam(value = "购买数量", required = true) @RequestParam BigDecimal num,
								   @ApiParam(value = "作品ID", required = true) @RequestParam Long productId,
								   @ApiParam(value = "验证码") @RequestParam(required = false) String code,
								   CmccDectOrderRequest cmccDectOrderRequest) {
		try {
			CmccPointRecord cmccPointRecord = new CmccPointRecord();
			cmccPointRecord.setHelpGoodsId(helpGoodsId);
			cmccPointRecord.setUserId(userId);
			cmccPointRecord.setNum(num);
			//加锁
			synchronized (cmccPointRecord.getUserId().toString().intern()) {
				appHelpGoodsService.exchangeProps(cmccPointRecord, cmccDectOrderRequest, productId, null, code);
			}
			return R.success("兑换成功");
		} catch (Exception e) {
			log.error(e.getMessage());
			return R.fail(e.getMessage());
		}
	}


	/**
	 * 创建道具验证码
	 */
	@GetMapping("/createPropsVerificationCode")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "创建道具验证码")
	public R<String> createPropsVerificationCode(@ApiParam(value = "道具ID", required = true) @RequestParam Long helpGoodsId,
												 @ApiParam(value = "用户ID", required = true) @RequestParam Long userId,
												 @ApiParam(value = "作品ID", required = true) @RequestParam Long productId) {
		// 创建图像验证码
		RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
		GifCaptcha gifCaptcha = CaptchaUtil.createGifCaptcha(250, 100);
		gifCaptcha.setGenerator(randomGenerator);
		// 重新生成code
		gifCaptcha.createCode();
		// 创建验证码，并放到缓存中，有效期60秒
		bladeRedis.setEx(HelpGoodsConstant.getVerificationCodeKey(userId, productId, helpGoodsId), gifCaptcha.getCode(), HelpGoodsConstant.HELP_GOODS_VERIFICATION_CODE_EXIST_TIME);
		return R.data(gifCaptcha.getImageBase64Data());
	}

	/**
	 * 创建现金道具订单
	 */
	@ApiLog("创建现金道具订单")
	@PostMapping("/createCashPropsOrder")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "创建现金道具订单")
	public R<YeepayOrder> createCashPropsOrder(@ApiParam(value = "道具ID", required = true) @RequestParam Long helpGoodsId,
											   @ApiParam(value = "用户ID", required = true) @RequestParam Long userId,
											   @ApiParam(value = "手机号码", required = true) @RequestParam String phone,
											   @ApiParam(value = "作品ID", required = true) @RequestParam Long productId,
											   @ApiParam(value = "openId", required = true) @RequestParam String openId,
											   @ApiParam(value = "购买数量", required = true) @RequestParam Integer num) {
		try {
			YeepayOrder yeepayOrder = new YeepayOrder() {{
				setNum(num);
				setHelpGoodsId(helpGoodsId);
				setPhone(phone);
				setUserId(userId);
				setProductId(productId);
				setOpenId(openId);
			}};
			//创建随机单号
			appHelpGoodsService.createCashPropsOrder(yeepayOrder);
			return R.data(yeepayOrder);
		} catch (Exception e) {
			log.error(e.getMessage());
			return R.fail(e.getMessage());
		}
	}

	/**
	 * 现金支付回调地址
	 */
	@ApiLog("现金支付回调地址")
	@RequestMapping(value = "/callbackUrl", method = {RequestMethod.GET, RequestMethod.POST})
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "现金支付回调地址")
	public String callbackUrl(HttpServletRequest request) {
		bladeLogger.info("道具订单支付回调", request.getParameterMap().toString());
		log.info("道具订单支付回调:{}", request.getParameterMap().toString());

		//处理现金道具支付回调
		appHelpGoodsService.handlerCasePropsOrder(request);
		return "SUCCESS";
	}

	/**
	 * 创建道具订单
	 */
	@ApiLog("创建道具订单")
	@PostMapping("/createPropsOrder")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "创建道具订单")
	public R<String> createPropsOrder(@ApiParam(value = "道具ID", required = true) @RequestParam Long helpGoodsId,
									  @ApiParam(value = "用户ID", required = true) @RequestParam Long userId,
									  @ApiParam(value = "手机号码", required = true) @RequestParam String phone,
									  @ApiParam(value = "购买数量", required = true) @RequestParam BigDecimal num,
									  @ApiParam(value = "同盾设备指纹", required = true) @RequestParam String fingerprint,
									  @ApiParam(value = "通付盾参数", required = true) @RequestParam String sessionId) {
		try {
			CmccPlaceOrderRequest cmccPlaceOrderRequest = CmccPlaceOrderRequest
				.builder()
				.fingerprint(fingerprint)
				.sessionId(sessionId)
				.build();

			CmccPointRecord cmccPointRecord = new CmccPointRecord();
			cmccPointRecord.setHelpGoodsId(helpGoodsId);
			cmccPointRecord.setNum(num);
			cmccPointRecord.setPhone(phone);
			cmccPointRecord.setUserId(userId);
			//创建随机单号
			appHelpGoodsService.createPropsOrder(cmccPointRecord, cmccPlaceOrderRequest);
			return R.data(cmccPlaceOrderRequest.getOutOrderId());
		} catch (Exception e) {
			log.error(e.getMessage());
			return R.fail(e.getMessage());
		}
	}

	/**
	 * 发送验证码
	 */
	@PostMapping("/sendCmccSms")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "发送验证码")
	public R<String> sendCmccSms(@ApiParam(value = "手机号码", required = true) @RequestParam String mobile,
								 @ApiParam(value = "订单号ID", required = true) @RequestParam String outOrderId) {
		try {
			CmccPlaceOrderRequest cmccPlaceOrderRequest = CmccPlaceOrderRequest
				.builder()
				.mobile(mobile)
				.outOrderId(outOrderId)
				.build();
			CmccUtil.sendCmccSms(cmccPlaceOrderRequest);
			return R.data(cmccPlaceOrderRequest.getOutOrderId());
		} catch (Exception e) {
			log.error(e.getMessage());
			return R.fail(e.getMessage());
		}
	}

	/**
	 * 初始化道具缓存(预热)
	 */
	@PostConstruct
	public void init() {
		for (ActiveRecord activeRecord : activeRecordService.list(
			Wrappers.<ActiveRecord>lambdaQuery().select(ActiveRecord::getId))) {
			HelpGoodsUtil.setHelpGoodsListCache(activeRecord.getId(),
				helpGoodsService.list(Wrappers.<HelpGoods>lambdaQuery().eq(HelpGoods::getActiveId, activeRecord.getId()).eq(HelpGoods::getStatus, 1)));
		}
	}

	/**
	 * 获取道具助力列表
	 */
	@GetMapping("/getHelpGoodsList")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "获取道具助力列表")
	public R<List<HelpGoodsVO>> getHelpGoodsList(@ApiParam(value = "活动ID", required = true) @RequestParam Long activeId,
												 @ApiParam(value = "用户ID", required = true) @RequestParam Long userId,
												 @ApiParam(value = "作品ID", required = true) @RequestParam Long productId) {
		return R.data(HelpGoodsWrapper.build(userId, productId)
			.listVO(HelpGoodsUtil.getHelpGoodsList(activeId)));
	}
}
