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.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.canteen.core.notice.print.v2.constant.PrinterDeviceTypeEnum;
import com.bonus.canteen.core.notice.print.v2.dto.NoticePrintSceneTemplateDTO;
import com.bonus.canteen.core.notice.print.v2.dto.NoticePrintTemplateAddDTO;
import com.bonus.canteen.core.notice.print.v2.dto.NoticePrintTemplateUpdateDTO;
import com.bonus.canteen.core.notice.print.v2.mapper.NoticePrintTemplateMapper;
import com.bonus.canteen.core.notice.print.v2.model.NoticePrintTemplate;
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.vo.NoticePrintSceneTemplateVO;
import com.bonus.canteen.core.notice.print.v2.vo.NoticePrintTemplateSettingVO;
import com.bonus.canteen.core.notice.print.v2.vo.NoticePrintTemplateVO;
import com.bonus.canteen.core.notice.print.v2.vo.NoticePrintTypeTemplateVO;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.constant.DelFlagEnum;
import com.bonus.common.houqin.constant.LeConstants;
import com.bonus.common.houqin.i18n.I18n;
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.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.invoke.SerializedLambda;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class NoticePrintTemplateServiceImpl extends ServiceImpl<NoticePrintTemplateMapper, NoticePrintTemplate> implements NoticePrintTemplateService {
   private static final Logger log = LoggerFactory.getLogger(NoticePrintTemplateServiceImpl.class);
   @Autowired
   @Lazy
   private NoticePrintTemplateSettingService noticePrintTemplateSettingService;

   public Map<String, List<NoticePrintTemplateVO>> findPrintTemplateListByPrintModel(String printModel) {
      PrinterDeviceTypeEnum typeEnum = PrinterDeviceTypeEnum.getPrinterDeviceType(printModel);
      if (ObjectUtil.isNull(typeEnum)) {
         log.info("错误的设备类型");
         return MapUtil.newHashMap();
      } else {
         List<NoticePrintTemplateVO> templateList = ((NoticePrintTemplateMapper)this.baseMapper).getPrintTemplateListByDeviceType(typeEnum.getKey(), DelFlagEnum.DEL_FALSE.key());
         if (ObjectUtil.isEmpty(templateList)) {
            return MapUtil.newHashMap();
         } else {
            Map<String, List<NoticePrintTemplateVO>> templateMap = templateList.stream()
                    .collect(Collectors.groupingBy(NoticePrintTemplateVO::getPrintType));
            templateMap.values().forEach((typeTemplateList) -> {
               typeTemplateList.sort(Comparator.comparing(NoticePrintTemplateVO::getIfDefault)
                       .thenComparing(NoticePrintTemplateVO::getUptime));
            });
            return templateMap;
         }
      }
   }

   public List<NoticePrintSceneTemplateVO> getNoticePrintSceneTemplateList(NoticePrintSceneTemplateDTO content) {
      List<NoticePrintTemplateVO> templateList = ((NoticePrintTemplateMapper)this.baseMapper).getNoticePrintTemplateListByScene(content, DelFlagEnum.DEL_FALSE.key());
      if (ObjectUtil.isEmpty(templateList)) {
         return CollUtil.newArrayList(new NoticePrintSceneTemplateVO[0]);
      } else {
         List<NoticePrintSceneTemplateVO> result = CollUtil.newArrayList(new NoticePrintSceneTemplateVO[0]);
         Map<String, List<NoticePrintTemplateVO>> sceneTemplateMap = templateList.stream().collect(Collectors.groupingBy(NoticePrintTemplateVO::getPrintScene));
         Iterator var5 = sceneTemplateMap.entrySet().iterator();

         while(var5.hasNext()) {
            Map.Entry<String, List<NoticePrintTemplateVO>> sceneEntry = (Map.Entry)var5.next();
            NoticePrintSceneTemplateVO sceneTemplateVO = new NoticePrintSceneTemplateVO();
            sceneTemplateVO.setDeviceType(content.getDeviceType());
            sceneTemplateVO.setPrintScene((String)sceneEntry.getKey());
            List<NoticePrintTypeTemplateVO> typeTemplateList = CollUtil.newArrayList(new NoticePrintTypeTemplateVO[0]);
            Map<String, List<NoticePrintTemplateVO>> typeTemplateMap = (Map)((List)sceneEntry.getValue()).stream().collect(Collectors.groupingBy(NoticePrintTemplateVO::getPrintType));
            Iterator var10 = typeTemplateMap.entrySet().iterator();

            while(var10.hasNext()) {
               Map.Entry<String, List<NoticePrintTemplateVO>> typeEntry = (Map.Entry)var10.next();
               NoticePrintTypeTemplateVO typeTemplateVO = new NoticePrintTypeTemplateVO();
               typeTemplateVO.setDeviceType(content.getDeviceType());
               typeTemplateVO.setPrintScene((String)sceneEntry.getKey());
               typeTemplateVO.setPrintType((String)typeEntry.getKey());
               ((List)typeEntry.getValue()).sort(Comparator.comparing(NoticePrintTemplateVO::getIfDefault).thenComparing(NoticePrintTemplateVO::getUptime, Comparator.reverseOrder()));
               typeTemplateVO.setTemplateList((List)typeEntry.getValue());
               typeTemplateList.add(typeTemplateVO);
            }

            typeTemplateList.sort(Comparator.comparing(NoticePrintTypeTemplateVO::getPrintType));
            sceneTemplateVO.setTemplateList(typeTemplateList);
            result.add(sceneTemplateVO);
         }

         result.sort(Comparator.comparing(NoticePrintSceneTemplateVO::getPrintScene));
         return result;
      }
   }

   @Transactional(
      rollbackFor = {Exception.class}
   )
   public void addNoticePrintTemplate(NoticePrintTemplateAddDTO content) {
      Long templateId = Id.next();
      NoticePrintTemplate template = new NoticePrintTemplate();
      BeanUtil.copyProperties(content, template, new String[0]);
      template.setTemplateId(templateId);
      this.save(template);
      this.noticePrintTemplateSettingService.addNoticePrintTemplateSetting(templateId, content.getSettingList(), content.getDeviceType());
   }

   @Transactional(
      rollbackFor = {Exception.class}
   )
   public void updateNoticePrintTemplate(NoticePrintTemplateUpdateDTO content) {
      NoticePrintTemplate oldTemplate = this.getOne(Wrappers.lambdaQuery(NoticePrintTemplate.class)
              .select(NoticePrintTemplate::getTemplateId, NoticePrintTemplate::getIfDefault)
              .eq(NoticePrintTemplate::getTemplateId, content.getTemplateId()));
      if (!ObjectUtil.isNull(oldTemplate) && !ObjectUtil.isNull(oldTemplate.getTemplateId())) {
         if (ObjectUtil.equal(LeConstants.COMMON_YES, oldTemplate.getIfDefault())) {
            throw new ServiceException(I18n.getMessage("notice_print_template_update_default_null", new Object[0]));
         } else {
            NoticePrintTemplate template = new NoticePrintTemplate();
            BeanUtil.copyProperties(content, template);
            this.updateById(template);
            this.noticePrintTemplateSettingService.updateNoticePrintTemplateSetting(content.getTemplateId(), content.getSettingList(), content.getDeviceType());
         }
      } else {
         throw new ServiceException(I18n.getMessage("notice_print_template_id_is_null", new Object[0]));
      }
   }

   public NoticePrintTemplateVO getNoticePrintTemplateVO(Long templateId) {
      NoticePrintTemplateVO template = ((NoticePrintTemplateMapper)this.baseMapper).getNoticePrintTemplateByTemplateId(templateId);
      if (ObjectUtil.isNull(template)) {
         return null;
      } else {
         List<NoticePrintTemplateSettingVO> settingList = this.noticePrintTemplateSettingService.getTemplateSettingList(templateId);
         template.setSettingList(settingList);
         return template;
      }
   }

   public void deleteNoticePrintTemplate(Long templateId) {
      NoticePrintTemplate oldTemplate = this.getOne(Wrappers.lambdaQuery(NoticePrintTemplate.class)
              .select(NoticePrintTemplate::getTemplateId, NoticePrintTemplate::getIfDefault)
              .eq(NoticePrintTemplate::getTemplateId, templateId));
      if (!ObjectUtil.isNull(oldTemplate) && !ObjectUtil.isNull(oldTemplate.getTemplateId())) {
         if (ObjectUtil.equal(LeConstants.COMMON_YES, oldTemplate.getIfDefault())) {
            throw new ServiceException(I18n.getMessage("notice_print_template_delete_default_null", new Object[0]));
         } else {
            this.update((Wrappers.lambdaUpdate(NoticePrintTemplate.class).set(NoticePrintTemplate::getDelFlag,
                    DelFlagEnum.DEL_TRUE.key())).eq(NoticePrintTemplate::getTemplateId, templateId));
         }
      } else {
         throw new ServiceException(I18n.getMessage("notice_print_template_id_is_null", new Object[0]));
      }
   }
}
