package com.bonus.canteen.core.drp.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.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.canteen.core.drp.api.DrpAuthorityApi;
import com.bonus.canteen.core.drp.dto.*;
import com.bonus.canteen.core.drp.mapper.DrpUnitMapper;
import com.bonus.canteen.core.drp.model.DrpUnit;
import com.bonus.canteen.core.drp.service.DrpUnitService;
import com.bonus.canteen.core.drp.vo.DrpUnitListVO;
import com.bonus.canteen.core.drp.vo.DrpUnitPageVO;
import com.bonus.canteen.core.menu.entity.MenuMaterial;
import com.bonus.canteen.core.menu.mapper.MenuMaterialMapper;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.constant.DelFlagEnum;
import com.bonus.common.houqin.i18n.I18n;
import com.bonus.common.houqin.utils.id.Id;
import com.bonus.common.security.utils.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

@Service
public class DrpUnitServiceImpl extends ServiceImpl<DrpUnitMapper, DrpUnit> implements DrpUnitService {
   private static final Logger log = LoggerFactory.getLogger(DrpUnitServiceImpl.class);
   @Resource
   @Lazy
   private MenuMaterialMapper menuMaterialMapper;
   @Resource
   @Lazy
   private DrpAuthorityApi drpAuthorityApi;

   @Override
   public void addDrpUnit(DrpUnitAddDTO content) {
      if (!ObjectUtil.equals(content.getUnitName(), "斤") && !ObjectUtil.equals(content.getUnitName(), "公斤")) {
         List<DrpUnit> unitList = this.baseMapper.selectList(Wrappers.lambdaQuery(DrpUnit.class)
                 .eq(DrpUnit::getUnitName, content.getUnitName()).and((i) -> {
            (i.eq(content.getAreaId() != null, DrpUnit::getAreaId, content.getAreaId())).or()
                    .isNull(DrpUnit::getAreaId);
         }).isNull(content.getAreaId() == null, DrpUnit::getAreaId)
                 .eq(DrpUnit::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
         if (!CollUtil.isEmpty(unitList)) {
            log.info("***[库存中心_基础配置]_新增计量单位_新增的计量单位已存在************");
            throw new ServiceException("drp.unit-name-repeat-add");
         } else if ("KG".equals(content.getUnitName().toUpperCase())) {
            throw new ServiceException("drp.unit-kg-is-exist");
         } else {
            String username = SecurityUtils.getUsername();
            DrpUnit unit = new DrpUnit();
            BeanUtil.copyProperties(content, unit, new String[0]);
            unit.setUnitId(Id.next());
            unit.setCrby(username);
            this.baseMapper.insert(unit);
         }
      } else {
         throw new ServiceException("公斤与斤不可新增");
      }
   }

   @Override
   public Page<DrpUnitPageVO> getDrpUnitPage(DrpUnitPageDTO content) {
      content.setAreaAuth(this.drpAuthorityApi.listAreaAuth());
      Page<DrpUnitPageVO> page = new Page(content.getCurrent(), content.getSize());
      return this.baseMapper.selectAllList(page, content, DelFlagEnum.DEL_FALSE.key());
   }

   @Override
   public void editDrpUnit(DrpUnitEditDTO content) {
      if (!content.getUnitName().equals("公斤") && !content.getUnitName().equals("斤")) {
         List<DrpUnit> unitList = this.baseMapper.selectList(Wrappers.lambdaQuery(DrpUnit.class).eq(DrpUnit::getUnitName, content.getUnitName())
                 .and((i) -> {
            (i.eq(content.getAreaId() != null, DrpUnit::getAreaId, content.getAreaId())).or()
                    .isNull(DrpUnit::getAreaId);
         }).isNull(content.getAreaId() == null, DrpUnit::getAreaId)
                 .eq(DrpUnit::getDelFlag, DelFlagEnum.DEL_FALSE.key())
                 .ne(DrpUnit::getUnitId, content.getUnitId()));
         if (!CollUtil.isEmpty(unitList)) {
            log.info("***[库存中心_基础配置]_修改计量单位_修改的计量单位已存在************");
            throw new ServiceException("drp.unit-name-repeat-update");
         } else {
            String username = SecurityUtils.getUsername();
            DrpUnit unit = new DrpUnit();
            BeanUtil.copyProperties(content, unit, new String[0]);
            unit.setUpby(username);
            this.baseMapper.update(unit,Wrappers.lambdaQuery(DrpUnit.class).eq(DrpUnit::getUnitId, content.getUnitId()));
         }
      } else {
         throw new ServiceException("drp.kg-not-edit");
      }
   }

   @Override
   public void removeByUnitId(Long unitId) {
      if (ObjectUtil.isEmpty(unitId)) {
         log.info("***[库存中心_基础配置]_删除计量单位信息_传入的计量单位id为空************");
         throw new ServiceException(I18n.getMessage("drp.select-delete-unit", new Object[0]));
      } else {
         DrpUnit drpUnit = this.baseMapper.selectOne(Wrappers.lambdaQuery(DrpUnit.class)
                 .eq(DrpUnit::getUnitId, unitId)
                 .select(DrpUnit::getUnitName));
         if (!drpUnit.getUnitName().equals("公斤") && !drpUnit.getUnitName().equals("斤")) {
            Long checkMaterialUnit = this.menuMaterialMapper.selectCount(Wrappers.lambdaQuery(MenuMaterial.class)
                    .eq(MenuMaterial::getUnitId, unitId)
                    .eq(MenuMaterial::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
            if (checkMaterialUnit > 0L) {
               throw new ServiceException("drp.unit-in-material-is-use");
            } else {
               this.baseMapper.update(null, Wrappers.lambdaUpdate(DrpUnit.class)
                       .eq(DrpUnit::getUnitId, unitId)
                       .set(DrpUnit::getDelFlag, DelFlagEnum.DEL_TRUE.key()));
            }
         } else {
            throw new ServiceException("drp.kg-not-delete");
         }
      }
   }

   @Override
   public BigDecimal conversionUnit(ConversionUnitDTO content) {
      DrpUnit oldUnit = this.baseMapper.selectOne(Wrappers.lambdaQuery(DrpUnit.class)
              .eq(DrpUnit::getUnitId, content.getOldUnitId()));
      DrpUnit newUnit = this.baseMapper.selectOne(Wrappers.lambdaQuery(DrpUnit.class)
              .eq(DrpUnit::getUnitId, content.getNewUntiId()));
      BigDecimal oldRate = oldUnit.getRate();
      BigDecimal newRate = newUnit.getRate();
      return content.getNumber().multiply(oldRate).divide(newRate, 10, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP);
   }

   @Override
   public List<DrpUnitListVO> listUnitAll(DrpUnitListDTO content) {
      List<Long> areaAuth = this.drpAuthorityApi.listAreaAuth();
      content.setAreaAuth(areaAuth);
      return this.baseMapper.listUnitAll(content, DelFlagEnum.DEL_FALSE.key());
   }
}
