package com.cyksj.web.controller.vip;

import cn.hutool.extra.servlet.ServletUtil;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.StringUtil;
import com.cyksj.dto.Result;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.model.dto.AliPayParams;
import com.cyksj.model.entity.PaypalPayConfig;
import com.cyksj.model.entity.VipOrderDon;
import com.cyksj.model.request.AlipayOrderDonReq;
import com.cyksj.model.request.VipOrderDonPayReq;
import com.cyksj.model.response.AliPayTradeStatus;
import com.cyksj.service.order.VipOrderDonService;
import com.cyksj.service.paypal.PayPalService;
import com.cyksj.service.paypal.PaypalPayConfigService;
import com.cyksj.service.paypal.PaypalV2Service;
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.MapBuilder;
import com.ejlchina.searcher.util.MapUtils;
import com.paypal.api.payments.Links;
import com.paypal.api.payments.Payment;
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 javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * server/银河会员/订单
 * 项目名: yhlxj2
 * 文件名: VipUserOrderController
 * 创建者: JavaZou
 * 创建时间:2025/5/13 11:08
 */
@RestController
@RequestMapping("/applet/vip/orders")
@RequiredArgsConstructor
@Slf4j
public class VipUserOrderController {
	private final HttpServletRequest request;

	private final VipOrderDonService vipOrderDonService;

	private final PayPalService payPalService;

	private final PaypalV2Service paypalV2Service;

	private final PaypalPayConfigService paypalPayConfigService;

	private final HttpServletResponse response;

	private final UserBindRelationService userBindRelationService;

	private final BeanSearcher beanSearcher;

	/**
	 * 会员预下单
	 */
	@PostMapping("/post/submit")
	public Result<VipOrderDon> submit(@Validated @RequestBody VipOrderDonPayReq payRequest) throws Exception {
		final String methodName = "吊起会员预支付";
		Long userId = StpUserUtil.getUserIdAfterLogin();
		payRequest.setUserId(userId);
		log.info("{}[start] params:{}", methodName, payRequest);

		String ip = ServletUtil.getClientIP(request);
		String address = StringUtil.getNewInternalAddressByIp(ip);
		//address.contains("柬埔寨") ||
		if (address != null && address.contains("缅甸")) {
			throw BusinessRuntimeException.getInstance("用户异常");
		}
		VipOrderDon orderDon = vipOrderDonService.submit(payRequest);
		return GatewayResponse.SUCCESS.newBuilder().toResult(orderDon);
	}

	/**
	 * 续费会员预下单
	 */
	@PostMapping("/post/renew")
	public Result<VipOrderDon> renew(@Validated @RequestBody VipOrderDonPayReq payRequest) throws Exception {
		final String methodName = "吊起会员续费预支付";
		Long userId = StpUserUtil.getUserIdAfterLogin();
		log.info("{}[start] params:{}", methodName, payRequest);
		payRequest.setUserId(userId);
		VipOrderDon orderDon = vipOrderDonService.renew(payRequest);
		return GatewayResponse.SUCCESS.newBuilder().toResult(orderDon);
	}

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

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



	/**
	 * 支付宝支付
	 */
	@PostMapping("/post/pay/zfb")
	public Result<String> aliPay(@RequestBody @Validated AlipayOrderDonReq re) throws Exception {
		AliPayParams aliPayParams = vipOrderDonService.aliPay(re);
		return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody());
	}

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

	/**
	 * 关闭订单
	 */
	@PutMapping("/close/{orderId}")
	public Result closeOrderDon(@PathVariable Long orderId) throws Exception {
		long userId = StpUserUtil.getLoginIdAsLong();
		vipOrderDonService.closeOrderDon(userId, orderId);
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}


	/**
	 * paypal支付
	 */
	@PostMapping("/paypal/pay/{orderId}")
	public Result<String> paypalPay(@PathVariable Long orderId, String successUrl) throws Exception {
		final String methodName = "paypal支付";
		log.info("{}[start] orderId:{}",methodName,orderId);

		Payment payment = payPalService.createVipPayment(orderId,successUrl);
		String payUrl = "/";
		log.info("paypal links:{}",payment.getLinks());
		for(Links links : payment.getLinks()){
			if("approval_url".equals(links.getRel())){
				// 客户付款登陆地址
				String payPalUrl = links.getHref();
				log.info("PayPal调起支付成功[end]：{}", orderId);
				payUrl = payPalUrl;
			}
		}

		log.info("paypal支付成功[end]");

		return GatewayResponse.SUCCESS.newBuilder().toResult(payUrl);
	}

	/**
	 * paypal支付回调
	 */
	@RequestMapping(value = "/paypal/notify")
	public void successPay(@RequestParam(value = "paymentId") String paymentId, @RequestParam(value = "PayerID") String PayerID) throws Exception {
		PaypalPayConfig paypalPayConfig = paypalPayConfigService.getById(1);
		response.sendRedirect(payPalService.successVipPayment(paymentId,PayerID,paypalPayConfig));
	}

	/**
	 * paypalV2支付
	 */
	@PostMapping("/paypalV2/pay/{orderId}")
	public Result<String> paypalV2Pay(@PathVariable Long orderId,String successUrl) throws Exception {
		final String methodName = "paypal支付";
		log.info("{}[start] orderId:{}",methodName,orderId);

		String payUrl = paypalV2Service.createVipPayment(orderId,successUrl);
		log.info("paypal links:{}",payUrl);
		log.info("paypal支付成功[end]");

		return GatewayResponse.SUCCESS.newBuilder().toResult(payUrl);
	}

	/**
	 * paypalV2支付回调
	 */
	@RequestMapping(value = "/paypalV2/notify")
	public void successV2Pay(@RequestParam(value = "token") String token, @RequestParam(value = "PayerID") String PayerID) throws Exception {
		PaypalPayConfig paypalPayConfig = paypalPayConfigService.getById(1);
		response.sendRedirect(paypalV2Service.successVipPayment(token,PayerID,paypalPayConfig));
	}

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