package com.cyksj.web.controller.wholesale;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.util.Jsons;
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.mapper.GoodsWholesaleMapper;
import com.cyksj.mapper.GoodsWholesaleOrderDonMapper;
import com.cyksj.mapper.GoodsWholesaleUserDepositMapper;
import com.cyksj.mapper.GoodsWholesaleUserReturnRecordMapper;
import com.cyksj.model.dto.AliPayParams;
import com.cyksj.model.entity.*;
import com.cyksj.model.request.AlipayOrderDonReq;
import com.cyksj.model.request.GoodsWholesaleOrderPayReq;
import com.cyksj.model.response.AliPayTradeStatus;
import com.cyksj.model.views.GoodsWholesaleFrontOrderView;
import com.cyksj.model.views.GoodsWholesaleFrontView;
import com.cyksj.model.views.GoodsWholesaleOrderDonView;
import com.cyksj.model.views.WholeGoodsSkuPayUserDetailView;
import com.cyksj.redis.RedisService;
import com.cyksj.service.order.GoodsWholesalePayService;
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.*;
import java.util.stream.Collectors;

/**
 * server/批发下单
 * 项目名: yhlxj
 * 文件名: GoodsWholesaleWebControlelr
 * 创建者: JavaZou
 * 创建时间:2024/8/26 17:41
 */
@RestController
@RequestMapping("/applet/wholesale")
@RequiredArgsConstructor
@Slf4j
public class GoodsWholesaleWebController {
	private final BeanSearcher beanSearcher;

	private final HttpServletRequest request;

	private final RedisService redisService;

	private final GoodsWholesaleOrderDonMapper orderDonMapper;

	private final UserBindRelationService userBindRelationService;

	private final GoodsWholesaleUserDepositMapper goodsWholesaleUserDepositMapper;

	private final GoodsWholesalePayService goodsWholesalePayService;

	private final GoodsWholesaleMapper goodsWholesaleMapper;

	private final GoodsWholesaleUserReturnRecordMapper returnRecordMapper;

	/**
	 * 平台批发列表
	 */
	@GetMapping("/get")
	public Result<List<GoodsWholesaleFrontView>> goodsWholesaleList() {
		long userId = StpUserUtil.getLoginIdAsLong();
		String key = RedisService.key.GOODS_WHOLESALE_KEY.getName();
		List<GoodsWholesaleFrontView> list = (List<GoodsWholesaleFrontView>) redisService.get(key);

		if (list == null) {
			list = beanSearcher.searchAll(GoodsWholesaleFrontView.class, MapUtils.builder().build());
			redisService.setNx(key, list, RedisService.key.GOODS_WHOLESALE_KEY.getTimeout());
		}
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		list.forEach(data->{
			data.setTotal(orderDonMapper.getUserWholesaleNumByUserIds(userIdList, data.getSkuId()));
		});
		return GatewayResponse.SUCCESS.newBuilder().toResult(list);
	}

	/**
	 * 押金支付详情
	 */
	@GetMapping("/get/deposit/detail")
	public Result<GoodsWholesaleUserDeposit> getUserDepositDetail() {
		long userId = StpUserUtil.getLoginIdAsLong();
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		GoodsWholesaleUserDeposit goodsWholesaleUserDeposit = goodsWholesaleUserDepositMapper.selectOne(Wrappers.lambdaQuery(GoodsWholesaleUserDeposit.class)
				.in(GoodsWholesaleUserDeposit::getUserId, userIdList)
				.last("limit 1")
				.select(GoodsWholesaleUserDeposit::getId, GoodsWholesaleUserDeposit::getIsGoal, GoodsWholesaleUserDeposit::getMoney, GoodsWholesaleUserDeposit::getStatus));
		if (goodsWholesaleUserDeposit == null) {
			return GatewayResponse.SUCCESS.newBuilder().toResult(goodsWholesaleUserDeposit);
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult(goodsWholesaleUserDeposit);
	}

	/**
	 * 当前批发规格已购买详情
	 */
	@GetMapping("/get/sku/detail")
	public Result<WholeGoodsSkuPayUserDetailView> getUserPayWholesaleSkuDetail(@RequestParam(required = true) Long orderId) {
		long userId = StpUserUtil.getLoginIdAsLong();
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		WholeGoodsSkuPayUserDetailView wholeGoodsSkuPayUserDetailView = beanSearcher.searchFirst(WholeGoodsSkuPayUserDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
				.put("oid", String.format("where id = %s", orderId))
				.field(WholeGoodsSkuPayUserDetailView::getUserId, userIdList).op(Operator.InList)
				.build());
		wholeGoodsSkuPayUserDetailView.setTotal(orderDonMapper.getUserWholesaleNumByUserIds(userIdList, wholeGoodsSkuPayUserDetailView.getSkuId()));

		GoodsWholesale goodsWholesale = goodsWholesaleMapper.selectOne(Wrappers.lambdaQuery(GoodsWholesale.class)
				.eq(GoodsWholesale::getSkuId, wholeGoodsSkuPayUserDetailView.getSkuId())
				.eq(GoodsWholesale::getDeleted, 1)
				.last("limit 1"));
		wholeGoodsSkuPayUserDetailView.setIsReturn(goodsWholesale.getIsReturn());
		if (goodsWholesale != null && goodsWholesale.getIsReturn()) {
			String configStr = goodsWholesale.getConfig();
			List<GoodsWholesale.GoodsWholesaleConfig> configs = null;
			try {
				configs = Jsons.parseList(configStr, GoodsWholesale.GoodsWholesaleConfig.class);
				GoodsWholesale.GoodsWholesaleConfig endConfig = configs.get(configs.size() - 1);
				wholeGoodsSkuPayUserDetailView.setGoal(endConfig.getStart());
			} catch (Exception e) {
			}
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult(wholeGoodsSkuPayUserDetailView);
	}

	@GetMapping("/get/order/goods")
	public Result<List<GoodsWholesaleFrontOrderView>> getWholesaleOrderGoodsList() {
		long userId = StpUserUtil.getLoginIdAsLong();
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		String userIds = userIdList.stream().map(id -> id.toString()).collect(Collectors.joining(","));
		List<GoodsWholesaleFrontOrderView> goodsWholesaleFrontOrderViews = beanSearcher.searchAll(GoodsWholesaleFrontOrderView.class, MapUtils.flatBuilder(request.getParameterMap())
				.put("uid", String.format("where user_id in (%s)", userIds)).build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(goodsWholesaleFrontOrderViews);
	}

	/**
	 * 支付押金
	 */
	@PostMapping("/post/submit/deposit")
	public Result<GoodsWholesaleUserDeposit> submitDeposit() throws Exception {
		long userId = StpUserUtil.getLoginIdAsLong();
		GoodsWholesaleUserDeposit deposit = goodsWholesalePayService.submitDeposit(userId);
		return GatewayResponse.SUCCESS.newBuilder().toResult(deposit);
	}

	/**
	 * 下单批发
	 */
	@PostMapping("/post/submit")
	public Result<GoodsWholesaleOrderDon> submit(@RequestBody @Validated GoodsWholesaleOrderPayReq payReq) throws Exception {
		long userId = StpUserUtil.getLoginIdAsLong();
		payReq.setUserId(userId);
		GoodsWholesaleOrderDon orderDon = goodsWholesalePayService.unifiedPay(payReq);
		return GatewayResponse.SUCCESS.newBuilder().toResult(orderDon);
	}

	/**
	 * 取消批发订单
	 */
	@PutMapping("/close/order/{orderId}")
	public Result<String> closeWholesaleOrder(@PathVariable Long orderId) throws Exception {
		long userId = StpUserUtil.getLoginIdAsLong();
		goodsWholesalePayService.closeWholesaleOrder(orderId, userId);
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}

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

	/**
	 * 批发支付宝web支付
	 * pc网页内嵌二维码
	 */
	@PostMapping("/post/pay/wholesale/web/zfb")
	public Result<String> zfbWholesaleWebQrCode(@RequestBody @Validated AlipayOrderDonReq re) throws Exception {
		AliPayParams aliPayParams = goodsWholesalePayService.zfbWholesaleWebQrCode(re, ZfbProductCode.PC_WEB.getProductCode(), BaseZfbConfig.qrPayMode_orderCode);
		return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody());
	}

	/**
	 * 批发支付宝回调
	 */
	@PostMapping("/zfb/notify")
	public String aliPayWholesaleNotify(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);
			goodsWholesalePayService.aliPayWholesaleNotify(params);
		} else {
			log.error("支付宝回调 error 状态不符合 成功或完成 status:{} ,orderNo:{}", tradeStatus, orderNo);
			return "fail";
		}
		return "success";
	}

	/**
	 * 批发押金支付宝回调
	 */
	@PostMapping("/deposit/zfb/notify")
	public String aliPayWholesaleDepositNotify(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);
			goodsWholesalePayService.aliPayWholesaleDepositNotify(params);
		} else {
			log.error("支付宝回调 error 状态不符合 成功或完成 status:{} ,orderNo:{}", tradeStatus, orderNo);
			return "fail";
		}
		return "success";
	}

	/**
	 * 查询订单状态
	 */
	@GetMapping("/get/order/status/{orderId}")
	public Result<Object> getOrderStatus(@RequestParam(defaultValue = "2") Integer type, @PathVariable Long orderId) {
		long userId = StpUserUtil.getLoginIdAsLong();
		Object o = goodsWholesalePayService.getOrderStatus(userId, type, orderId);
		return GatewayResponse.SUCCESS.newBuilder().toResult(o);
	}

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

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

	/**
	 * 是否已返差价
	 */
	@GetMapping("/return/differ")
	public Result<GoodsWholesaleUserReturnRecord> returnDiffer(@RequestParam(required = true) Long orderId) {
		long userId = StpUserUtil.getLoginIdAsLong();
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		GoodsWholesaleOrderDon orderDon = orderDonMapper.selectById(orderId);
		GoodsWholesaleUserReturnRecord returnRecord = returnRecordMapper.selectOne(Wrappers.lambdaQuery(GoodsWholesaleUserReturnRecord.class)
				.in(GoodsWholesaleUserReturnRecord::getUserId, userIdList)
				.eq(GoodsWholesaleUserReturnRecord::getSkuId, orderDon.getSkuId())
				.last("limit 1")
				.select(GoodsWholesaleUserReturnRecord::getReturnBalance, GoodsWholesaleUserReturnRecord::getSkuId, GoodsWholesaleUserReturnRecord::getNum));
		return GatewayResponse.SUCCESS.newBuilder().toResult(returnRecord);
	}


	/**
	 * 获取支付宝回调参数
	 */
	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;
	}

}
