package com.jeeplus.psimanage.dishManage.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.core.domain.BaseEntity;
import com.jeeplus.psimanage.dishManage.domain.PsiDishType;
import com.jeeplus.psimanage.dishManage.mapper.PsiDishLibraryMapper;
import com.jeeplus.psimanage.dishManage.mapper.PsiDishTypeMapper;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 菜品分类
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PsiDishTypeService extends ServiceImpl<PsiDishTypeMapper, PsiDishType> {

    @Resource
    private PsiDishTypeMapper mapper;

    @Resource
    private PsiDishLibraryMapper dishLibraryMapper;

    public List<PsiDishType> list(PsiDishType info) {
        LambdaQueryWrapper<PsiDishType> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(info.getName())) {
            wrapper.like(PsiDishType::getName, info.getName());
        }
        if (StringUtils.isNotBlank(info.getStatus())) {
            wrapper.eq(PsiDishType::getStatus, info.getStatus());
        }
        wrapper.eq(BaseEntity::getDelFlag, 0);
        wrapper.orderByAsc(PsiDishType::getSort);
        return mapper.findList(wrapper);
    }

    public List<PsiDishType> treeData(String extId) {
        LambdaQueryWrapper<PsiDishType> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BaseEntity::getDelFlag, 0);
        wrapper.eq(PsiDishType::getStatus, "0");
        if (StringUtils.isNotBlank(extId)) {
            wrapper.ne(PsiDishType::getId, extId);
        }
        wrapper.orderByAsc(PsiDishType::getSort);
        List<PsiDishType> list = mapper.findList(wrapper);
        return buildTree(list);
    }

    public PsiDishType findById(String id) {
        return mapper.getById(id);
    }

    public String saveDishType(PsiDishType info) {
        if (StringUtils.isBlank(info.getParentId())) {
            info.setParentId("0");
        }
        if (StringUtils.isNotBlank(info.getId())) {
            return update(info);
        }
        return add(info);
    }

    private String add(PsiDishType info) {
        Integer exist = mapper.checkNameIsExist(info.getName(), info.getParentId(), null);
        if (exist != null && exist > 0) {
            return "分类名称重复，请重新填写";
        }
        UserDTO userDto = SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken());
        info.setId(UUID.randomUUID().toString().replace("-", ""));
        info.setCreateById(userDto.getId());
        info.setCreateTime(new Date());
        info.setUpdateById(userDto.getId());
        info.setUpdateTime(new Date());
        info.setDelFlag(0);
        if (StringUtils.isBlank(info.getStatus())) {
            info.setStatus("0");
        }
        getNo(info);
        mapper.insert(info);
        return "操作完成";
    }

    private String update(PsiDishType info) {
        Integer exist = mapper.checkNameIsExist(info.getName(), info.getParentId(), info.getId());
        if (exist != null && exist > 0) {
            return "分类名称重复，请重新填写";
        }
        UserDTO userDto = SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken());
        info.setUpdateById(userDto.getId());
        info.setUpdateTime(new Date());
        getNo(info);
        mapper.updateById(info);
        return "操作完成";
    }

    private void getNo(PsiDishType info) {
        PsiDishType parentInfo = null;
        if (!"0".equals(info.getParentId())) {
            parentInfo = mapper.getById(info.getParentId());
        }
        if (parentInfo != null) {
            info.setParentIds(StringUtils.isBlank(parentInfo.getParentIds()) ? parentInfo.getId() : parentInfo.getParentIds() + "," + parentInfo.getId());
            info.setLevel(String.valueOf(Integer.parseInt(parentInfo.getLevel()) + 1));
        } else {
            info.setParentIds("0");
            info.setLevel("1");
        }
        if (info.getSort() == null) {
            Integer no = mapper.getNo(info.getParentId());
            info.setSort(no == null ? 1 : no);
        }
    }

    public String remove(String id) {
        Integer children = mapper.countChildren(id);
        if (children != null && children > 0) {
            return "当前分类存在下级分类，不能删除";
        }
        Integer dishCount = dishLibraryMapper.countByTypeId(id);
        if (dishCount != null && dishCount > 0) {
            return "当前分类已被菜品使用，不能删除";
        }
        mapper.deleteById(id);
        return "操作成功";
    }

    public String changeStatus(String id, String status) {
        PsiDishType info = new PsiDishType();
        info.setId(id);
        info.setStatus(status);
        mapper.updateById(info);
        return "操作成功";
    }

    private List<PsiDishType> buildTree(List<PsiDishType> source) {
        if (CollectionUtil.isEmpty(source)) {
            return new ArrayList<>();
        }
        List<PsiDishType> result = source.stream()
                .filter(item -> StringUtils.isBlank(item.getParentId()) || "0".equals(item.getParentId()))
                .collect(Collectors.toList());
        result.forEach(item -> item.setChildren(getChildren(item.getId(), source)));
        return result;
    }

    private List<PsiDishType> getChildren(String parentId, List<PsiDishType> source) {
        List<PsiDishType> children = source.stream()
                .filter(item -> parentId.equals(item.getParentId()))
                .collect(Collectors.toList());
        children.forEach(item -> item.setChildren(getChildren(item.getId(), source)));
        return children;
    }
}
