package com.cyksj.web.controller.spotify;

import com.cyksj.config.zfb.BaseZfbConfig;
import com.cyksj.config.zfb.ZfbProductCode;
import com.cyksj.dto.Result;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.model.dto.AliPayParams;
import com.cyksj.model.dto.SpotifyOrderInfoDto;
import com.cyksj.model.entity.SpotifyUserSelfServiceRecord;
import com.cyksj.model.entity.SpotifyUserUpgradeOrder;
import com.cyksj.model.entity.SpotifyUserUpgradeSubmitRecord;
import com.cyksj.model.request.AlipayOrderDonReq;
import com.cyksj.model.request.SpotifyUpgradeInfoReq;
import com.cyksj.model.request.SpotifyUpgradeOrderReq;
import com.cyksj.model.response.AliPayTradeStatus;
import com.cyksj.service.order.OrderDonService;
import com.cyksj.service.spotify.SpotifyUserUpgradeOrderService;
import com.cyksj.service.user.UserBindRelationService;
import com.cyksj.web.util.StpUserUtil;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.SearchResult;
import com.ejlchina.searcher.param.Operator;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

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

/**
 * 项目名: yhlxj
 * 文件名: SpotifyController
 * 创建者: JavaZou
 * 创建时间:2024/12/3 12:11
 */
@RestController
@RequestMapping("/applets/spotify")
@RequiredArgsConstructor
@Slf4j
public class SpotifyController {
	private final SpotifyUserUpgradeOrderService spotifyUserUpgradeOrderService;

	private final OrderDonService orderDonService;

	private final UserBindRelationService userBindRelationService;

	private final BeanSearcher beanSearcher;

	private final HttpServletRequest request;

	/**
	 * 提交升级订单
	 */
	@PostMapping("/upgrade/submit")
	public Result<SpotifyUserUpgradeOrder> upgradeSubmit(@RequestBody SpotifyUpgradeOrderReq spotifyUpgradeOrderReq) {
		long userId = StpUserUtil.getLoginIdAsLong();
		spotifyUpgradeOrderReq.setUserId(userId);
		SpotifyUserUpgradeOrder order = spotifyUserUpgradeOrderService.upgradeSubmit(spotifyUpgradeOrderReq);
		return GatewayResponse.SUCCESS.newBuilder().toResult(order);
	}

	/**
	 * 支付宝表单支付
	 * 支付宝调起支付宝表单
	 * 手机支付
	 */
	@PostMapping("/post/pay/zfb")
	public Result<String> aliPaySpotifyUpgrade(@RequestBody @Validated AlipayOrderDonReq re) throws Exception {
		AliPayParams aliPayParams = orderDonService.aliPaySpotifyUpgrade(re, ZfbProductCode.MOBILE_WEB.getProductCode(), null);
		return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody());
	}

	/**
	 * 支付宝web支付
	 */
	@PostMapping("/get/zfb/orderQrCode")
	public Result<String> zfbWebQrCode(@RequestBody @Validated AlipayOrderDonReq re) throws Exception {
		AliPayParams aliPayParams = orderDonService.aliPaySpotifyUpgrade(re, ZfbProductCode.PC_WEB.getProductCode(), BaseZfbConfig.qrPayMode_orderCode);
		return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody());
	}

	/**
	 * 支付宝回调
	 */
	@PostMapping("/prepay/zfb/upgrade/notify")
	public String aliPaySpotifyUpgradeNotify(HttpServletRequest request) throws Exception {
		////将异步通知中收到的所有参数都存放到map中
		Map<String, String> params = convertRequestParamsToMap(request);
		String tradeStatus = params.get("trade_status");
		String orderNo = params.get("out_trade_no");
		if (AliPayTradeStatus.TRADE_SUCCESS.getStatus().equals(tradeStatus) || AliPayTradeStatus.TRADE_FINISHED.getStatus().equals(tradeStatus)) {
			log.info("支付宝商家订单号orderNo:{},status:{}开始回调", orderNo, tradeStatus);
			orderDonService.aliPaySpotifyUpgradeNotify(params);
		} else {
			log.error("支付宝回调 error 状态不符合 成功或完成 status:{} ,orderNo:{}", tradeStatus, orderNo);
			return "fail";
		}
		return "success";
	}

	/**
	 * 查询订单状态
	 */
	@GetMapping("/get/order/status/{orderId}")
	public Result<SpotifyUserUpgradeOrder> getOrderStatus(@PathVariable Long orderId) {
		long userId = StpUserUtil.getLoginIdAsLong();
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		SpotifyUserUpgradeOrder order = beanSearcher.searchFirst(SpotifyUserUpgradeOrder.class, MapUtils.builder()
				.field(SpotifyUserUpgradeOrder::getId, orderId)
				.field(SpotifyUserUpgradeOrder::getUserId, userIdList).op(Operator.InList)
				.build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(order);
	}

	/**
	 * 订单列表
	 */
	@GetMapping("/get/order")
	public Result<SearchResult<SpotifyUserUpgradeOrder>> getOrders() {
		long userId = StpUserUtil.getLoginIdAsLong();
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		SearchResult<SpotifyUserUpgradeOrder> search = beanSearcher.search(SpotifyUserUpgradeOrder.class, MapUtils.flatBuilder(request.getParameterMap())
				.field(SpotifyUserUpgradeOrder::getUserId, userIdList).op(Operator.InList)
				.build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 是否开启升级spotify权限
	 */
	@GetMapping("/get/upgrade/permit")
	public Result<Boolean> getUpgradePermit() {
		long userId = StpUserUtil.getLoginIdAsLong();
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		Number number = beanSearcher.searchCount(SpotifyUserSelfServiceRecord.class, MapUtils.builder().field(SpotifyUserSelfServiceRecord::getUserId, userIdList).op(Operator.InList).build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(number.intValue() > 0);
	}

	/**
	 * 提交账号信息
	 */
	@PostMapping("/upgrade/submit/info")
	public Result<String> submitUpgradeInfo(@RequestBody SpotifyUpgradeInfoReq spotifyUpgradeInfoReq) {
		long userId = StpUserUtil.getLoginIdAsLong();
		spotifyUpgradeInfoReq.setUserId(userId);
		spotifyUserUpgradeOrderService.submitUpgradeInfo(spotifyUpgradeInfoReq);
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}

	/**
	 * 查看提交账号信息
	 */
	@GetMapping("/upgrade/submit/account")
	public Result<SpotifyOrderInfoDto> getUpgradeSubmitAccount() {
		long userId = StpUserUtil.getLoginIdAsLong();
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		SpotifyOrderInfoDto spotifyOrderInfoDto = new SpotifyOrderInfoDto();
		SpotifyUserUpgradeOrder order = beanSearcher.searchFirst(SpotifyUserUpgradeOrder.class, MapUtils.builder()
				.field(SpotifyUserUpgradeOrder::getUserId, userIdList).op(Operator.InList)
				.field(SpotifyUserUpgradeOrder::getStatus, SpotifyUserUpgradeOrder.Status.hasPayment.name())
				.build());
		if (order == null) {
			spotifyOrderInfoDto.setStatus(SpotifyOrderInfoDto.Status.noPayment.name());
		} else {
			spotifyOrderInfoDto.setRelationId(order.getRelationId());
			SpotifyUserUpgradeSubmitRecord upgradeSubmitRecord = beanSearcher.searchFirst(SpotifyUserUpgradeSubmitRecord.class, MapUtils.builder()
					.field(SpotifyUserUpgradeSubmitRecord::getUserId, userIdList).op(Operator.InList)
					.field(SpotifyUserUpgradeSubmitRecord::getRelationId, order.getRelationId())
					.orderBy(SpotifyUserUpgradeSubmitRecord::getId).desc().build());
			if (upgradeSubmitRecord == null) {
				spotifyOrderInfoDto.setStatus(SpotifyOrderInfoDto.Status.notSubmitted.name());
			} else {
				spotifyOrderInfoDto.setAccount(upgradeSubmitRecord.getAccount());
				spotifyOrderInfoDto.setPassword(upgradeSubmitRecord.getPassword());
				spotifyOrderInfoDto.setEmail(upgradeSubmitRecord.getEmail());
				spotifyOrderInfoDto.setStatus(upgradeSubmitRecord.getStatus().name());
			}
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult(spotifyOrderInfoDto);
	}

	/**
	 * 获取支付宝回调参数
	 */
	private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
		Map<String, String> retMap = 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) {
				retMap.put(name, values[0]);
			} else if (valLen > 1) {
				StringBuilder sb = new StringBuilder();
				for (String val : values) {
					sb.append(",").append(val);
				}
				retMap.put(name, sb.substring(1));
			} else {
				retMap.put(name, "");
			}
		}
		return retMap;
	}
}
