package com.bonus.canteen.core.order.mobile.controller;

import com.bonus.canteen.core.common.utils.HeaderFetchUtil;
import com.bonus.canteen.core.order.common.constants.StageWhiteList;
import com.bonus.canteen.core.order.mobile.dto.OrderPayMobileDTO;
import com.bonus.canteen.core.order.mobile.dto.StagePayMobileDTO;
import com.bonus.canteen.core.pay.api.vo.UnifyPayVO;
import com.bonus.canteen.core.pay.common.constants.PayStateEnum;
import com.bonus.canteen.core.pay.common.constants.PayTypeEnum;
import com.bonus.common.core.domain.R;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.houqin.constant.RetCodeEnum;
import com.bonus.canteen.core.common.utils.LogUtil;
import com.bonus.canteen.core.order.common.dto.RequestHeaderDTO;
import com.bonus.canteen.core.order.mobile.business.OrderPlaceMobileBusiness;
import com.bonus.canteen.core.order.mobile.dto.OrderReserveMealTotalDTO;
import com.bonus.canteen.core.order.mobile.vo.OrderPayMobileVO;
import com.bonus.common.houqin.utils.LeRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Objects;

@RestController
@RequestMapping({"/api/v2/mobile/order"})
@Api(
   value = "mobileOrderPlace",
   tags = {"移动端下单接口"}
)
public class OrderPlaceMobileController {
   private static final Logger log = LoggerFactory.getLogger(OrderPlaceMobileController.class);
   @Autowired
   protected OrderPlaceMobileBusiness orderPlaceMobileBusiness;

//   @PostMapping({"/curr/meal/add"})
//   @ApiOperation(
//      value = "当餐下单",
//      notes = "cmt-当餐下单"
//   )
//   public LeResponse<OrderPayMobileVO> addCurrentMealOrder(@RequestHeader Map<String, String> headers, @RequestBody LeRequest<OrderCurrMealTotalDTO> request) {
//      long startTime = System.currentTimeMillis();
//      RequestHeaderDTO headerDTO = RequestHeaderDTO.of(headers);
//      OrderCurrMealTotalDTO currMealTotalDTO = (OrderCurrMealTotalDTO)request.getContent();
//      currMealTotalDTO.setCustId(headerDTO.getCustId());
//      OrderPayMobileVO mobileVO = this.orderPlaceMobileBusiness.addCurrentMealOrder(headerDTO, currMealTotalDTO);
//      LogUtil.info("[当餐下单]支付耗时：{}", System.currentTimeMillis() - startTime, mobileVO);
//      if (CollectionUtils.isNotEmpty(mobileVO.getGoodIdSet())) {
//         return LeResponse.fail(RetCodeEnum.MENU_EXCEED_SURPLUS_NUM, mobileVO);
//      } else {
//         return !mobileVO.success() ? LeResponse.fail(mobileVO.getCode(), mobileVO.getMsg(), mobileVO) : LeResponse.succ(mobileVO);
//      }
//   }

   @PostMapping({"/reserve/meal/add"})
   @ApiOperation(
      value = "预订餐下单",
      notes = "cmt-预订餐下单"
   )
   public R<OrderPayMobileVO> addReserveMealOrder(@RequestHeader Map<String, String> headers, @RequestBody OrderReserveMealTotalDTO reserveMealDTO) {
      long startTime = System.currentTimeMillis();
      RequestHeaderDTO headerDTO = RequestHeaderDTO.of(headers);
      reserveMealDTO.setCustId(headerDTO.getCustId());
      OrderPayMobileVO mobileVO = this.orderPlaceMobileBusiness.addReserveMealOrder(headerDTO, reserveMealDTO);
      LogUtil.info("[预订餐下单]支付耗时", System.currentTimeMillis() - startTime, mobileVO);
      if (CollectionUtils.isNotEmpty(mobileVO.getGoodIdSet())) {
         return R.fail(mobileVO, RetCodeEnum.MENU_EXCEED_SURPLUS_NUM.getDesc());
      } else {
         return !mobileVO.success() ? R.fail(mobileVO, mobileVO.getMsg()) : R.ok(mobileVO);
      }
   }

//   @PostMapping({"/book/meal/add"})
//   @ApiOperation(
//      value = "报餐下单",
//      notes = "cmt-报餐下单"
//   )
//   public LeResponse<OrderPayMobileVO> addBookMealOrder(@RequestHeader Map<String, String> headers, @RequestBody LeRequest<OrderBookMealTotalDTO> request) {
//      long startTime = System.currentTimeMillis();
//      RequestHeaderDTO headerDTO = RequestHeaderDTO.of(headers);
//      OrderBookMealTotalDTO bookMealDTO = (OrderBookMealTotalDTO)request.getContent();
//      bookMealDTO.setCustId(headerDTO.getCustId());
//      OrderPayMobileVO mobileVO = this.orderPlaceMobileBusiness.addBookMealOrder(headerDTO, bookMealDTO);
//      LogUtil.info("[报餐下单]支付耗时", System.currentTimeMillis() - startTime, mobileVO);
//      return !mobileVO.success() ? LeResponse.fail(mobileVO.getCode(), mobileVO.getMsg(), mobileVO) : LeResponse.succ(mobileVO);
//   }
//
//   @PostMapping({"/shop/add"})
//   @ApiOperation(
//      value = "商城下单",
//      notes = "cmt-商城下单"
//   )
//   public LeResponse<OrderPayMobileVO> addShopMealOrder(@RequestHeader Map<String, String> headers, @RequestBody LeRequest<OrderShopDTO> request) {
//      long startTime = System.currentTimeMillis();
//      RequestHeaderDTO headerDTO = RequestHeaderDTO.of(headers);
//      OrderShopDTO orderShopDTO = (OrderShopDTO)request.getContent();
//      orderShopDTO.setCustId(headerDTO.getCustId());
//      OrderPayMobileVO mobileVO = this.orderPlaceMobileBusiness.addShopMealOrder(headerDTO, orderShopDTO);
//      LogUtil.info("[商城下单]支付耗时", System.currentTimeMillis() - startTime, mobileVO);
//      if (CollectionUtils.isNotEmpty(mobileVO.getGoodIdSet())) {
//         return LeResponse.fail(RetCodeEnum.MENU_EXCEED_SURPLUS_NUM, mobileVO);
//      } else {
//         return !mobileVO.success() ? LeResponse.fail(mobileVO.getCode(), mobileVO.getMsg(), mobileVO) : LeResponse.succ(mobileVO);
//      }
//   }
//
//   @PostMapping({"/scan/add"})
//   public LeResponse<OrderPayMobileVO> addScanOrder(@RequestHeader Map<String, String> headers, @RequestBody LeRequest<OrderMobileScanDTO> request) {
//      long startTime = System.currentTimeMillis();
//      RequestHeaderDTO headerDTO = RequestHeaderDTO.of(headers);
//      OrderMobileScanDTO orderShopDTO = (OrderMobileScanDTO)request.getContent();
//      orderShopDTO.setCustId(headerDTO.getCustId());
//      OrderPayMobileVO mobileVO = this.orderPlaceMobileBusiness.addSacnOrder(headerDTO, orderShopDTO);
//      LogUtil.info("[到店扫码下单]支付耗时", System.currentTimeMillis() - startTime, mobileVO);
//      return mobileVO.success() ? LeResponse.succ(mobileVO) : LeResponse.fail(mobileVO.getCode(), mobileVO.getMsg(), mobileVO);
//   }

   @PostMapping({"/pay/by/orderId"})
   @ApiOperation(
      value = "根据订单id支付",
      notes = "cmt-根据订单id支付"
   )
   public AjaxResult orderPayByOrderId(@RequestHeader Map<String, String> headers,
                                       @RequestBody OrderPayMobileDTO orderPayDTO) {
      long startTime = System.currentTimeMillis();
      RequestHeaderDTO headerDTO = RequestHeaderDTO.of(headers);
      orderPayDTO.setCustId(headerDTO.getCustId());
      OrderPayMobileVO mobileVO = this.orderPlaceMobileBusiness.orderPayByOrderId(headerDTO, orderPayDTO);
      LogUtil.info("[根据订单id支付]支付耗时", System.currentTimeMillis() - startTime, mobileVO);
      return !mobileVO.success() ? AjaxResult.error( mobileVO.getMsg(), mobileVO) : AjaxResult.success(mobileVO);
   }

   @PostMapping({"/stage/pay"})
   @ApiOperation(
           value = "驿站付款",
           notes = "驿站付款"
   )
   public AjaxResult stageOrderPay(@RequestHeader Map<String, String> headers,
                                       @RequestBody StagePayMobileDTO stagePayDTO) {
      if(stagePayDTO.getAmount() == null) {
         return AjaxResult.error("金额不能为空");
      }
      if(BigDecimal.ZERO.compareTo(stagePayDTO.getAmount()) >= 0) {
         return AjaxResult.error("金额必须大于0");
      }
      UnifyPayVO mobileVO = null;
      try{
         long startTime = System.currentTimeMillis();
         RequestHeaderDTO headerDTO = RequestHeaderDTO.of(headers);
         stagePayDTO.setPayType(PayTypeEnum.MEAL_CARD.getKey());
         mobileVO = this.orderPlaceMobileBusiness.stageOrderPay(headerDTO, stagePayDTO);
         LogUtil.info("[驿站支付]支付耗时", System.currentTimeMillis() - startTime, mobileVO);
         if(Objects.isNull(mobileVO)) {
            throw new ServiceException("支付失败");
         }
         if(PayStateEnum.isFailedState(mobileVO.getCode())) {
            throw new ServiceException(mobileVO.getMsg());
         }
      }catch (ServiceException ex) {
         log.error("驿站支付异常", ex);
         return AjaxResult.error(ex.getMessage());
      }catch (Exception ex) {
         log.error("驿站支付异常", ex);
         return AjaxResult.error("支付失败");
      }
      return AjaxResult.success(mobileVO);
   }

//   @PostMapping({"/mixPay/by/orderId"})
//   @ApiOperation(
//      value = "根据交易id混合支付",
//      notes = "根据交易id混合支付"
//   )
//   public LeResponse<OrderPayMobileVO> mixPayByTradeId(@RequestHeader Map<String, String> headers, @RequestBody LeRequest<OrderMixPayMobileDTO> request) {
//      long startTime = System.currentTimeMillis();
//      RequestHeaderDTO headerDTO = RequestHeaderDTO.of(headers);
//      OrderMixPayMobileDTO orderMixPayMobileDTO = (OrderMixPayMobileDTO)request.getContent();
//      orderMixPayMobileDTO.setCustId(headerDTO.getCustId());
//      OrderPayMobileVO mobileVO = this.orderPlaceMobileBusiness.orderMixPayByTradeId(headerDTO, orderMixPayMobileDTO);
//      LogUtil.info("[根据交易id混合支付]支付耗时", System.currentTimeMillis() - startTime, mobileVO);
//      return !mobileVO.success() ? LeResponse.fail(mobileVO.getCode(), mobileVO.getMsg(), mobileVO) : LeResponse.succ(mobileVO);
//   }
//
//   @PostMapping({"/pre-book/add"})
//   public LeResponse<OrderPayMobileVO> addPreBook(@RequestHeader Map<String, String> headers, @RequestBody LeRequest<OrderPreBookAddDTO> request) {
//      RequestHeaderDTO headerDTO = RequestHeaderDTO.of(headers);
//      OrderPreBookAddDTO addDTO = (OrderPreBookAddDTO)request.getContent();
//      addDTO.setCustId(headerDTO.getCustId());
//      this.orderPlaceMobileBusiness.orderPreBookAdd(headerDTO, addDTO);
//      return LeResponse.succ();
//   }
}
