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

import cn.hutool.core.collection.CollUtil;
import com.bonus.canteen.core.common.page.PageVO;
import com.bonus.canteen.core.common.utils.LeCodeUtil;
import com.bonus.canteen.core.device.api.DeviceApi;
import com.bonus.canteen.core.device.manage.vo.DeviceInfoVO;
import com.bonus.canteen.core.order.android.business.OrderDishesAndroidBusiness;
import com.bonus.canteen.core.order.android.business.OrderInfoAndroidBusiness;
import com.bonus.canteen.core.order.android.business.OrderPlaceAndroidBusiness;
import com.bonus.canteen.core.order.android.dto.*;
import com.bonus.canteen.core.order.android.vo.*;
import com.bonus.canteen.core.order.common.business.OrderRefundBusiness;
import com.bonus.canteen.core.order.common.constants.OrderRefundBizEnum;
import com.bonus.canteen.core.order.common.dto.OrderCheckDTO;
import com.bonus.canteen.core.order.common.dto.OrderPartRefundDTO;
import com.bonus.canteen.core.order.common.dto.OrderRefundDTO;
import com.bonus.canteen.core.order.common.vo.OrderRefundResultVO;
import com.bonus.canteen.core.order.deprecated.dto.OrdLeCodeDTO;
import com.bonus.canteen.core.report.api.dto.DeviceOrderDishesSumQueryDTO;
import com.bonus.canteen.core.report.api.vo.DeviceOrderDishesSumVO;
import com.bonus.canteen.core.report.api.vo.ReportDeviceOrderSumVO;
import com.bonus.canteen.core.supermarket.api.SupermarketApi;
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.common.houqin.i18n.I18n;
import com.bonus.common.houqin.utils.HeaderFetchUtil;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping({"/api/v3/order/android"})
@Api(
   tags = {"设备订单"}
)
public class OrderAndroidController {
   private static final Logger log = LoggerFactory.getLogger(OrderAndroidController.class);
   @Autowired
   @Lazy
   protected OrderPlaceAndroidBusiness orderPlaceAndroidBusiness;
   @Autowired
   @Lazy
   protected OrderInfoAndroidBusiness orderInfoAndroidBusiness;
   @Autowired
   @Lazy
   protected OrderDishesAndroidBusiness orderDishesAndroidBusiness;
   @Autowired
   @Lazy
   protected OrderRefundBusiness orderRefundBusiness;
   @Autowired
   @Lazy
   protected DeviceApi deviceApi;
   @Autowired
   @Lazy
   protected SupermarketApi supermarketApi;

   @PostMapping({"/place-and-pay"})
//   @RequiresGuest
   public AjaxResult placeAndPay(@RequestHeader Map<String, String> headers,
                                 @RequestBody OrderPayAndroidTotalDTO dto) {
      long startTime = System.currentTimeMillis();
      DeviceInfoVO deviceInfoVO = this.orderPlaceAndroidBusiness.getDeviceInfoByHeader(headers, true);
      OrderPayAndroidVO payAndroidVO = this.orderPlaceAndroidBusiness.placeAndPay(dto, deviceInfoVO);
      log.info("[设备收单支付]支付耗时：{}", System.currentTimeMillis() - startTime);
      return !payAndroidVO.ifSuccess() && dto.ifOnline() ? new AjaxResult(payAndroidVO.getCode(), payAndroidVO.getMsg(),
              payAndroidVO) : AjaxResult.success(payAndroidVO);
   }

   @PostMapping({"/query-pay-result"})
//   @RequiresGuest
   public AjaxResult queryPayResult(@RequestBody @Validated OrderPayAndroidQueryDTO request) {
      long startTime = System.currentTimeMillis();
      OrderPayAndroidVO payAndroidVO = this.orderPlaceAndroidBusiness.queryPayResult((request).getMacOrderId());
      log.info("[设备收单查询]支付耗时：{}", System.currentTimeMillis() - startTime);
      return RetCodeEnum.SUCC.getKey().equals(payAndroidVO.getCode()) ? AjaxResult.success(payAndroidVO) :
              new AjaxResult(payAndroidVO.getCode(), payAndroidVO.getMsg(), payAndroidVO);
   }

   @PostMapping({"/page"})
//   @RequiresGuest
   public AjaxResult page(@RequestBody OrderListAndroidQueryDTO request) {
      PageVO<OrderListAndroidVO> pageVO = this.orderInfoAndroidBusiness.queryPage(request);
      return AjaxResult.success(pageVO);
   }

   @PostMapping({"/page-by-cust"})
//   @RequiresGuest
   public AjaxResult pageByCust(@RequestHeader Map<String, String> headers,
                                @RequestBody OrderListAndroidCustQueryDTO request) {
      PageVO<OrderListAndroidVO> pageVO = this.orderInfoAndroidBusiness.queryPageByCust(request);
      return AjaxResult.success(pageVO);
   }

   @GetMapping({"/info"})
//   @RequiresGuest
   public AjaxResult info(String orderId) {
      OrderInfoAndroidVO infoAndroidVO = this.orderInfoAndroidBusiness.getInfo(Long.valueOf(orderId));
      return AjaxResult.success(infoAndroidVO);
   }

   @GetMapping({"/info-by-qrcode"})
//   @RequiresGuest
   public AjaxResult infoByQrCode(String qrCode) {
      if (!LeCodeUtil.isLeCode(qrCode)) {
         throw new ServiceException(I18n.getMessage("order.mac.code-wrong", new Object[0]));
      } else {
         OrdLeCodeDTO ordLeCodeDTO = LeCodeUtil.readLeCode(qrCode);
         Long orderId = LeCodeUtil.getPlatformId(ordLeCodeDTO);
         OrderInfoAndroidVO infoAndroidVO = this.orderInfoAndroidBusiness.getInfo(orderId);
         return AjaxResult.success(infoAndroidVO);
      }
   }

   /** @deprecated */
   @GetMapping({"/machine-order-stat"})
//   @RequiresGuest
   @Deprecated
   public AjaxResult machineOrderStat(@RequestHeader Map<String, String> headers) {
      ReportDeviceOrderSumVO statByMachine = this.orderInfoAndroidBusiness.getOrderStat((new OrderStatAndroidQueryDTO())
              .setMachineSn(HeaderFetchUtil.getMachineSn(headers)));
      return AjaxResult.success(statByMachine);
   }

   @PostMapping({"/order-stat"})
//   @RequiresGuest
   public AjaxResult orderStat(@RequestBody OrderStatAndroidQueryDTO request) {
      ReportDeviceOrderSumVO statByMachine = this.orderInfoAndroidBusiness.getOrderStat(request);
      return AjaxResult.success(statByMachine);
   }

   @PostMapping({"/order-goods-stat"})
//   @RequiresGuest
   public AjaxResult orderGoodsStat(@RequestBody DeviceOrderDishesSumQueryDTO request) {
      return AjaxResult.success(this.orderInfoAndroidBusiness.pageGoodsState(request));
   }

   @PostMapping({"/sign-in"})
//   @RequiresGuest
   public AjaxResult signIn(@RequestBody OrderSignInAndroidDTO request) {
      OrderAndroidSignInVO orderAndroidSignInVO = this.orderDishesAndroidBusiness.orderSignIn(request);
      return AjaxResult.success(orderAndroidSignInVO.getCallNum());
   }

   @PostMapping({"/cust-take-meal"})
//   @RequiresGuest
   public AjaxResult custTakeMeal(@RequestHeader Map<String, String> headers,
                                                      @RequestBody OrderTakeAndroidDTO content) {
      content.setMachineSn(HeaderFetchUtil.getMachineSn(headers));
      OrderTakeAndroidVO orderTakeAndroidVO = this.orderDishesAndroidBusiness.custTakeMeal(content);
      return AjaxResult.success(orderTakeAndroidVO);
   }

   @PostMapping({"/update-dishes-state"})
//   @RequiresGuest
   public AjaxResult updateDishesState(@RequestBody OrderDishesUpdateAndroidDTO content) {
      if (CollUtil.size(content.getOrderIds()) == 1) {
         this.orderDishesAndroidBusiness.orderUpdateDishesState(content.toSingleUpdateDTO());
      } else {
         this.orderDishesAndroidBusiness.orderUpdateDishesState(content.getOrderIds(), content.getDishesState());
      }

      return AjaxResult.success();
   }

   @PostMapping({"/refund"})
//   @RequiresGuest
   public AjaxResult refund(@RequestBody OrderRefundDTO content) {
      OrderRefundResultVO orderRefundResultVO = this.orderRefundBusiness.orderRefund(content.convertToOrderRefundParam(),
              OrderRefundBizEnum.ANDROID);
      return orderRefundResultVO.ifSuccess() ? AjaxResult.success() :
              AjaxResult.error(orderRefundResultVO.getResultCode(), orderRefundResultVO.getResultMsg());
   }

   @PostMapping({"/correct"})
//   @RequiresGuest
   public AjaxResult orderCorrect(@RequestBody OrderPartRefundDTO request) {
      this.orderRefundBusiness.orderCorrect(request, OrderRefundBizEnum.ANDROID_CORRECT);
      return AjaxResult.success();
   }

   @PostMapping({"/refund-check"})
//   @RequiresGuest
   public AjaxResult refundCheck(@RequestBody OrderCheckDTO request) {
      this.orderRefundBusiness.orderCheck(request);
      return AjaxResult.success();
   }
}
