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

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.bonus.canteen.core.common.thirdutils.feie.FeiePrint;
import com.bonus.canteen.core.common.thirdutils.feie.FeiePrintResponse;
import com.bonus.canteen.core.device.manage.dto.DeviceDTO;
import com.bonus.canteen.core.notice.print.v2.constant.PrintColumnTypeEnum;
import com.bonus.canteen.core.notice.print.v2.po.PrintResponsePO;
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.canteen.core.order.api.vo.NoticePrintNutritionVO;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.constant.LeConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Service
public class NoticePrinterFeiELabelBusiness extends NoticePrinterAbstractBusiness {
   @Autowired
   @Lazy
   private FeiePrint feiePrint;

   public Integer getPrintStatus(String sn, String ip) {
      return this.feiePrint.queryPrinterStatus(sn);
   }

   protected PrintResponsePO executePrint(Map<String, String> paramMap, List<NoticePrintTemplateSettingVO> settingList, String sn, String ip, Long recordId) {
      String size = (String)paramMap.get("printSize");
      if (ObjectUtil.isEmpty(size)) {
         size = "40,30";
      }

      StringBuilder sb = new StringBuilder();
      sb.append("<DIRECTION>").append(LeConstants.COMMON_YES).append("</DIRECTION>");
      String finalSize = size;
      settingList.forEach((setting) -> {
         PrintColumnTypeEnum printColumnTypeEnum = PrintColumnTypeEnum.getPrintColumnTypeEnum(setting.getColumnType());
         if (ObjectUtil.isNull(printColumnTypeEnum)) {
            printColumnTypeEnum = PrintColumnTypeEnum.TEXT;
         }

         String paramValue = NoticePrintTransformUtil.getSettingParamValue(setting, paramMap);
         if (!ObjectUtil.isEmpty(paramValue)) {
            if (this.noticePrintBurialPointBusiness.checkSpecialPrintColumn(setting)) {
               this.noticePrintBurialPointBusiness.didFeieLabelSpecialPrintColumn(setting, paramValue, sb);
            } else {
               switch (printColumnTypeEnum) {
                  case TEXT:
                     this.addText(sb, setting, paramValue);
                     break;
                  case TEXT_ARRAY:
                     this.addArray(sb, finalSize, setting, paramValue);
                     break;
                  case QR:
                     String qr = NoticePrintTransformUtil.getOrderQRCode((String)paramMap.get("sourceType"), paramValue);
                     this.addQr(sb, setting, qr);
               }

            }
         }
      });
      FeiePrintResponse print = this.feiePrint.printLabelMsg(sn, sb.toString(), "1");
      if (ObjectUtil.isNull(print)) {
         throw new ServiceException("飞鹅打印未响应");
      } else {
         return print.isSuccess() ? PrintResponsePO.getSuccessPO(print.getData()) : PrintResponsePO.getFailPO(print.getMsg());
      }
   }

   private void addText(StringBuilder sb, NoticePrintTemplateSettingVO setting, String paramValue) {
      this.addText(sb, setting.getSettingX(), setting.getSettingY(), setting.getSettingW(), setting.getSettingH(), paramValue);
   }

   private void addText(StringBuilder sb, Integer x, Integer y, Integer w, Integer h, String paramValue) {
      sb.append("<TEXT x='").append(x).append("' y='").append(y).append("' font='12' w='").append(w).append("' h='").append(h).append("' r='0'>").append(paramValue).append("</TEXT>");
   }

   private void addArray(StringBuilder sb, String size, NoticePrintTemplateSettingVO setting, String paramValue) {
      Integer x = setting.getSettingX();
      Integer y = setting.getSettingY();
      Integer w = setting.getSettingW();
      Integer h = setting.getSettingH();
      String[] sizeArr = size.split(",");
      int paperHeight = NumberUtil.mul(new BigDecimal(sizeArr[1]), BigDecimal.valueOf(8L)).intValue();
      if (ObjectUtil.equal("canteenDishesList", setting.getColumnValue())) {
         this.addDishesList(sb, x, y, w, h, paperHeight, paramValue);
      } else if (ObjectUtil.equal("nutritionList", setting.getColumnValue())) {
         this.addNutritionList(sb, x, y, w, h, paramValue);
      }

   }

   private void addDishesList(StringBuilder sb, Integer x, Integer y, Integer w, Integer h, Integer paperHeight, String paramValue) {
      List<NoticePrintDetailVO> ordDetailList = JSON.parseArray(paramValue, NoticePrintDetailVO.class);

      for(Iterator var9 = ordDetailList.iterator(); var9.hasNext(); y = y + 24) {
         NoticePrintDetailVO printOrdDetail = (NoticePrintDetailVO)var9.next();
         if (y + 24 > paperHeight) {
            break;
         }

         String goodsName = printOrdDetail.getGoodsDishesName().length() > 5 ? printOrdDetail.getGoodsDishesName().substring(0, 5) + "..." : printOrdDetail.getGoodsDishesName();
         this.addText(sb, x, y, w, h, goodsName);
         this.addText(sb, x + 132, y, w, h, "*" + printOrdDetail.getQuantity());
      }

   }

   private void addNutritionList(StringBuilder sb, Integer x, Integer y, Integer w, Integer h, String paramValue) {
      NoticePrintNutritionVO nutritionVO = (NoticePrintNutritionVO)JSON.parseObject(paramValue, NoticePrintNutritionVO.class);
      Double calories = ObjectUtil.isNotNull(nutritionVO.getCalories()) ? nutritionVO.getCalories() : 0.0;
      Double protein = ObjectUtil.isNotNull(nutritionVO.getProtein()) ? nutritionVO.getProtein() : 0.0;
      Double fat = ObjectUtil.isNotNull(nutritionVO.getFat()) ? nutritionVO.getFat() : 0.0;
      Double carbohydrate = ObjectUtil.isNotNull(nutritionVO.getCarbohydrate()) ? nutritionVO.getCarbohydrate() : 0.0;
      Double dietaryFiber = ObjectUtil.isNotNull(nutritionVO.getDietaryFiber()) ? nutritionVO.getDietaryFiber() : 0.0;
      Double cholesterol = ObjectUtil.isNotNull(nutritionVO.getCholesterol()) ? nutritionVO.getCholesterol() : 0.0;
      this.addText(sb, x, y, w, h, NoticePrintTransformUtil.getNutritionValue("notice_print_nutrition_calories", String.valueOf(calories), "kj"));
      this.addText(sb, x + 144, y, w, h, NoticePrintTransformUtil.getNutritionValue("notice_print_nutrition_protein", String.valueOf(protein), "g"));
      y = y + 24;
      this.addText(sb, x, y, w, h, NoticePrintTransformUtil.getNutritionValue("notice_print_nutrition_fat", String.valueOf(fat), "g"));
      this.addText(sb, x + 144, y, w, h, NoticePrintTransformUtil.getNutritionValue("notice_print_nutrition_carbohydrate", String.valueOf(carbohydrate), "g"));
      y = y + 24;
      this.addText(sb, x, y, w, h, NoticePrintTransformUtil.getNutritionValue("notice_print_nutrition_dietary_fiber", String.valueOf(dietaryFiber), "g"));
      this.addText(sb, x + 144, y, w, h, NoticePrintTransformUtil.getNutritionValue("notice_print_nutrition_cholesterol", String.valueOf(cholesterol), "g"));
   }

   private void addQr(StringBuilder sb, NoticePrintTemplateSettingVO setting, String paramValue) {
      sb.append("<QR x='").append(setting.getSettingX()).append("' y='").append(setting.getSettingY()).append("'").append("' e='L' w='5'>").append(paramValue).append("</QR>");
   }

   public void setPrinterSize(DeviceDTO deviceDTO) {
      String templateSize = super.getTemplateSize(deviceDTO);
      if (!ObjectUtil.isEmpty(templateSize)) {
         String sizeStr = "<SIZE>" + templateSize + "</SIZE>";
         this.feiePrint.printLabelMsg(deviceDTO.getDeviceSn(), sizeStr, "1");
      }
   }
}
