package com.yc.ship.module.miniapplet.service.catalogue;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.framework.common.util.object.BeanUtils;
import com.yc.ship.module.miniapplet.controller.admin.catalogue.vo.CataloguePageReqVO;
import com.yc.ship.module.miniapplet.controller.admin.catalogue.vo.CatalogueRespVO;
import com.yc.ship.module.miniapplet.controller.admin.catalogue.vo.CatalogueSaveReqVO;
import com.yc.ship.module.miniapplet.dal.dataobject.catalogue.CatalogueDO;
import com.yc.ship.module.miniapplet.dal.dataobject.content.ContentDO;
import com.yc.ship.module.miniapplet.dal.mysql.catalogue.CatalogueMapper;
import com.yc.ship.module.miniapplet.service.content.ContentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yc.ship.module.miniapplet.enums.ErrorCodeConstants.*;


/**
 * 目录类型 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
public class CatalogueServiceImpl implements CatalogueService {

    @Resource
    private ContentService contentService;


    @Resource
    private CatalogueMapper catalogueMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createCatalogue(CatalogueSaveReqVO createReqVO) {
        // 插入
        CatalogueDO catalogue = BeanUtils.toBean(createReqVO, CatalogueDO.class);
        Long id = IdWorker.getId(catalogue);
        catalogue.setId(id);
        catalogueMapper.insert(catalogue);
        // 返回
        return catalogue.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCatalogue(CatalogueSaveReqVO updateReqVO) {
        // 校验存在
        validateCatalogueExists(updateReqVO.getId());
        // 更新
        CatalogueDO updateObj = BeanUtils.toBean(updateReqVO, CatalogueDO.class);
        catalogueMapper.updateById(updateObj);
    }


    @Override
    public void deleteCatalogue(Long id) {
        List<ContentDO> contentList = contentService.getContentList(id, null);
        if (!contentList.isEmpty()) {
            throw exception(CATALOGUE_BINDING_CONTENT);
        }
        // 删除
        catalogueMapper.deleteById(id);
    }

    private CatalogueDO validateCatalogueExists(Long id) {
        CatalogueDO catalogueDO = catalogueMapper.selectById(id);
        if (catalogueDO == null) {
            throw exception(CATALOGUE_NOT_EXISTS);
        }
        return catalogueDO;
    }

    @Override
    public CatalogueDO getCatalogue(Long id) {
        return catalogueMapper.selectById(id);
    }

    @Override
    public CatalogueRespVO getCatalogueResp(Long id) {
        CatalogueDO catalogue = getCatalogue(id);
        CatalogueRespVO respVO = BeanUtils.toBean(catalogue, CatalogueRespVO.class);
        return respVO;
    }

    @Override
    public PageResult<CatalogueDO> getCataloguePage(CataloguePageReqVO pageReqVO) {
        return catalogueMapper.selectPage(pageReqVO);
    }

    @Override
    public List<CatalogueDO> getCatalogueList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return catalogueMapper.selectBatchIds(ids);
    }

    @Override
    public List<Map<String, Object>> getCatalogueTree() {
        return getCatalogueTree(0L);
    }

    @Override
    public List<CatalogueDO> getCatalogueListByStatus(Integer status) {
        return catalogueMapper.selectList(CatalogueDO::getIsUse, status);
    }

    @Override
    public CatalogueDO getByCode(String code) {
        return catalogueMapper.selectByCode(code);
    }

    private List<Map<String, Object>> getCatalogueTree(Long prentId) {
        List<CatalogueDO> catalogueList = catalogueMapper.getCatalogueByParentId(prentId);
        return catalogueList.stream().map(catalogueDO -> {
            Map<String, Object> data = new HashMap<>(3);
            data.put("value", catalogueDO.getId());
            data.put("label", catalogueDO.getName());
            data.put("children", getCatalogueTree(catalogueDO.getId()));
            return data;
        }).collect(Collectors.toList());
    }

}
