/**
 * There are liru code generation
 */
package com.sw.mes.store.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sw.mes.core.response.ResponsePage;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.RequestPage;
import com.sw.mes.store.dto.WarehouseModelDto;
import com.sw.mes.store.dto.WarehouseModelTree;
import com.sw.mes.store.entity.WarehouseModel;
import com.sw.mes.store.enums.WarehouseTypeEnum;
import com.sw.mes.store.service.WarehouseModelService;
import com.sw.mes.store.utils.TreeUtil;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author wupeng
 * @Description 线边仓模型
 * @Date 11:10 2023/7/24
 * @Param
 * @return
 **/
@RestController
@RequestMapping("/warehouse/model")
@Slf4j
@Api(tags = "线边仓模型管理")
public class WarehouseModelController {

    @Autowired
    private ModelMapper modelMapper;

    @Autowired
    private WarehouseModelService warehouseModelService;

    @ApiOperation(value = "分页查询线边仓模型列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "search_LIKE_type", value = "类型", dataType = "string", paramType = "query")
    })
    @GetMapping("/listByPage")
    public Result<ResponsePage<WarehouseModelDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
        //查询有权限的数据
        Page<WarehouseModel> page = warehouseModelService.listByPage(new Page(requestPage.getPage(), requestPage.getRows()), request);
        List<WarehouseModelDto> dtos = page.getRecords().stream()
                .map(entity -> toLazyDto(entity))
                .collect(Collectors.toList());
        ResponsePage responsePage = new ResponsePage(dtos, page.getTotal());
        return ResultGenerator.success(responsePage);
    }


    @GetMapping("/tree")
    @ApiOperation(value = "获取线边仓模型树状图")
    public Result<List<WarehouseModelTree>> tree() {
        List<WarehouseModel> locations = warehouseModelService.list();
        List<WarehouseModelTree> warehouseModelTree = getStoreLocationTree(locations, 0L);
        return ResultGenerator.success(warehouseModelTree);
    }

    @GetMapping("/partTree")
    @ApiOperation(value = "获取线边仓模型树状图-返回非库位的树结构")
    public Result<List<WarehouseModelTree>> partTree() {
        LambdaQueryWrapper<WarehouseModel> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.ne(WarehouseModel::getType, WarehouseTypeEnum.库位.getType());
        List<WarehouseModel> locations = warehouseModelService.list(lambdaQueryWrapper);
        List<WarehouseModelTree> warehouseModelTree = getStoreLocationTree(locations, 0L);
        return ResultGenerator.success(warehouseModelTree);
    }

    @GetMapping("/permission/tree")
    @ApiOperation(value = "获取当前用户有权限的线边仓模型树状图")
    public Result<List<WarehouseModelTree>> permissionTree(@ApiParam(value = "用户ID") @RequestParam Integer userId) {
        //TODO 如果后续库位太多，可以先返回有权限的非库位结构树，当用户点击具体的库位父ID时，再分页查询出该ID下面的库位
        List<WarehouseModel> warehouseModels = warehouseModelService.findByUserId(userId);
        if (warehouseModels != null && warehouseModels.size() > 0) {
            List<WarehouseModelTree> warehouseModelTree = getStoreLocationTree(warehouseModels, 0L);
            return ResultGenerator.success(warehouseModelTree);
        }
        return ResultGenerator.success();
    }

    @ApiOperation(value = "根据父ID查询所有子库位信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query")
    })
    @GetMapping("/getChildren")
    public Result<ResponsePage<WarehouseModelDto>> getByWarehouseModelId(@RequestParam("id") @ApiParam(value = "线边仓模型id") Long id, @ApiIgnore RequestPage requestPage) {
        List<WarehouseModelDto> storeLocations = warehouseModelService.getChildLocationIds(id)
                .stream().filter(e -> WarehouseTypeEnum.库位.getType().equals(e.getType())).collect(Collectors.toList());
        long total = 0L;
        if (storeLocations != null && !storeLocations.isEmpty()) {
            total = storeLocations.size();
        }
        storeLocations = storeLocations.stream().skip(requestPage.getRows() * (requestPage.getPage() - 1)).limit(requestPage.getRows()).collect(Collectors.toList());
        ResponsePage responsePage = new ResponsePage(storeLocations, total);
        return ResultGenerator.success(responsePage);
    }

    /**
     * 获取当前节点的所有子节点id
     * @param id
     * @return
     */
    @GetMapping("/getChildrenId")
    @ApiOperation("获取当前节点的所有子节点id")
    public Result<List<Long>> getByWarehouseModelId(@RequestParam("id")Long id) {
        List<WarehouseModelDto> storeLocations = warehouseModelService.getChildLocationIds(id);
        List<Long> result = storeLocations.stream().map(storeLocationId -> {
            return storeLocationId.getId();
        }).collect(Collectors.toList());
        return ResultGenerator.success(result);
    }

    @ApiOperation(value = "查询往上两级的线边仓信息")
    @GetMapping("/getSuperior")
    public Result getSuperior(@RequestParam("id") @ApiParam(value = "线边仓模型id") Long id) {
        try {
            Map<String, WarehouseModelDto> storeLocations = warehouseModelService.getSuperior(id);
            return ResultGenerator.success(storeLocations);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "线边仓模型详细信息")
    @GetMapping("/{id}")
    public Result<WarehouseModelDto> get(@PathVariable @ApiParam(value = "线边仓模型id") Long id) {
        WarehouseModel warehouseModel = warehouseModelService.getById(id);
        if (null == warehouseModel) {
            return ResultGenerator.fail("线边仓模型不存在");
        }
        return ResultGenerator.success(toEagerDto(warehouseModel));
    }

    @ApiOperation(value = "线边仓模型详细信息")
    @GetMapping("/getCode")
    public Result<WarehouseModelDto> getCode(@RequestParam @ApiParam(value = "线边仓模型code") String code) {
        WarehouseModel warehouseModel = warehouseModelService.getCode(code);
        if (null == warehouseModel) {
            return ResultGenerator.fail("线边仓模型不存在");
        }
        return ResultGenerator.success(toEagerDto(warehouseModel));
    }

    @ApiOperation(value = "线边仓模型创建")
    @PostMapping("/create")
    public Result create(@RequestBody @Valid @ApiParam(value = "线边仓模型对象") WarehouseModelDto warehouseModelDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        Result result = warehouseModelService.create(warehouseModelDto);
        return result;
    }

    @ApiOperation(value = "线边仓模型更新")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "线边仓模型对象") WarehouseModelDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        warehouseModelService.updateByDto(dto);
        return ResultGenerator.success();
    }

    @ApiOperation(value = "线边仓模型删除")
    @PostMapping("/delete")
    public Result remove(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Long[] ids) {
        return warehouseModelService.removeWithCheck(ids);
    }

    public WarehouseModelDto toLazyDto(WarehouseModel entity) {
        WarehouseModelDto warehouseModelDto = modelMapper.map(entity, WarehouseModelDto.class);
        //查询所属厂区
        Long factoryId = entity.getFactoryId();
        WarehouseModel factory = warehouseModelService.getById(factoryId);
        if (factory != null) {
            warehouseModelDto.setFactoryName(factory.getName());
        }
        //查询所属仓库
        Long warehouseId = entity.getWarehouseId();
        WarehouseModel warehouse = warehouseModelService.getById(warehouseId);
        if (warehouse != null) {
            warehouseModelDto.setWarehouseName(warehouse.getName());
        }
        //查询所属库区
        Long areaId = entity.getAreaId();
        WarehouseModel area = warehouseModelService.getById(areaId);
        if (area != null) {
            warehouseModelDto.setAreaName(area.getName());
        }

        return warehouseModelDto;
    }

    public WarehouseModelDto toEagerDto(WarehouseModel entity) {
        WarehouseModelDto dto = modelMapper.map(entity, WarehouseModelDto.class);
        return dto;
    }

    public WarehouseModel fromDto(WarehouseModelDto dto) {
        return modelMapper.map(dto, WarehouseModel.class);
    }

    private List<WarehouseModelTree> getStoreLocationTree(List<WarehouseModel> warehouseModels, Long root) {
        List<WarehouseModelTree> treeNodes = new ArrayList<>();
        for (WarehouseModel warehouseModel : warehouseModels) {
            WarehouseModelTree warehouseModelTree = modelMapper.map(warehouseModel, WarehouseModelTree.class);
            treeNodes.add(warehouseModelTree);
        }
        List<WarehouseModelTree> warehouseModelTrees = TreeUtil.buildByRecursive(treeNodes, root);
        return warehouseModelTrees;
    }

}







