package com.ruoyi.mall.controller;

import com.github.pagehelper.PageInfo;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.mall.domain.MallGoodsClass;
import com.ruoyi.mall.domain.vo.MallGoodsClassVO;
import com.ruoyi.mall.service.IMallGoodsClassService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品类型Controller
 *
 * @author chang
 * @date 2021-11-25
 */
@RestController
@RequestMapping("/mall/mallGoodsClass")
public class MallGoodsClassController extends BaseController
{
    @Autowired
    private IMallGoodsClassService mallGoodsClassService;

    /**
     * 查询商品类型列表
     */
    @PreAuthorize("@ss.hasPermi('mall:mallGoodsClass:list')")
    @GetMapping("/list")
    public TableDataInfo list(MallGoodsClass mallGoodsClass)
    {
        startPage();
        mallGoodsClass.setParentId(0L);
        List<MallGoodsClass> list = mallGoodsClassService.selectMallGoodsClassList(mallGoodsClass);
        if (CollectionUtils.isNotEmpty(list)){
            List<MallGoodsClass> mallGoodsClasses = mallGoodsClassService.listByParentIds(
                    list.stream().map(MallGoodsClass::getId).collect(Collectors.toList()));
            list.addAll(mallGoodsClasses);
            TableDataInfo rspData = new TableDataInfo();
            rspData.setCode(HttpStatus.SUCCESS);
            rspData.setMsg("查询成功");
            rspData.setRows(buildTree(list));
            rspData.setTotal(new PageInfo(list).getTotal());
            return rspData;
        }
        return getDataTable(list);
    }

    /**
     * 导出商品类型列表
     */
    @PreAuthorize("@ss.hasPermi('mall:mallGoodsClass:export')")
    @Log(title = "商品类型", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(MallGoodsClass mallGoodsClass)
    {
        List<MallGoodsClass> list = mallGoodsClassService.selectMallGoodsClassList(mallGoodsClass);
        ExcelUtil<MallGoodsClass> util = new ExcelUtil<MallGoodsClass>(MallGoodsClass.class);
        return util.exportExcel(list, "商品类型数据");
    }

    /**
     * 获取商品类型详细信息
     */
    @PreAuthorize("@ss.hasPermi('mall:mallGoodsClass:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return AjaxResult.success(mallGoodsClassService.selectMallGoodsClassById(id));
    }

    /**
     * 新增商品类型
     */
    @PreAuthorize("@ss.hasPermi('mall:mallGoodsClass:add')")
    @Log(title = "商品类型", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody MallGoodsClass mallGoodsClass)
    {
        mallGoodsClass.setCreateAt(DateUtils.getTime());
        return toAjax(mallGoodsClassService.insertMallGoodsClass(mallGoodsClass));
    }

    /**
     * 修改商品类型
     */
    @PreAuthorize("@ss.hasPermi('mall:mallGoodsClass:edit')")
    @Log(title = "商品类型", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody MallGoodsClass mallGoodsClass)
    {
        return toAjax(mallGoodsClassService.updateMallGoodsClass(mallGoodsClass));
    }

    /**
     * 删除商品类型
     */
    @PreAuthorize("@ss.hasPermi('mall:mallGoodsClass:remove')")
    @Log(title = "商品类型", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(mallGoodsClassService.deleteMallGoodsClassByIds(ids));
    }

    @GetMapping("/getClassList")
    public AjaxResult getClassList(MallGoodsClass mallGoodsClass)
    {
        List<MallGoodsClass> list = mallGoodsClassService.selectMallGoodsClassList(mallGoodsClass);
        if (CollectionUtils.isNotEmpty(list)){
            return AjaxResult.success(buildTree(list));
        }
        return AjaxResult.success(list);
    }

    @GetMapping("/tree")
    public AjaxResult tree()
    {
        MallGoodsClass mallGoodsClass = new MallGoodsClass();
        mallGoodsClass.setStatus("0");
        List<MallGoodsClass> list = mallGoodsClassService.selectMallGoodsClassList(mallGoodsClass);
        if (CollectionUtils.isNotEmpty(list)){
            return AjaxResult.success(buildTree(list));
        }
        return AjaxResult.success(list);
    }



    /**
     * 将扁平化的列表转换为树形结构
     *
     * @param flatList 扁平化的列表
     * @return 树形结构的根节点列表
     */
    public static  List<MallGoodsClassVO> buildTree(List<MallGoodsClass> flatList) {
        List<MallGoodsClassVO> rootNodes = new ArrayList<>();
        Map<Long, List<MallGoodsClass>> map = new HashMap<>();
        List<MallGoodsClass> collect = flatList.stream().filter(
                f -> f.getParentId() == null || f.getParentId() == 0).collect(Collectors.toList());
        List<MallGoodsClass> collect1 = flatList.stream().filter(
                f -> f.getParentId() != null && f.getParentId() != 0).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(collect1)){
            map = collect1.stream().collect(Collectors.groupingBy(MallGoodsClass::getParentId));
        }


        // 将所有节点放入Map中，方便通过id快速查找
        for (MallGoodsClass node : collect) {
            MallGoodsClassVO vo = new  MallGoodsClassVO();
            BeanUtils.copyProperties(node , vo);
            List<MallGoodsClass> mallGoodsClasses = map.get(node.getId());
            if(CollectionUtils.isNotEmpty(mallGoodsClasses)){
                vo.setMallGoodsClassVOS(mallGoodsClasses.stream().map(
                        m -> {
                            MallGoodsClassVO vo1 = new  MallGoodsClassVO();
                            BeanUtils.copyProperties(m , vo1);
                            return vo1;
                        }).collect(Collectors.toList()));
            }
            rootNodes.add(vo);
        }
        return rootNodes;
    }
}
