package cn.stylefeng.team.portal.modular.management.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.rule.pidset.CalcParentIdListUtil;
import cn.stylefeng.roses.kernel.rule.pidset.callback.PidGetterService;
import cn.stylefeng.roses.kernel.rule.pidset.pojo.ParentIdInfoPojo;
import cn.stylefeng.roses.kernel.rule.tree.factory.SortedTreeBuildFactory;
import cn.stylefeng.team.portal.modular.management.entity.PortalNewsCategory;
import cn.stylefeng.team.portal.modular.management.enums.PortalNewsCategoryExceptionEnum;
import cn.stylefeng.team.portal.modular.management.mapper.PortalNewsCategoryMapper;
import cn.stylefeng.team.portal.modular.management.pojo.request.PortalNewsCategoryRequest;
import cn.stylefeng.team.portal.modular.management.service.PortalNewsCategoryService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class PortalNewsCategoryServiceImpl extends ServiceImpl<PortalNewsCategoryMapper, PortalNewsCategory> implements PortalNewsCategoryService, PidGetterService {

    @Override
    public void add(PortalNewsCategoryRequest portalNewsCategoryRequest) {

        PortalNewsCategory portalNewsCategory = new PortalNewsCategory();

        portalNewsCategory.setDesignId(portalNewsCategoryRequest.getDesignId());
        portalNewsCategory.setParentId(portalNewsCategoryRequest.getParentId());
        portalNewsCategory.setCategoryName(portalNewsCategoryRequest.getCategoryName());
        portalNewsCategory.setFldSort(portalNewsCategoryRequest.getFldSort());

        CalcParentIdListUtil.fillParentIds(portalNewsCategory, this);

        this.save(portalNewsCategory);
    }

    @Override
    public void del(PortalNewsCategoryRequest portalNewsCategoryRequest) {
        PortalNewsCategory portalNewsCategory = this.queryPortalNewsCategory(portalNewsCategoryRequest);
        this.removeById(portalNewsCategory.getCategoryId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDelete(PortalNewsCategoryRequest portalNewsCategoryRequest) {
        this.removeByIds(portalNewsCategoryRequest.getBatchDeleteIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(PortalNewsCategoryRequest portalNewsCategoryRequest) {
        PortalNewsCategory oldCategory = this.queryPortalNewsCategory(portalNewsCategoryRequest);

        PortalNewsCategory newCategory = new PortalNewsCategory();
        BeanUtil.copyProperties(oldCategory, newCategory);

        newCategory.setParentId(portalNewsCategoryRequest.getParentId());
        newCategory.setCategoryName(portalNewsCategoryRequest.getCategoryName());
        newCategory.setFldSort(portalNewsCategoryRequest.getFldSort());

        CalcParentIdListUtil.fillParentIds(newCategory, this);
        this.updateById(newCategory);

        CalcParentIdListUtil.updateParentIdStringList("portal_news_category", "parent_id_list", oldCategory, newCategory, this);
    }

    @Override
    public PortalNewsCategory detail(PortalNewsCategoryRequest portalNewsCategoryRequest) {
        return this.queryPortalNewsCategory(portalNewsCategoryRequest);
    }

    @Override
    public List<PortalNewsCategory> treeList(PortalNewsCategoryRequest portalNewsCategoryRequest) {
        LambdaQueryWrapper<PortalNewsCategory> wrapper = this.createWrapper(portalNewsCategoryRequest);
        List<PortalNewsCategory> portalNewsCategoryList = this.list(wrapper);
        if (ObjectUtil.isEmpty(portalNewsCategoryList)) {
            return new ArrayList<>();
        }

        return new SortedTreeBuildFactory<PortalNewsCategory>().doTreeBuild(portalNewsCategoryList);
    }

    private PortalNewsCategory queryPortalNewsCategory(PortalNewsCategoryRequest portalNewsCategoryRequest) {
        PortalNewsCategory portalNewsCategory = this.getById(portalNewsCategoryRequest.getCategoryId());
        if (ObjectUtil.isEmpty(portalNewsCategory)) {
            throw new ServiceException(PortalNewsCategoryExceptionEnum.PORTAL_NEWS_CATEGORY_NOT_EXISTED);
        }
        return portalNewsCategory;
    }

    private LambdaQueryWrapper<PortalNewsCategory> createWrapper(PortalNewsCategoryRequest portalNewsCategoryRequest) {
        LambdaQueryWrapper<PortalNewsCategory> queryWrapper = new LambdaQueryWrapper<>();

        Long designId = portalNewsCategoryRequest.getDesignId();
        queryWrapper.eq(PortalNewsCategory::getDesignId, designId);

        String searchText = portalNewsCategoryRequest.getSearchText();
        queryWrapper.like(ObjectUtil.isNotEmpty(searchText), PortalNewsCategory::getCategoryName, searchText);

        queryWrapper.orderByAsc(PortalNewsCategory::getFldSort);

        return queryWrapper;
    }

    @Override
    public ParentIdInfoPojo getPointNodePidInfo(Long itemId) {
        PortalNewsCategory portalNewsCategory = this.getById(itemId);
        if (portalNewsCategory == null) {
            return new ParentIdInfoPojo(null, "");
        }
        return new ParentIdInfoPojo(portalNewsCategory.getCategoryId(), portalNewsCategory.getParentIdList());
    }

}
