package com.bonus.canteen.core.notice.print.v2.business.impl;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.bonus.canteen.core.device.manage.dto.DeviceDTO;
import com.bonus.canteen.core.device.manage.vo.DeviceInfoVO;
import com.bonus.canteen.core.notice.print.v2.business.NoticePrinterBusiness;
import com.bonus.canteen.core.notice.print.v2.constant.PrintConstants;
import com.bonus.canteen.core.notice.print.v2.model.NoticePrintRecord;
import com.bonus.canteen.core.notice.print.v2.model.NoticePrintTemplate;
import com.bonus.canteen.core.notice.print.v2.po.PrintResponsePO;
import com.bonus.canteen.core.notice.print.v2.service.NoticePrintRecordService;
import com.bonus.canteen.core.notice.print.v2.service.NoticePrintTemplateService;
import com.bonus.canteen.core.notice.print.v2.service.NoticePrintTemplateSettingService;
import com.bonus.canteen.core.notice.print.v2.utils.NoticePrintTransformUtil;
import com.bonus.canteen.core.notice.print.v2.vo.NoticePrintTemplateSettingVO;
import com.bonus.canteen.core.order.api.vo.NoticePrintDetailVO;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.constant.LeConstants;
import com.bonus.common.houqin.utils.id.Id;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;

import java.lang.invoke.SerializedLambda;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public abstract class NoticePrinterAbstractBusiness implements NoticePrinterBusiness {
   private static final Logger log = LoggerFactory.getLogger(NoticePrinterAbstractBusiness.class);
   @Autowired
   @Lazy
   private NoticePrintTemplateSettingService noticePrintTemplateSettingService;
   @Autowired
   @Lazy
   private NoticePrintRecordService noticePrintRecordService;
   @Autowired
   @Lazy
   private NoticePrintTemplateService noticePrintTemplateService;
   @Autowired
   @Lazy
   protected NoticePrintBurialPointBusiness noticePrintBurialPointBusiness;
   @Value("${system.print.bold-column:}")
   protected String boldColumns;

   public void printByParamAndTemplateId(DeviceInfoVO deviceInfoVO, Long busId, String printType, Long templateId, Map<String, String> paramMap) {
      this.printByParamAndTemplateId(deviceInfoVO, busId, printType, templateId, paramMap, 1);
   }

   public void printByParamAndTemplateId(DeviceInfoVO deviceInfoVO, Long busId, String printType, Long templateId, Map<String, String> paramMap, int times) {
      log.info("【模版打印】打印机id:{},业务id:{},打印类型:{},打印参数:{},打印模版id:{},打印次数:{}", new Object[]{deviceInfoVO.getDeviceId(), busId, printType, JSON.toJSONString(paramMap), templateId, times});

      for(int i = 0; i < times; ++i) {
         NoticePrintRecord noticePrintRecord = new NoticePrintRecord();
         noticePrintRecord.setRecordId(Id.next()).setDeviceId(deviceInfoVO.getDeviceId()).setDeviceName(deviceInfoVO.getDeviceName()).setDeviceSn(deviceInfoVO.getDeviceSn()).setBusId(busId).setPrintType(printType).setIfSuccess(0);

         try {
            List<NoticePrintTemplateSettingVO> settingList = this.noticePrintTemplateSettingService.getTemplateSettingList(templateId);
            if (ObjectUtil.isEmpty(settingList)) {
               throw new ServiceException("打印模版未配置打印参数");
            }

            PrintResponsePO responsePO = this.executePrint(paramMap, settingList, deviceInfoVO.getDeviceSn(), deviceInfoVO.getDeviceIp(), noticePrintRecord.getRecordId());
            if (!ObjectUtil.equal(responsePO.getRet(), PrintConstants.PRINT_RESPONSE_SUCCESS_RET)) {
               noticePrintRecord.setMsg(responsePO.getMsg());
               noticePrintRecord.setIfSuccess(LeConstants.COMMON_NO);
               throw new ServiceException("打印失败---------------");
            }

            noticePrintRecord.setDataId(responsePO.getData());
            noticePrintRecord.setIfSuccess(LeConstants.COMMON_YES);
            this.noticePrintRecordService.save(noticePrintRecord);
         } catch (Exception var11) {
            log.info("【模版打印】业务id:{}-打印失败：{}", new Object[]{busId, var11.getMessage(), var11});
            noticePrintRecord.setIfSuccess(LeConstants.COMMON_NO);
            noticePrintRecord.setMsg(var11.getMessage());
            this.noticePrintRecordService.save(noticePrintRecord);
            throw new ServiceException("打印失败---------------");
         }
      }

   }

   protected PrintResponsePO executePrint(Map<String, String> paramMap, List<NoticePrintTemplateSettingVO> settingList, String sn, String ip, Long recordId) throws Exception {
      return PrintResponsePO.getFailPO("不支持该打印类型");
   }

   public void setPrinterSize(DeviceDTO deviceDTO) {
      log.info("{}不支持打印大小设置", "");
   }

   protected boolean checkBoldColumns(NoticePrintTemplateSettingVO setting) {
      if (ObjectUtil.equal(LeConstants.COMMON_YES, setting.getIfBold())) {
         return true;
      } else {
         return CharSequenceUtil.isBlank(this.boldColumns) ? false : this.boldColumns.contains(setting.getColumnValue() + ",");
      }
   }

   protected String getTemplateSize(DeviceDTO deviceDTO) {
      Map<String, Object> metadata = deviceDTO.getMetadata();
      if (ObjectUtil.isEmpty(metadata)) {
         return null;
      } else {
         String templateId = String.valueOf(metadata.get("canteenOrderTemplateId"));
         if (ObjectUtil.isEmpty(templateId)) {
            return null;
         } else {
            NoticePrintTemplate noticePrintTemplate = (NoticePrintTemplate)this.noticePrintTemplateService.
                    getOne(Wrappers.lambdaQuery(NoticePrintTemplate.class).select(NoticePrintTemplate::getTemplateSize)
                            .eq(NoticePrintTemplate::getTemplateId, templateId));
            return ObjectUtil.isNull(noticePrintTemplate) ? null : noticePrintTemplate.getTemplateSize();
         }
      }
   }

   protected String getDetailTotalPrice(NoticePrintDetailVO ordDetail) {
      BigDecimal total = NumberUtil.mul(ordDetail.getPrice(), ordDetail.getQuantity());
      if (ObjectUtil.notEqual(ordDetail.getSalesMode(), 2)) {
         return NoticePrintTransformUtil.transformAmountYuan(total);
      } else {
         Integer weightUnit = (Integer)Optional.ofNullable(ordDetail.getWeightUnit()).orElse(100);
         return NoticePrintTransformUtil.transformAmountYuan(NumberUtil.div(total, weightUnit));
      }
   }
}
