package com.bonus.canteen.core.menu.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.canteen.core.menu.dto.CategoryTreeListDTO;
import com.bonus.canteen.core.menu.dto.MenuMaterialCategoryAddDTO;
import com.bonus.canteen.core.menu.enums.MgrRoleTypeEnum;
import com.bonus.canteen.core.menu.enums.RoleCodeEnum;
import com.bonus.canteen.core.menu.vo.MenuCategoryTreeVO;
import com.bonus.canteen.core.menu.enums.LeLevelEnum;
import com.bonus.canteen.core.utils.BnsConstants;
import com.bonus.canteen.core.utils.TreeNodeUtil;
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 com.bonus.common.security.utils.SecurityUtils;
import com.bonus.system.api.model.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bonus.canteen.core.menu.mapper.MenuMaterialCategoryMapper;
import com.bonus.canteen.core.menu.domain.MenuMaterialCategory;
import com.bonus.canteen.core.menu.service.IMenuMaterialCategoryService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 原料类别Service业务层处理
 *
 * @author xsheng
 * @date 2025-04-03
 */
@Service
public class MenuMaterialCategoryServiceImpl extends ServiceImpl<MenuMaterialCategoryMapper, MenuMaterialCategory> implements IMenuMaterialCategoryService {
    @Autowired
    private MenuMaterialCategoryMapper menuMaterialCategoryMapper;

    /**
     * 查询原料类别
     *
     * @param id 原料类别主键
     * @return 原料类别
     */
    @Override
    public MenuMaterialCategory selectMenuMaterialCategoryById(Long id) {
        return menuMaterialCategoryMapper.selectMenuMaterialCategoryById(id);
    }

    /**
     * 查询原料类别列表
     *
     * @param menuMaterialCategory 原料类别
     * @return 原料类别
     */
    @Override
    public List<MenuMaterialCategory> selectMenuMaterialCategoryList(MenuMaterialCategory menuMaterialCategory) {
        return menuMaterialCategoryMapper.selectMenuMaterialCategoryList(menuMaterialCategory);
    }

    /**
     * 新增原料类别
     *
     * @param content 原料类别
     * @return 结果
     */
    @Override
    public int insertMenuMaterialCategory(MenuMaterialCategoryAddDTO content) {
        try {
            int num = 0;
            Long count = this.baseMapper.selectCount(Wrappers.lambdaQuery(MenuMaterialCategory.class)
                    .eq(MenuMaterialCategory::getCategoryName, content.getCategoryName())
                    .eq(content.getAreaId() != null, MenuMaterialCategory::getAreaId,content.getAreaId())
                    .isNull(content.getAreaId() == null, MenuMaterialCategory::getAreaId));
            if (ObjectUtil.isNotNull(count) && count > 0L) {
                throw new ServiceException("添加物品已存在");
            } else {
                Long parentId = content.getParentId();
                if (ObjectUtil.isNotNull(parentId) && parentId != -1L) {
                    Long countParent = this.baseMapper.selectCount(Wrappers.lambdaQuery(MenuMaterialCategory.class)
                            .eq(MenuMaterialCategory::getCategoryId, parentId));
                    if (ObjectUtil.isNull(countParent) || countParent <= 0L) {
                        throw new ServiceException("菜单无父级节点");
                    }
                }

                String username = SecurityUtils.getUsername();
                MenuMaterialCategory materialCategory = new MenuMaterialCategory();
                BeanUtil.copyProperties(content, materialCategory, new String[0]);
                materialCategory.setCategoryId(Id.next());
                materialCategory.setCreateBy(username);
                this.syncAllCategoryBigCategoryAndLevel();
                MenuMaterialCategory parentCategory = this.baseMapper.selectOne(
                        Wrappers.lambdaQuery(MenuMaterialCategory.class)
                                .eq(MenuMaterialCategory::getCategoryId, content.getParentId())
                                .select(MenuMaterialCategory::getCategoryId, MenuMaterialCategory::getLevel,
                                        MenuMaterialCategory::getBigCategoryId));
                materialCategory.setLevel(parentCategory.getLevel() + 1);
                materialCategory.setBigCategoryId(parentCategory.getBigCategoryId());
                num =  this.baseMapper.insert(materialCategory);
             //   MqUtil.pushToTenantAllDevice(materialCategory, LeMqConstant.Topic.DRP_SYNC_MATERIAL_BIG_CATEGORY);
                this.generateCategoryNum(materialCategory.getCategoryId(), materialCategory.getParentId(), materialCategory.getCategoryType());

            }
            //return menuMaterialCategoryMapper.insertMenuMaterialCategory(menuMaterialCategory);
            return num;
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    @Override
    public void generateCategoryNum(Long categoryId, Long parentId, Integer categoryType) {
        MenuMaterialCategory parentCategory = this.baseMapper.selectOne(Wrappers.lambdaQuery(MenuMaterialCategory.class)
                .eq(MenuMaterialCategory::getCategoryId, parentId)
                .eq(MenuMaterialCategory::getCategoryType, categoryType)
               // .eq(MenuMaterialCategory::getDelFlag, DelFlagEnum.DEL_FALSE.key())
                .select(MenuMaterialCategory::getCategoryId, MenuMaterialCategory::getParentId,
                        MenuMaterialCategory::getCategoryNum));
        if (ObjectUtil.isNotEmpty(parentCategory)) {
            if (CharSequenceUtil.isNotEmpty(parentCategory.getCategoryNum())) {
                String maxCategoryNum = this.baseMapper.getCategoryChildMaxNum(parentCategory.getCategoryId(), categoryType,
                        DelFlagEnum.DEL_FALSE.key());
                String categoryNum = "";
                if (CharSequenceUtil.isNotEmpty(maxCategoryNum)) {
                    String lastStr = maxCategoryNum.substring(maxCategoryNum.lastIndexOf("-") + 1);
                    String lastNum = String.format("%02d", Integer.parseInt(lastStr) + 1);
                    String var10000 = parentCategory.getCategoryNum();
                    categoryNum = var10000 + "-" + lastNum;
                } else {
                    categoryNum = parentCategory.getCategoryNum() + "-01";
                }

                this.baseMapper.update(null, Wrappers.lambdaUpdate(MenuMaterialCategory.class)
                        .eq(MenuMaterialCategory::getCategoryId, categoryId)
                        .set(MenuMaterialCategory::getCategoryNum, categoryNum));
            } else {
                this.generateCategoryNum(parentCategory.getCategoryId(), parentCategory.getParentId(), categoryType);
            }
        } else {
            this.baseMapper.update(null,Wrappers.lambdaUpdate(MenuMaterialCategory.class)
                    .eq(MenuMaterialCategory::getParentId, -1).eq(MenuMaterialCategory::getCategoryType, categoryType)
                    .set(MenuMaterialCategory::getCategoryNum, categoryType));
        }

        MenuMaterialCategory menuMaterialCategory = this.baseMapper.selectOne(Wrappers.lambdaQuery(MenuMaterialCategory.class)
                .eq(MenuMaterialCategory::getCategoryId, categoryId)
                //.eq(MenuMaterialCategory::getDelFlag, DelFlagEnum.DEL_FALSE.key())
                .select(MenuMaterialCategory::getCategoryNum));
        if (!ObjectUtil.isNotEmpty(menuMaterialCategory) || !CharSequenceUtil.isNotEmpty(menuMaterialCategory.getCategoryNum())) {
            this.generateCategoryNum(categoryId, parentId, categoryType);
        }
    }

    @Override
    public void syncAllCategoryBigCategoryAndLevel() {
        Long checkIfExistLevel = this.baseMapper.selectCount(new LambdaQueryWrapper<>(MenuMaterialCategory.class)
               // .eq(MenuMaterialCategory::getDelFlag, DelFlagEnum.DEL_FALSE.key())
                .isNull(MenuMaterialCategory::getBigCategoryId).or()
                .isNull(MenuMaterialCategory::getLevel));
        System.err.println("[货品类别_所有货品类别的所属大类和等级]_未赋值大类id和等级的类别数量：{}"+checkIfExistLevel);
        if (checkIfExistLevel <= 0L) {
            System.err.println("[货品类别_所有货品类别的所属大类和等级]_不需要同步,跳过!");
        } else {
            List<MenuMaterialCategory> topCategoryList = this.baseMapper.selectList(Wrappers.lambdaQuery(MenuMaterialCategory.class)
                    .eq(MenuMaterialCategory::getParentId, -1));
//                    .eq(MenuMaterialCategory::getDelFlag,
//                            DelFlagEnum.DEL_FALSE.key()));
            Iterator var3 = topCategoryList.iterator();

            while(true) {
                List menuMaterialCategoryList;
                do {
                    if (!var3.hasNext()) {
                        return;
                    }

                    MenuMaterialCategory topCategory = (MenuMaterialCategory)var3.next();
                    this.baseMapper.update(null,Wrappers.lambdaUpdate(MenuMaterialCategory.class)
                            .eq(MenuMaterialCategory::getCategoryId, topCategory.getCategoryId())
                            .set(MenuMaterialCategory::getLevel, 0)
                            .set(MenuMaterialCategory::getBigCategoryId, topCategory.getCategoryId()));
                    menuMaterialCategoryList = this.baseMapper.selectList(Wrappers.lambdaQuery(MenuMaterialCategory.class)
                            .eq(MenuMaterialCategory::getParentId, topCategory.getCategoryId()));
                } while(CollUtil.isEmpty(menuMaterialCategoryList));

                Iterator var6 = menuMaterialCategoryList.iterator();

                while(var6.hasNext()) {
                    MenuMaterialCategory menuMaterialCategory = (MenuMaterialCategory)var6.next();
                    this.baseMapper.update(null, Wrappers.lambdaUpdate(MenuMaterialCategory.class)
                            .eq(MenuMaterialCategory::getCategoryId, menuMaterialCategory.getCategoryId())
                            .set(MenuMaterialCategory::getLevel, LeLevelEnum.FIRST.getKey())
                            .set(MenuMaterialCategory::getBigCategoryId, menuMaterialCategory.getCategoryId()));
                    menuMaterialCategory.setLevel(LeLevelEnum.FIRST.getKey());
                    menuMaterialCategory.setBigCategoryId(menuMaterialCategory.getCategoryId());
                    this.setChildBigCategoryAndLevel(menuMaterialCategory, LeLevelEnum.FIRST.getKey() + 1, menuMaterialCategory.getCategoryId());
                }
            }
        }
    }

    public void setChildBigCategoryAndLevel(MenuMaterialCategory parentCategory, Integer level, Long bigCategoryId) {
        List<MenuMaterialCategory> childCategoryList = this.baseMapper.selectList(Wrappers.lambdaQuery(MenuMaterialCategory.class)
                .eq(MenuMaterialCategory::getParentId, parentCategory.getCategoryId()));
        if (!CollUtil.isEmpty(childCategoryList)) {
            Iterator var5 = childCategoryList.iterator();

            while(var5.hasNext()) {
                MenuMaterialCategory childCategory = (MenuMaterialCategory)var5.next();
                this.baseMapper.update(null, Wrappers.lambdaUpdate(MenuMaterialCategory.class)
                        .eq(MenuMaterialCategory::getCategoryId, childCategory.getCategoryId())
                        .set(MenuMaterialCategory::getLevel, level)
                        .set(MenuMaterialCategory::getBigCategoryId, bigCategoryId));
                this.setChildBigCategoryAndLevel(childCategory, level + 1, bigCategoryId);
            }

        }
    }
    /**
     * 修改原料类别
     *
     * @param menuMaterialCategory 原料类别
     * @return 结果
     */
    @Override
    public int updateMenuMaterialCategory(MenuMaterialCategory menuMaterialCategory) {
        try {

            MenuMaterialCategory one = menuMaterialCategoryMapper.getOne(menuMaterialCategory);
            if(one != null){
                throw new ServiceException("修改物品已存在！");
            }
            int num = menuMaterialCategoryMapper.updateMenuMaterialCategory(menuMaterialCategory);
            if(num >0){
                this.generateCategoryNum(menuMaterialCategory.getCategoryId()!=null?menuMaterialCategory.getCategoryId():menuMaterialCategory.getId(), menuMaterialCategory.getParentId(), menuMaterialCategory.getCategoryType());
            }
            return num;
        } catch (Exception e) {
            throw new ServiceException(""+e.getMessage());
        }
    }

    /**
     * 批量删除原料类别
     *
     * @param ids 需要删除的原料类别主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteMenuMaterialCategoryByIds(String[] ids) {
        try{
            menuMaterialCategoryMapper.deleteMenuMaterialCategoryByIds(ids);
            List<String> childCategoryIds = menuMaterialCategoryMapper.getChildCategoryIds(ids);
            if(childCategoryIds !=null && childCategoryIds.size() > 0){
                String[] idss = childCategoryIds.toArray(new String[childCategoryIds.size()]); // 避免数组扩容
                //递归删除
                deleteMenuMaterialCategoryByIds(idss);
            }
            return 1;
        }catch (Exception e){
            throw new ServiceException(e.getMessage());
        }

    }

    /**
     * 删除原料类别信息
     *
     * @param id 原料类别主键
     * @return 结果
     */
    @Override
    public int deleteMenuMaterialCategoryById(Long id) {
        return menuMaterialCategoryMapper.deleteMenuMaterialCategoryById(id);
    }

    @Override
    public List<MenuCategoryTreeVO> getTree(CategoryTreeListDTO content) {
//        LambdaQueryWrapper<MenuMaterialCategory> lambdaQueryWrapper = new LambdaQueryWrapper();
//        lambdaQueryWrapper.eq(MenuMaterialCategory::getDelFlag, DelFlagEnum.DEL_FALSE.key());
//        content.setAreaAuth(getTenantAreaIdList(BnsConstants.COMMON_YES));
//        if (ObjectUtil.isNotEmpty(content.getCategoryType())) {
//            lambdaQueryWrapper.eq(MenuMaterialCategory::getCategoryType, content.getCategoryType());
//        }
//
//        if (ObjectUtil.isNotEmpty(content.getAreaId())) {
//            lambdaQueryWrapper.and((i) -> {
//                i.eq(MenuMaterialCategory::getAreaId, content.getAreaId()).or()
//                        .isNull(MenuMaterialCategory::getAreaId);
//            });
//        }
//
//        if (ObjectUtil.isNotEmpty(content.getAreaAuth())) {
//            lambdaQueryWrapper.and((i) -> {
//                i.in(MenuMaterialCategory::getAreaId, content.getAreaAuth()).or()
//                        .isNull(MenuMaterialCategory::getAreaId);
//            });
//        }
//
//        if (ObjectUtil.isNotEmpty(content.getIfAdd()) && ObjectUtil.isEmpty(content.getAreaId())) {
//            lambdaQueryWrapper.isNull(MenuMaterialCategory::getAreaId);
//        }
//
//        List<MenuCategoryTreeVO> sqlList = this.baseMapper.selectCategoryTree(lambdaQueryWrapper);

       // Map<Long, String> areaNameMap = this.allocCanteenApi.getAreaNameMap(sqlList.stream().map(MenuCategoryTreeVO::getAreaId).filter(Objects::nonNull).collect(Collectors.toList()));


        List<MenuCategoryTreeVO> list = menuMaterialCategoryMapper.selectCategoryTrees(content);


        return TreeNodeUtil.assembleTree(list);
    }

}
