package cn.iocoder.yudao.module.pms.controller.admin.iotdevicebom;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicebom.vo.*;
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialSaveReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicebom.IotDeviceBomDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicematerial.IotDeviceMaterialDO;
import cn.iocoder.yudao.module.pms.service.iotdevicebom.IotDeviceBomService;
import cn.iocoder.yudao.module.pms.service.iotdevicematerial.IotDeviceMaterialService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - PMS 设备BOM 关系")
@RestController
@RequestMapping("/pms/iot-device-bom")
@Validated
public class IotDeviceBomController {

    @Resource
    private IotDeviceBomService iotDeviceBomService;
    @Resource
    private IotDeviceMaterialService iotDeviceMaterialService;

    @PostMapping("/create")
    @Operation(summary = "创建PMS 设备BOM 关系")
    @PreAuthorize("@ss.hasPermission('pms:iot-device-bom:create')")
    public CommonResult<Long> createIotDeviceBom(@Valid @RequestBody IotDeviceBomSaveReqVO createReqVO) {
        return success(iotDeviceBomService.createIotDeviceBom(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新PMS 设备BOM 关系")
    @PreAuthorize("@ss.hasPermission('pms:iot-device-bom:update')")
    public CommonResult<Boolean> updateIotDeviceBom(@Valid @RequestBody IotDeviceBomSaveReqVO updateReqVO) {
        iotDeviceBomService.updateIotDeviceBom(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除PMS 设备BOM 关系")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('pms:iot-device-bom:delete')")
    public CommonResult<Boolean> deleteIotDeviceBom(@RequestParam("id") Long id) {
        iotDeviceBomService.deleteIotDeviceBom(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得PMS 设备BOM 关系")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('pms:iot-device-bom:query')")
    public CommonResult<IotDeviceBomRespVO> getIotDeviceBom(@RequestParam("id") Long id) {
        IotDeviceBomDO iotDeviceBom = iotDeviceBomService.getIotDeviceBom(id);
        return success(BeanUtils.toBean(iotDeviceBom, IotDeviceBomRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得PMS 设备BOM 关系分页")
    @PreAuthorize("@ss.hasPermission('pms:iot-device-bom:query')")
    public CommonResult<PageResult<IotDeviceBomRespVO>> getIotDeviceBomPage(@Valid IotDeviceBomPageReqVO pageReqVO) {
        PageResult<IotDeviceBomDO> pageResult = iotDeviceBomService.getIotDeviceBomPage(pageReqVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(PageResult.empty());
        }
        List<Long> bomNodeIds = pageResult.getList().stream()
                .map(IotDeviceBomDO::getId)
                .collect(Collectors.toList());
        IotDeviceMaterialSaveReqVO saveReqVO = new IotDeviceMaterialSaveReqVO();
        saveReqVO.setBomNodeIds(bomNodeIds);
        List<IotDeviceMaterialDO> bomMaterials = iotDeviceMaterialService.getIotDeviceMaterials(saveReqVO);
        Map<Long, Integer> bomMaterialCount = new HashMap<>();
        if (CollUtil.isNotEmpty(bomMaterials)) {
            bomMaterials.forEach(material -> {
                if (bomMaterialCount.containsKey(material.getBomNodeId())) {
                    bomMaterialCount.put(material.getBomNodeId(), bomMaterialCount.get(material.getBomNodeId())+1);
                } else {
                    bomMaterialCount.put(material.getBomNodeId(), 1);
                }
            });
        }
        // return success(BeanUtils.toBean(pageResult, IotDeviceBomRespVO.class));
        return success(BeanUtils.toBean(pageResult, IotDeviceBomRespVO.class, bom -> {
            Integer materialCount = bomMaterialCount.getOrDefault(bom.getId(), 0);
            bom.setMaterials(materialCount);
        }));
    }

    @GetMapping(value = {"/list-all-simple", "/simple-list"})
    @Operation(summary = "获取 设备BOM树 精简信息列表", description = "只包含被开启的BOM树节点，主要用于前端的下拉选项")
    public CommonResult<List<IotDeviceBomSimpleRespVO>> getSimpleDeviceBomList(IotDeviceBomListReqVO reqVO) {
        reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
        List<IotDeviceBomDO> list = iotDeviceBomService.getDeviceBomList(reqVO);
        return success(BeanUtils.toBean(list, IotDeviceBomSimpleRespVO.class));
    }

    @GetMapping("/list")
    @Operation(summary = "获取 设备BOM 列表 树")
    @PreAuthorize("@ss.hasPermission('pms:iot-device-bom:query')")
    public CommonResult<List<IotDeviceBomRespVO>> getDeviceBomList(IotDeviceBomListReqVO reqVO) {
        List<IotDeviceBomDO> list = iotDeviceBomService.getDeviceBomList(reqVO);
        if (CollUtil.isEmpty(list)) {
            return success(Collections.emptyList());
        }
        // 当前设备 设备类别 下所有BOM节点
        List<Long> bomNodeIds = list.stream()
                .map(IotDeviceBomDO::getId)
                .collect(Collectors.toList());
        IotDeviceMaterialSaveReqVO saveReqVO = new IotDeviceMaterialSaveReqVO();
        saveReqVO.setBomNodeIds(bomNodeIds);
        // 查询所有bom节点已经绑定的物料列表
        List<IotDeviceMaterialDO> deviceMaterials = iotDeviceMaterialService.getIotDeviceMaterials(saveReqVO);
        Map<Long, Integer> bomMaterialCount = new HashMap<>();
        if (CollUtil.isNotEmpty(deviceMaterials)) {
            deviceMaterials.forEach(material -> {
                if (bomMaterialCount.containsKey(material.getBomNodeId())) {
                    bomMaterialCount.put(material.getBomNodeId(), bomMaterialCount.get(material.getBomNodeId())+1);
                } else {
                    bomMaterialCount.put(material.getBomNodeId(), 1);
                }
            });
        }
        return success(BeanUtils.toBean(list, IotDeviceBomRespVO.class, bom -> {
            Integer materialCount = bomMaterialCount.getOrDefault(bom.getId(), 0);
            bom.setMaterials(materialCount);
        }));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出PMS 设备BOM 关系 Excel")
    @PreAuthorize("@ss.hasPermission('pms:iot-device-bom:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportIotDeviceBomExcel(@Valid IotDeviceBomPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<IotDeviceBomDO> list = iotDeviceBomService.getIotDeviceBomPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "PMS 设备BOM 关系.xls", "数据", IotDeviceBomRespVO.class,
                        BeanUtils.toBean(list, IotDeviceBomRespVO.class));
    }

}