package com.tzy.controller.mall;

import com.tzy.annotation.ApiLimitRule;
import com.tzy.annotation.ApiLog;
import com.tzy.common.config.handle.ApiVersion;
import com.tzy.common.constant.Constants;
import com.tzy.common.constant.MqConstans;
import com.tzy.common.core.controller.BaseController;
import com.tzy.common.dto.InDto;
import com.tzy.common.dto.OutDTO;
import com.tzy.common.enums.BusinessType;
import com.tzy.common.exception.ServiceException;
import com.tzy.common.utils.DateUtils;
import com.tzy.common.utils.bean.JSONTools;
import com.tzy.dto.EvaluationDTO;
import com.tzy.dto.OrderReq;
import com.tzy.framework.util.RedisUtils;
import com.tzy.framework.web.domain.LimitRule;
import com.tzy.member.benefits.mapper.MemberBenefitsRecordMapper;
import com.tzy.pojo.item.EvaluationRecord;
import com.tzy.pojo.item.OrderList;
import com.tzy.pojo.item.Sku;
import com.tzy.service.MallOrderService;
import com.tzy.sportcard.api.domain.AppUserInfoDto;
import com.tzy.sportcard.api.service.AsyncAppService;
import com.tzy.sportcard.api.service.MineApiService;
import com.tzy.sportcard.api.service.PayService;
import com.tzy.sportcard.group.domain.CardGroupOrderInfo;
import com.tzy.sportcard.group.service.ICardGroupOrderInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;
import org.teasoft.bee.osql.Condition;
import org.teasoft.bee.osql.FunctionType;
import org.teasoft.bee.osql.Op;
import org.teasoft.bee.osql.SuidRich;
import org.teasoft.honey.osql.core.ConditionImpl;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * @author by po'yi
 * @Classname MallOrderController
 * @Description 订单
 * @Date 2022/3/18 11:56
 */
@Slf4j
@Api("订单")
@RestController
@RequestMapping("/api/{version}/order")
public class MallOrderController extends BaseController {

	@Autowired
	private MineApiService mineApiService;
	@Autowired
	private MallOrderService mallOrderService;
	@Autowired
	private ICardGroupOrderInfoService cardGroupOrderInfoService;
	@Autowired
	private SuidRich suidRich;
	@Autowired
	private RedisUtils redisUtils;
	@Autowired
	@Lazy
	private AsyncAppService asyncAppService;
	@Resource
	private MemberBenefitsRecordMapper memberBenefitsRecordMapper;
	@Resource
	private  RabbitTemplate rabbitTemplate;
	@Autowired
	private PayService payService;


	@ApiLog(title = "提交订单", businessType = BusinessType.SEARCH)
	@ResponseBody
	@ApiVersion(1.0)
	@ApiOperation("提交订单")
	@ApiLimitRule(seconds = 2,limitCount=10,type= LimitRule.ACT,msg="抱歉,抢购人数太多,请稍后再试!")
	@PostMapping("/submit")
	public OutDTO submitOrder(@RequestBody OrderReq inDto ){
		return OutDTO.error500("请更新app最新版本");
	}

	@ApiLog(title = "预支付2", businessType = BusinessType.SEARCH)
	@ResponseBody
	@ApiVersion(1.0)
	@ApiOperation("预支付2")
	@PostMapping("/prePayNew")
	public OutDTO orderPrePayNew(@RequestBody InDto inDto ){
		return OutDTO.error500("请先升级app");
	}

	@ApiLog(title = "积分兑换", businessType = BusinessType.SEARCH)
	@ResponseBody
	@ApiVersion(1.0)
	@ApiOperation("积分兑换 ")
	@ApiLimitRule(seconds = 1,limitCount=1,type= LimitRule.USER,msg="操作拼豆,请稍后再试!")
	@PostMapping("/buyOfPoint")
	public OutDTO buyOfPoint(@RequestBody InDto inDto ){
		return OutDTO.error500("请更新app最新版本");
	}

	@ApiLog(title = "积分兑换优惠劵", businessType = BusinessType.SEARCH)
	@ResponseBody
	@ApiVersion(1.0)
	@ApiOperation("积分兑换优惠劵,根据spuId兑换")
	@ApiLimitRule(seconds = 2,limitCount=10,type= LimitRule.ACT_TOKEN,msg="抱歉,抢购人数太多,请稍后再试!")
	@PostMapping("/exchangeCouponByPoint")
	public OutDTO exchangeCouponByPoint(@RequestBody InDto inDto ){
		Object spuId = inDto.get("spuId");
		if(spuId==null){
			return OutDTO.error500("参数skuId为空");
		}
		Integer skuId=getCouponSkuId(Long.valueOf(spuId.toString()));
		Integer purchaseCount=1;
		if(inDto.get("purchaseCount")!=null){
			//购买数量
			purchaseCount = (Integer) inDto.get("purchaseCount");
			if(purchaseCount<1 ){
				return OutDTO.error500("请选择兑换数量");
			}
		}
		AppUserInfoDto userInfo = mineApiService.checkUserNew(inDto);
		return mallOrderService.buyOfPoint(userInfo.getId(),skuId,inDto.get("addressId"),purchaseCount);
	}

	private Integer getCouponSkuId(Long spuId){
		Object o = redisUtils.get(Constants.SKU_COUPON_ID_CACHE + spuId);
		Integer skuId;
		if(o==null){
			Sku sku = new Sku();
			sku.setSpuId(spuId);
			sku.setStatus(201L);
			List<Sku> skus = suidRich.select(sku);
			if(skus.isEmpty()||skus.size()!=1){
				throw new ServiceException(500, "优惠劵数量异常,请联系管理员!");
			}
			skuId = skus.get(0).getId().intValue();
			redisUtils.set(Constants.SKU_COUPON_ID_CACHE + spuId,skuId,Constants.ONE_HOUR);
		}else{
			skuId=(Integer)o;
		}
		return skuId;
	}

	@ApiLog(title = "取消订单",businessType = BusinessType.UPDATE,indto = "{{inDto}}")
	@ApiOperation("取消订单")
	@ResponseBody
	@PostMapping(value = "/cancelOrder")
	public OutDTO cancelOrder(@RequestBody InDto inDto){
		mineApiService.checkUserNew(inDto);
		Integer orderId = (Integer) inDto.get("orderId");
		CardGroupOrderInfo cardGroupOrderInfo = cardGroupOrderInfoService.selectCardGroupOrderInfoById(orderId.longValue());
		if(null == cardGroupOrderInfo ){
			return OutDTO.error500("未找到订单信息");
		}
		//判断是否符合取消订单的条件
		Long status = cardGroupOrderInfo.getStatus();
		if(status != 100){
			return OutDTO.error500("不符合取消订单的条件!");
		}

		// 唤起支付前做一个查询
		if(cardGroupOrderInfoService.checkOrderIsPay(orderId.longValue())){
			return OutDTO.error500("订单支付中,无法取消!");
		}
		// 抢拍订单不允许取消
		String orderSubType = cardGroupOrderInfo.getOrderSubType();
		if(Strings.isNotEmpty(orderSubType) && Constants.AUCTION_ORDER_COMMON_AMOUNT.equals(orderSubType)){
			return OutDTO.error500("抢拍订单不能取消!");
		}
		//用户取消
		cardGroupOrderInfo.setStatus(202L);
		// 释放库存
		if (Constants.ORDER_TYPE_SHOP.equals(cardGroupOrderInfo.getOrderType())) {
			mallOrderService.cancelOrder(cardGroupOrderInfo);
			// 如果是权益兑换订单  删除权益兑换记录
			String prop3 = cardGroupOrderInfo.getProp3();
			if (Constants.MEMBER_BENEFITS.equals(cardGroupOrderInfo.getOrderSubType()) && Strings.isNotEmpty(prop3)) {
				// 根据权益兑换记录id删除权益兑换记录
				memberBenefitsRecordMapper.deleteMemberBenefitsRecordById(Long.parseLong(prop3));
			}
			if (cardGroupOrderInfo.getGiveOrderId() != null) {
				rabbitTemplate.convertAndSend(MqConstans.EXCHANGE_DELAYED_ORDER_EXPIRED, MqConstans.ROUTING_KEY_ORDER_EXPIRED, cardGroupOrderInfo.getGiveOrderId());
			}
		} else if (Constants.ORDER_TYPE_GIFT_CARD.equals(cardGroupOrderInfo.getOrderType())) {
			CardGroupOrderInfo updateOrder = new CardGroupOrderInfo();
			updateOrder.setId(orderId.longValue());
			updateOrder.setStatus(202L);
			cardGroupOrderInfoService.updateCardGroupOrderInfo(updateOrder);
		} else {
			cardGroupOrderInfoService.cancelOrder(cardGroupOrderInfo);
		}
		cardGroupOrderInfoService.returnCouponByOrderId(orderId.longValue());
		//回退积分
		mineApiService.addUserPoint(cardGroupOrderInfo, true, Constants.POINT_TYPE_COMMON_RETURN);
		return OutDTO.ok();
	}

	@ApiLog(title = "用户申请售后",businessType = BusinessType.UPDATE,indto = "{{inDto}}")
	@ApiOperation("用户申请售后,退款,换货")
	@ResponseBody
	@PostMapping(value = "/afterSale")
	public OutDTO refundOrder(@RequestBody InDto inDto){
		AppUserInfoDto userInfo = mineApiService.checkUserNew(inDto);
		Integer orderId = (Integer) inDto.get("orderId");
		CardGroupOrderInfo cardGroupOrderInfo = cardGroupOrderInfoService.getOrderByUserAndId(userInfo.getId(),orderId.longValue());
		if(null == cardGroupOrderInfo ){
			return OutDTO.error(500,"未找到订单信息");
		}

		if(cardGroupOrderInfo.getPoint()!=null&&cardGroupOrderInfo.getPoint()>0){
			return OutDTO.error500("积分订单无法申请,请联系客服!");
		}

		//判断是否符合取消订单的条件
		Long status = cardGroupOrderInfo.getStatus();
		if(!Constants.refundOrderStatus.contains(status.intValue())){
			return OutDTO.error500("订单不符合申请退款的条件");
		}
		// 抢拍订单不允许退款
		String orderSubType = cardGroupOrderInfo.getOrderSubType();
		if(Strings.isNotEmpty(orderSubType) && Constants.AUCTION_ORDER_COMMON_AMOUNT.equals(orderSubType)){
			return OutDTO.error500("抢拍订单不能退款!");
		}
		OrderList orderList = new OrderList();
		orderList.setOrderId(cardGroupOrderInfo.getId());
		Condition beeCondition = new ConditionImpl();
		beeCondition.op("liveId", Op.gt,0);
		String living = suidRich.selectWithFun(orderList, FunctionType.COUNT, "*", beeCondition);
		if(Integer.valueOf(living)>0){
			return OutDTO.error500("订单正在直播中,不符合申请退款的条件");
		}

		String refundType =inDto.getString("refundType");
		String refundReason =inDto.getString("refundReason");
		String refundDesc =inDto.getString("refundDesc");
		CardGroupOrderInfo updateOrder = new CardGroupOrderInfo();
		updateOrder.setId(cardGroupOrderInfo.getId());
		updateOrder.setUserRefundTime(DateUtils.getTimestampNow());
		updateOrder.setRefundType(refundType);
		updateOrder.setRefundReason(refundReason);
		updateOrder.setRefundDesc(refundDesc);
		updateOrder.setRefundStatus(1);
		cardGroupOrderInfoService.updateCardGroupOrderInfo(updateOrder);
		asyncAppService.sendMerchantRefundNotice(cardGroupOrderInfo);
		return OutDTO.ok();
	}


	@ApiLog(title = "用户评价订单",businessType = BusinessType.UPDATE,indto = "{{inDto}}")
	@ApiOperation("用户评价订单")
	@ResponseBody
	@PostMapping(value = "/evaluation")
	public OutDTO evaluateOrder(@RequestBody InDto inDto){
		AppUserInfoDto appUserInfoDto = mineApiService.checkUserNew(inDto);
		Integer orderId = (Integer) inDto.get("orderId");
		CardGroupOrderInfo cardGroupOrderInfo = cardGroupOrderInfoService.selectCardGroupOrderInfoById(orderId.longValue());
		if(null == cardGroupOrderInfo ){
			return OutDTO.error(10040,"未找到订单信息");
		}

		if(cardGroupOrderInfo.getStatus()!=301){
			return OutDTO.error(500,"订单未签收!");
		}
		//json
		String evaluation =inDto.getString("evaluation");
		CardGroupOrderInfo updateOrder = new CardGroupOrderInfo();
		updateOrder.setId(cardGroupOrderInfo.getId());
		updateOrder.setEvaluation(evaluation);
		cardGroupOrderInfoService.updateCardGroupOrderInfo(updateOrder);

		EvaluationDTO evaluationDTO = JSONTools.jsonStr2obj(evaluation, EvaluationDTO.class);
		EvaluationRecord evaluationRecord = new EvaluationRecord();
		evaluationRecord.setCreateUserId(appUserInfoDto.getId());
		evaluationRecord.setAvatar(appUserInfoDto.getAvatar());
		evaluationRecord.setNickName(appUserInfoDto.getNickname());
		evaluationRecord.setAnonymous(evaluationDTO.getAnonymous()?1:0);
		evaluationRecord.setContent(evaluationDTO.getContent());
		evaluationRecord.setImgUrl(evaluationDTO.getImgArrAll());
		evaluationRecord.setValue(evaluationDTO.getValue());
		evaluationRecord.setType("spu");
		List<OrderList> orderLists = mallOrderService.getOrderListByOrderId(cardGroupOrderInfo.getId());
		evaluationRecord.setRefId(orderLists.get(0).getSpuId());
		evaluationRecord.setCreateTime(DateUtils.getTimestampNow());
		suidRich.insert(evaluationRecord);
		return OutDTO.ok();
	}

	@ApiLog(title = "用户填写退换货物流",businessType = BusinessType.UPDATE,indto = "{{inDto}}")
	@ApiOperation("用户填写退换货物流")
	@ResponseBody
	@PostMapping(value = "/refundShip")
	public OutDTO refundShip(@RequestBody InDto inDto){
		mineApiService.checkUserNew(inDto);
		Integer orderId = (Integer) inDto.get("orderId");
		CardGroupOrderInfo cardGroupOrderInfo = cardGroupOrderInfoService.selectCardGroupOrderInfoById(orderId.longValue());
		if(null == cardGroupOrderInfo ){
			return OutDTO.error(10040,"未找到订单信息");
		}
		if(cardGroupOrderInfo.getRefundStatus()!=2){
			return OutDTO.error(500,"请等待商家同意!");
		}
		String refundCurierCompany =inDto.getString("refundCurierCompany");
		String refundCurierNum =inDto.getString("refundCurierNum");
		CardGroupOrderInfo updateOrder = new CardGroupOrderInfo();
		updateOrder.setId(cardGroupOrderInfo.getId());
		updateOrder.setRefundCurierCompany(refundCurierCompany);
		updateOrder.setRefundCourierNum(refundCurierNum);
		updateOrder.setRefundShipTime(DateUtils.getTimestampNow());
		updateOrder.setRefundStatus(4);
		cardGroupOrderInfoService.updateCardGroupOrderInfo(updateOrder);
		return OutDTO.ok();
	}


	@ApiLog(title = "售后客服介入或接受商家拒绝退款操作",businessType = BusinessType.UPDATE,indto = "{{inDto}}")
	@ApiOperation("售后客服介入或接受商家拒绝退款操作")
	@ResponseBody
	@PostMapping(value = "/saleCustomerServiceOrNot")
	public OutDTO saleCustomerService(@RequestBody InDto inDto){
		mineApiService.checkUserNew(inDto);
		Integer orderId = (Integer) inDto.get("orderId");
		CardGroupOrderInfo cardGroupOrderInfo = cardGroupOrderInfoService.selectCardGroupOrderInfoById(orderId.longValue());
		if(null == cardGroupOrderInfo ){
			return OutDTO.error(10040,"未找到订单信息");
		}

		if(cardGroupOrderInfo.getRefundStatus()!=3){
			return OutDTO.error(500,"请等待商家操作!");
		}

		CardGroupOrderInfo updateOrder = new CardGroupOrderInfo();
		updateOrder.setId(cardGroupOrderInfo.getId());
		if(inDto.get("refundStatus")==null){
			updateOrder.setRefundStatus(6);
		}else{
			updateOrder.setRefundStatus((Integer)inDto.get("refundStatus"));
		}
		cardGroupOrderInfoService.updateCardGroupOrderInfo(updateOrder);
		return OutDTO.ok();
	}

	@ApiLog(title = "商城支付方式", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
	@ResponseBody
	@PostMapping(value = "/v1/checkPayCat")
	public OutDTO checkPayCat(@RequestBody InDto inDto) {
		AppUserInfoDto appUserInfoDto = mineApiService.checkUserNew(inDto);
		return payService.checkGoodsPayCat( inDto, appUserInfoDto);
	}

	@ApiLog(title = "商城支付方式-v2 支持香港支付", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
	@ResponseBody
	@PostMapping(value = "/v2/checkPayCat")
	public OutDTO checkPayCatV2(@RequestBody InDto inDto) {
		AppUserInfoDto appUserInfoDto = mineApiService.checkUserNew(inDto);
		return payService.checkGoodsPayCatV2( inDto, appUserInfoDto);
	}

	@ApiLog(title = "商城支付方式-v3 用户标签重构", businessType = BusinessType.SEARCH, indto = "{{inDto}}")
	@ResponseBody
	@PostMapping(value = "/v3/checkPayCat")
	public OutDTO checkPayCatV3(@RequestBody InDto inDto) {
		AppUserInfoDto appUserInfoDto = mineApiService.checkUserNew(inDto);
		return payService.checkGoodsPayCatV3( inDto, appUserInfoDto);
	}

	/**
	 * @param inDto
	 * @return
	 */
	@ApiLog(title = "对公转账上传", businessType = BusinessType.SEARCH)
	@ResponseBody
	@ApiVersion(1.0)
	@ApiOperation("对公转账上传")
	@PostMapping("/{version}/corporatePublicToPay")
	public OutDTO corporatePublicToPay(@RequestBody InDto inDto ,@PathVariable("version") String version){
		Object orderId = inDto.get("orderId");
		if(Objects.isNull(orderId)){
			OutDTO.error(500, "订单id不能为空!");
		}
		AppUserInfoDto appUserInfoDto = mineApiService.checkUserNew(inDto);
		return payService.corporatePublicToPay(version,inDto,appUserInfoDto);
	}


	@ApiLog(title = "预支付3", businessType = BusinessType.SEARCH)
	@ResponseBody
	@ApiVersion(1.0)
	@ApiOperation("预支付3")
	@PostMapping("/v3/prePayNew")
	public OutDTO orderPrePayNewV3(@RequestBody InDto inDto) {
		Integer orderId = inDto.getIntegerParam("orderId");
		if (orderId == null) {
			return OutDTO.error500("id为空!");
		}
		AppUserInfoDto appUserInfoDto = mineApiService.checkUserNew(inDto);
		return payService.orderPrePayV3(inDto, appUserInfoDto, orderId.longValue(), "goods");
	}

	/**
	 * 订单预支付-新通道 新分配规则
	 * @param inDto
	 * @return
	 */
	@ApiLog(title = "预支付4【订单预支付-新通道 新分配规则】", businessType = BusinessType.SEARCH)
	@ResponseBody
	@ApiVersion(1.0)
	@ApiOperation("预支付4")
	@PostMapping("/v4/prePayNew")
	public OutDTO orderPrePayNewV4(@RequestBody InDto inDto) {
		Integer orderId = inDto.getIntegerParam("orderId");
		if (orderId == null) {
			return OutDTO.error500("id为空!");
		}
		AppUserInfoDto appUserInfoDto = mineApiService.checkUserNew(inDto);
		return payService.orderPrePayV4(inDto, appUserInfoDto, orderId.longValue(), "goods");
	}

}
