package com.zt.plat.module.base.api.materialclasses;

import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.module.base.api.materialclasses.dto.MaterialClassesPageReqDTO;
import com.zt.plat.module.base.api.materialclasses.dto.MaterialClassesRespDTO;
import com.zt.plat.module.base.api.materialclasses.dto.MaterialClassesSaveReqDTO;
import com.zt.plat.module.base.api.materialclasses.dto.MaterialClassesTreeRespDTO;
import com.zt.plat.module.base.controller.admin.materialclasses.vo.MaterialClassesPageReqVO;
import com.zt.plat.module.base.controller.admin.materialclasses.vo.MaterialClassesRespVO;
import com.zt.plat.module.base.controller.admin.materialclasses.vo.MaterialClassesSaveReqVO;
import com.zt.plat.module.base.dal.dataobject.materialclasses.MaterialClassesDO;
import com.zt.plat.module.base.service.materialclasses.MaterialClassesService;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static com.zt.plat.framework.common.pojo.CommonResult.success;

@RestController
@Validated
public class MaterialClassesApiImpl implements MaterialClassesApi {

    @Resource
    private MaterialClassesService materialClassesService;

    @Override
    public CommonResult<MaterialClassesRespDTO> createMaterialClasses(MaterialClassesSaveReqDTO createReqDTO) {
        MaterialClassesRespVO respVO = materialClassesService.createMaterialClasses(BeanUtils.toBean(createReqDTO, MaterialClassesSaveReqVO.class));
        return success(BeanUtils.toBean(respVO, MaterialClassesRespDTO.class));
    }

    @Override
    public CommonResult<Boolean> updateMaterialClasses(MaterialClassesSaveReqDTO updateReqDTO) {
        materialClassesService.updateMaterialClasses(BeanUtils.toBean(updateReqDTO, MaterialClassesSaveReqVO.class));
        return success(true);
    }

    @Override
    public CommonResult<Boolean> deleteMaterialClasses(Long id) {
        materialClassesService.deleteMaterialClasses(id);
        return success(true);
    }

    @Override
    public CommonResult<Boolean> deleteMaterialClassesList(List<Long> ids) {
        materialClassesService.deleteMaterialClassesListByIds(ids);
        return success(true);
    }

    @Override
    public CommonResult<MaterialClassesRespDTO> getMaterialClasses(Long id) {
        MaterialClassesDO classesDO = materialClassesService.getMaterialClasses(id);
        return success(BeanUtils.toBean(classesDO, MaterialClassesRespDTO.class));
    }

    @Override
    public CommonResult<PageResult<MaterialClassesRespDTO>> getMaterialClassesPage(MaterialClassesPageReqDTO pageReqDTO) {
        MaterialClassesPageReqVO pageReqVO = BeanUtils.toBean(pageReqDTO, MaterialClassesPageReqVO.class);
        PageResult<MaterialClassesDO> pageResult = materialClassesService.getMaterialClassesPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, MaterialClassesRespDTO.class));
    }

    @Override
    public CommonResult<List<MaterialClassesTreeRespDTO>> getMaterialClassesTree() {
        List<MaterialClassesDO> list = materialClassesService.getMaterialClassesList();
        return success(buildTree(list));
    }

    private List<MaterialClassesTreeRespDTO> buildTree(List<MaterialClassesDO> list) {
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }
        Map<Long, MaterialClassesTreeRespDTO> nodeMap = new LinkedHashMap<>();
        list.stream()
                .sorted(Comparator.comparing(MaterialClassesDO::getId))
                .forEach(item -> nodeMap.put(item.getId(), BeanUtils.toBean(item, MaterialClassesTreeRespDTO.class)));
        List<MaterialClassesTreeRespDTO> roots = new ArrayList<>();
        nodeMap.values().forEach(node -> {
            Long parentId = node.getParentId();
            if (parentId == null || parentId == 0 || !nodeMap.containsKey(parentId)) {
                roots.add(node);
            } else {
                nodeMap.get(parentId).getChildren().add(node);
            }
        });
        return roots;
    }
}
