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

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bonus.canteen.core.common.base.BaseController;
import com.bonus.canteen.core.common.constant.MachinePayOnlineEnum;
import com.bonus.canteen.core.common.enums.SourceTypeEnum;
import com.bonus.canteen.core.common.redis.RedisUtil;
import com.bonus.canteen.core.device.api.DeviceApi;
import com.bonus.canteen.core.order.common.constants.OrderTypeEnum;
import com.bonus.canteen.core.order.deprecated.dto.*;
import com.bonus.canteen.core.order.deprecated.service.MacPayNewBusiness;
import com.bonus.canteen.core.order.deprecated.vo.MacOrdPayVO;
import com.bonus.canteen.core.order.deprecated.vo.MacOrdSupermarketPayVO;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.houqin.i18n.I18n;
import com.bonus.canteen.core.order.deprecated.service.MacPayNewBusiness;
import com.bonus.common.houqin.utils.RetCodeEnum;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping({"/api/v1/payment"})
@Api(
   value = "pay",
   tags = {"设备支付控制器"}
)
public class MacPayController extends BaseController {
   private static final Logger log = LoggerFactory.getLogger(MacPayController.class);
   @Autowired
   @Lazy
   DeviceApi deviceApi;
   @Autowired
   @Lazy
   private StringRedisTemplate stringRedisTemplate;
   @Autowired
   @Lazy
   private MacPayNewBusiness macPayNewBusiness;

   private void delRedisKey(String key) {
      Boolean hasKey = this.stringRedisTemplate.hasKey(key);
      if (hasKey != null && hasKey) {
         this.stringRedisTemplate.delete(key);
      }

   }

   @ApiOperation("设备收单支付")
   @PostMapping({"/OrdPayMachine/fegin"})
//   @RequiresGuest
   public AjaxResult unityReceiptOrdPayFegin(@RequestHeader Map<String, String> headers,
                                                @RequestBody MacPayReceiptOrdDTO request) {
      return this.unityReceiptOrdPayNew(headers, request);
   }

   @PostMapping({"/OrdPayMachine"})
//   @RequiresGuest
   @ApiOperation(
      value = "设备收单支付",
      notes = "设备收单支付-cmt"
   )
   public AjaxResult unityReceiptOrdPayNew(@RequestHeader Map<String, String> headers,
                                            @RequestBody @Valid MacPayReceiptOrdDTO receiptOrdDTO) {
      if (StringUtils.isBlank(receiptOrdDTO.getMachineSn())) {
         receiptOrdDTO.setMachineSn(this.getMachineSnHeaders(headers));
      }

      if (StringUtils.isBlank(receiptOrdDTO.getMchNum())) {
         receiptOrdDTO.setMchNum(this.getMachineNumHeaders(headers));
      }

      if (ObjectUtil.isNull(receiptOrdDTO.getSourceType())) {
         receiptOrdDTO.setSourceType(this.getSourceTypeByHeaders(headers));
      }

      if (SourceTypeEnum.ANDROID_BINDING.getKey().equals(receiptOrdDTO.getSourceType())
              || SourceTypeEnum.AUTONOMOUS_WEIGHING.getKey().equals(receiptOrdDTO.getSourceType())) {
         receiptOrdDTO.setTakeOutFlag(OrderTypeEnum.RESERVE_SHOP.getKey());
      }

      receiptOrdDTO.setIfOnline(MachinePayOnlineEnum.MACHINE_PAY_ONLINE.getKey());
      long start = System.currentTimeMillis();

      try {
         MacOrdPayVO macOrdPayVO = this.macPayNewBusiness.macOrdPlaceAndPay(receiptOrdDTO);
         log.info("[设备下单]支付出参{},总耗时:{}", JSON.toJSONString(macOrdPayVO), System.currentTimeMillis() - start);
         return macOrdPayVO.getUnpaidBalance() != null && macOrdPayVO.getUnpaidBalance() > 0 ?
                 new AjaxResult(RetCodeEnum.PAY_BALANCE_NO_ENOUGH.getKey(), "余额不足", macOrdPayVO) : AjaxResult.success(macOrdPayVO);
      } catch (ServiceException var8) {
         log.error("[设备下单]订单号{}支付，自定义异常:{}", receiptOrdDTO.getMacOrdId(), var8.getMessage());
         String leMessage = var8.getMessage();
         if (StrUtil.isBlank(leMessage)) {
            leMessage = I18n.getMessage("order.mac.pay-failed", new Object[0]);
         }

         return AjaxResult.error(var8.getCode(), leMessage);
      } catch (Exception var9) {
         log.error("[设备下单]订单号{}支付异常:{}", receiptOrdDTO.getMacOrdId(), var9.getMessage());
         return AjaxResult.error("支付失败,请联系管理员");
      }
   }

   private void deletePayHandlerKey(String macOrdId) {
      String macOrdIdHandlerKey = this.macPayNewBusiness.getMacOrdHandlerKey(macOrdId);
      RedisUtil.delete(macOrdIdHandlerKey);
   }

   @PostMapping({"/OrdPaySelect"})
//   @RequiresGuest
   @ApiOperation(
      value = "统一收单支付查询接口",
      notes = "统一收单支付查询接口-cmt"
   )
   public AjaxResult unityQueryReceiptOrdPayNew(@RequestHeader Map<String, String> headers,
                                                @RequestBody @Valid MacQueryPayReceiptOrdDTO queryPayDTO) {
      queryPayDTO.setMchNum(this.getMachineNumHeaders(headers));
      queryPayDTO.setMachineSn(this.getMachineSnHeaders(headers));
      queryPayDTO.setSourceType(this.getSourceTypeByHeaders(headers));

      try {
         MacOrdPayVO macOrdPayVO = this.macPayNewBusiness.macOrdPayResultQuery(queryPayDTO);
         this.deletePayHandlerKey(queryPayDTO.getMacOrdId());
         return AjaxResult.success(macOrdPayVO);
      } catch (ServiceException var5) {
         log.error("[设备支付查询]订单号{}查询支付结果，自定义异常:{}", queryPayDTO.getMacOrdId(), var5.getMessage());
         return AjaxResult.error(var5.getCode(), var5.getMessage());
      } catch (Exception var6) {
         log.error("[设备支付查询]订单号{}查询支付结果异常:{}", queryPayDTO.getMacOrdId(), var6.getMessage());
         return AjaxResult.error("支付失败,请联系管理员");
      }
   }

   @PostMapping({"/ord/pay/cancel"})
//   @RequiresGuest
   @ApiOperation(
      value = "取消支付",
      notes = "取消支付-cmt"
   )
   public AjaxResult ordPayCancel(@RequestHeader Map<String, String> headers,
                                  @RequestBody @Valid MacOrdPayCancelDTO payCancelDTO) {
      payCancelDTO.setMachineSn(this.getMachineSnHeaders(headers));

      try {
         MacOrdPayVO macOrdPayVO = this.macPayNewBusiness.macOrdPayCancel(payCancelDTO);
         if (ObjectUtil.isNotNull(macOrdPayVO)) {
             return new AjaxResult(RetCodeEnum.SUCC_MAC_ORD.getKey(), "设备单号重复,特殊成功标识", macOrdPayVO);
         } else {
            return AjaxResult.success();
         }
      } catch (ServiceException var6) {
         log.error("[设备支付取消]订单号{}取消支付，自定义异常:{}", payCancelDTO.getMacOrdId(), var6.getMessage());
         return AjaxResult.error(var6.getCode(), var6.getMessage());
      } catch (Exception var7) {
         log.error("[设备支付取消]订单号{}取消支付，异常:{}", payCancelDTO.getMacOrdId(), var7.getMessage());
         return AjaxResult.error("取消支付失败,请联系管理员");
      }
   }

   @PostMapping({"/ord/pay/cancel/offline"})
//   @RequiresGuest
   @ApiOperation(
      value = "取消支付离线上传",
      notes = "取消支付离线上传-cmt"
   )
   public AjaxResult ordPayCancelOffline(@RequestHeader Map<String, String> headers,
                                         @RequestBody @Valid MacOrdPayCancelDTO payCancelDTO) {
      payCancelDTO.setMachineSn(this.getMachineSnHeaders(headers));

      try {
         String macOrdId = this.macPayNewBusiness.macOrdPayCancelOffline(payCancelDTO);
         log.info("[设备支付取消]离线,处理成功：{}", macOrdId);
         return new AjaxResult(200,"操作成功", macOrdId);
      } catch (ServiceException var5) {
         log.info("[设备支付取消]订单号{}离线,处理自定义异常:{}", payCancelDTO.getMacOrdId(), var5.getMessage());
         return new AjaxResult(200,"操作成功", payCancelDTO.getMacOrdId());
      } catch (Exception var6) {
         log.error("[设备支付取消]订单号{}离线,处理异常:{}", payCancelDTO.getMacOrdId(), var6.getMessage());
         return AjaxResult.error("取消支付失败,请联系管理员");
      }
   }

   @ApiOperation("统一收单离线接口")
   @PostMapping({"/OrdPayMachineOffline"})
//   @RequiresGuest
   public AjaxResult ordOfflineUpload(@RequestHeader Map<String, String> headers,
                                         @RequestBody List<MacPayReceiptOffLineDTO> receiptOffLineDTOList) {
      long start = System.currentTimeMillis();
      String machineSn = this.getMachineSnHeaders(headers);
      String mchNum = this.getMachineNumHeaders(headers);
      Integer sourceType = this.getSourceTypeByHeaders(headers);
      MacPayReceiptOffLineDTO receiptOffLineDTO = (MacPayReceiptOffLineDTO)receiptOffLineDTOList.get(0);
      receiptOffLineDTO.setMachineSn(machineSn);
      receiptOffLineDTO.setMchNum(mchNum);
      receiptOffLineDTO.setSourceType(sourceType);
      receiptOffLineDTO.setRealAmount(receiptOffLineDTO.getAmount());
      receiptOffLineDTO.setOrderType(OrderTypeEnum.ANDROID.getKey());
      receiptOffLineDTO.setIfOnline(MachinePayOnlineEnum.MACHINE_PAY_NO_ONLINE.getKey());
      List<MacPayReceiptOffLineDTO> resultList = Lists.newArrayList();
      MacPayReceiptOffLineDTO offLineDTO = new MacPayReceiptOffLineDTO();
      offLineDTO.setMacOrdId(receiptOffLineDTO.getMacOrdId());
      resultList.add(offLineDTO);

      try {
         this.macPayNewBusiness.ordOfflineUpload(receiptOffLineDTO);
         long end = System.currentTimeMillis();
         log.info("设备收单离线支付,macOrdId:{},总耗时:{}", offLineDTO.getMacOrdId(), end - start);
      } catch (ServiceException var14) {
         this.delRedisKey("Pay_" + receiptOffLineDTO.getMacOrdId());
         log.info("[离线订单]支付macOrdId:{}自定义异常：", receiptOffLineDTO.getMacOrdId(), var14);
         return AjaxResult.success(resultList);
      } catch (Exception var15) {
         this.delRedisKey("Pay_" + receiptOffLineDTO.getMacOrdId());
         log.info("[离线订单]支付macOrdId:{}_异常,异常明细:{}", receiptOffLineDTO.getMacOrdId(), var15.getMessage());
         return AjaxResult.error("支付失败,请联系管理员");
      }

      return AjaxResult.success(resultList);
   }

   @PostMapping({"/supermarket/macOrdPay"})
   @ApiOperation(
      value = "超市设备端下单支付接口",
      notes = "超市设备端下单支付接口"
   )
   public AjaxResult macSupermakertPay(@RequestHeader Map<String, String> headers,
                                                   @RequestBody SupermarketOrdDTO payOrdDTO) {
      payOrdDTO.setSourceType(this.getSourceTypeByHeaders(headers));
      long startTime = System.currentTimeMillis();
      if (payOrdDTO.getMacDate() == null) {
         payOrdDTO.setMacDate(LocalDateTime.now());
      }

      try {
         MacOrdSupermarketPayVO supermarketPayVO = this.macPayNewBusiness.macSupermakertPay(payOrdDTO);
         log.info("[超市下单]返回数据：{},耗时:{}", JSONObject.toJSONString(supermarketPayVO), System.currentTimeMillis() - startTime);
         return supermarketPayVO.getUnpaidBalance() != null && supermarketPayVO.getUnpaidBalance() > 0 ?
                 new AjaxResult(RetCodeEnum.PAY_BALANCE_NO_ENOUGH.getKey(), "操作失败", supermarketPayVO) :
                 AjaxResult.success(supermarketPayVO);
      } catch (ServiceException var8) {
         log.error("[超市下单]订单号{}支付，自定义异常:{}", payOrdDTO.getMacOrdId(), var8.getMessage());
         String leMessage = var8.getMessage();
         if (StrUtil.isBlank(leMessage)) {
            leMessage = I18n.getMessage("order.mac.pay-failed", new Object[0]);
         }

         return AjaxResult.error(var8.getCode(), leMessage);
      } catch (Exception var9) {
         log.error("[超市下单]订单号{}支付异常:{}", payOrdDTO.getMacOrdId(), var9.getMessage());
         this.macPayNewBusiness.macSupermakertBack(payOrdDTO.getMacOrdId());
         return AjaxResult.error("支付失败,请联系管理员");
      }
   }

   @PostMapping({"/supermarket/payResultSelect"})
   @ApiOperation(
      value = "统一收单支付查询接口",
      notes = "统一收单支付查询接口"
   )
   public AjaxResult macSupermakertPaySelect(@RequestHeader Map<String, String> headers,
                                             @RequestBody @Valid SupermarketPayReslutSelectDTO paySelectDTO) {
      log.info("[超市查支付结果]入参：{}", JSONObject.toJSONString(paySelectDTO));
      paySelectDTO.setMachineSn(this.getMachineSnHeaders(headers));

      try {
         MacOrdSupermarketPayVO macOrdPayVO = this.macPayNewBusiness.macSupermakertPaySelect(paySelectDTO);
         return AjaxResult.success(macOrdPayVO);
      } catch (ServiceException var5) {
         log.error("[超市查支付结果]单号{},异常:{}", paySelectDTO.getMacOrdId(), var5.getMessage());
         return AjaxResult.error(var5.getCode(), var5.getMessage());
      } catch (Exception var6) {
         log.error("[超市查支付结果]订单号{},异常:{}", paySelectDTO.getMacOrdId(), var6.getMessage());
         return AjaxResult.error("支付失败,请联系管理员");
      }
   }
}
