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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.canteen.core.notice.print.v2.constant.PrintTemplateExtSettingTypeEnum;
import com.bonus.canteen.core.notice.print.v2.constant.PrinterDeviceTypeEnum;
import com.bonus.canteen.core.notice.print.v2.dto.NoticePrintTemplateSettingAddDTO;
import com.bonus.canteen.core.notice.print.v2.mapper.NoticePrintTemplateExtSettingMapper;
import com.bonus.canteen.core.notice.print.v2.mapper.NoticePrintTemplateSettingMapper;
import com.bonus.canteen.core.notice.print.v2.model.NoticePrintTemplateExtSetting;
import com.bonus.canteen.core.notice.print.v2.model.NoticePrintTemplateSetting;
import com.bonus.canteen.core.notice.print.v2.service.NoticePrintTemplateExtSettingService;
import com.bonus.canteen.core.notice.print.v2.service.NoticePrintTemplateSettingService;
import com.bonus.canteen.core.notice.print.v2.vo.NoticePrintTemplateSettingVO;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.i18n.I18n;
import com.bonus.common.houqin.utils.id.Id;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.invoke.SerializedLambda;
import java.util.List;

@Service
public class NoticePrintTemplateSettingServiceImpl extends ServiceImpl<NoticePrintTemplateSettingMapper, NoticePrintTemplateSetting> implements NoticePrintTemplateSettingService {
   @Autowired
   @Lazy
   private NoticePrintTemplateExtSettingService noticePrintTemplateExtSettingService;
   @Autowired
   @Lazy
   private NoticePrintTemplateExtSettingMapper noticePrintTemplateExtSettingMapper;

   @Transactional(
      rollbackFor = {Exception.class}
   )
   public void addNoticePrintTemplateSetting(Long templateId, List<NoticePrintTemplateSettingAddDTO> settingList, Integer deviceType) {
      this.checkSettingColumnId(settingList, deviceType);
      List<NoticePrintTemplateSetting> saveSettingList = CollUtil.newArrayList(new NoticePrintTemplateSetting[0]);
      List<NoticePrintTemplateExtSetting> saveExtSettingList = CollUtil.newArrayList(new NoticePrintTemplateExtSetting[0]);
      settingList.forEach((settingAddDTO) -> {
         NoticePrintTemplateSetting setting = new NoticePrintTemplateSetting();
         Long settingId = Id.next();
         setting.setSettingId(settingId).setTemplateId(templateId).setColumnId(settingAddDTO.getColumnId()).setSort(settingAddDTO.getSort()).setIfBold(settingAddDTO.getIfBold());
         saveSettingList.add(setting);
         if (ObjectUtil.equal(deviceType, PrinterDeviceTypeEnum.LABEL_PRINTER.getKey())) {
            NoticePrintTemplateExtSetting extSetting = new NoticePrintTemplateExtSetting();
            BeanUtil.copyProperties(settingAddDTO.getExtDTO(), extSetting, new String[0]);
            extSetting.setSettingId(settingId).setTemplateId(templateId);
            saveExtSettingList.add(extSetting);
         }

      });
      super.saveBatch(saveSettingList);
      if (ObjectUtil.isNotEmpty(saveExtSettingList)) {
         this.noticePrintTemplateExtSettingService.saveBatch(saveExtSettingList);
      }

   }

   private void checkSettingColumnId(List<NoticePrintTemplateSettingAddDTO> settingList, Integer deviceType) {
      if (ObjectUtil.equal(deviceType, PrinterDeviceTypeEnum.LABEL_PRINTER.getKey())) {
         settingList.forEach((setting) -> {
            if (ObjectUtil.isNull(setting.getExtDTO())) {
               throw new ServiceException(I18n.getMessage("notice_print_template_setting_ext_is_null"));
            } else if (ObjectUtil.isNull(setting.getColumnId()) && ObjectUtil.equal(setting.getExtDTO().getSettingType(),
                    PrintTemplateExtSettingTypeEnum.DYNAMIC.getKey())) {
               throw new ServiceException(I18n.getMessage("notice_print_template_setting_is_null"));
            }
         });
      } else {
         settingList.forEach((setting) -> {
            if (ObjectUtil.isNull(setting.getColumnId())) {
               throw new ServiceException(I18n.getMessage("notice_print_template_setting_is_null", new Object[0]));
            }
         });
      }

   }

   @Transactional(
      rollbackFor = {Exception.class}
   )
   public void updateNoticePrintTemplateSetting(Long templateId, List<NoticePrintTemplateSettingAddDTO> settingList, Integer deviceType) {
      this.deleteNoticePrintTemplateSetting(templateId, deviceType);
      this.addNoticePrintTemplateSetting(templateId, settingList, deviceType);
   }

   public void deleteNoticePrintTemplateSetting(Long templateId, Integer deviceType) {
      ((NoticePrintTemplateSettingMapper)this.baseMapper).delete(Wrappers.lambdaQuery(NoticePrintTemplateSetting.class).eq(NoticePrintTemplateSetting::getTemplateId, templateId));
      if (ObjectUtil.equal(deviceType, PrinterDeviceTypeEnum.LABEL_PRINTER.getKey())) {
         this.noticePrintTemplateExtSettingMapper.delete(Wrappers.lambdaQuery(NoticePrintTemplateExtSetting.class).eq(NoticePrintTemplateExtSetting::getTemplateId, templateId));
      }

   }

   public List<NoticePrintTemplateSettingVO> getTemplateSettingList(Long templateId) {
      return ((NoticePrintTemplateSettingMapper)this.baseMapper).getTemplateSettingList(templateId);
   }

   public List<NoticePrintTemplateSettingVO> getTemplateSettingList(List<Long> templateIdList) {
      return ((NoticePrintTemplateSettingMapper)this.baseMapper).getTemplateSettingListByTemplateIdList(templateIdList);
   }
}
