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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
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.iotbom.vo.*;
import cn.iocoder.yudao.module.pms.controller.admin.iotcommonbommaterial.vo.IotCommonBomMaterialSaveReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotProductClassifyDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotbom.IotBomDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotcommonbommaterial.IotCommonBomMaterialDO;
import cn.iocoder.yudao.module.pms.service.IotProductClassifyService;
import cn.iocoder.yudao.module.pms.service.iotbom.IotBomService;
import cn.iocoder.yudao.module.pms.service.iotcommonbommaterial.IotCommonBomMaterialService;
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;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;

@Tag(name = "管理后台 - PMS BOM 关系")
@RestController
@RequestMapping("/rq/iot-bom")
@Validated
public class IotBomController {

    @Resource
    private IotBomService iotBomService;
    @Resource
    private IotCommonBomMaterialService iotCommonBomMaterialService;
    @Resource
    private IotProductClassifyService iotProductClassifyService;

    @PostMapping("/create")
    @Operation(summary = "创建PMS BOM 关系")
    @PreAuthorize("@ss.hasPermission('rq:iot-bom:create')")
    public CommonResult<Long> createIotBom(@Valid @RequestBody IotBomSaveReqVO createReqVO) {
        return success(iotBomService.createIotBom(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新PMS BOM 关系")
    @PreAuthorize("@ss.hasPermission('rq:iot-bom:update')")
    public CommonResult<Boolean> updateIotBom(@Valid @RequestBody IotBomSaveReqVO updateReqVO) {
        iotBomService.updateIotBom(updateReqVO);
        return success(true);
    }

    @PutMapping("/copyCategoryBom")
    @Operation(summary = "拷贝已有设备分类的BOM")
    @PreAuthorize("@ss.hasPermission('rq:iot-bom:create')")
    public CommonResult<Boolean> copyCategoryBom(@Valid @RequestBody IotBomSaveReqVO updateReqVO) {
        iotBomService.copyCategoryBom(updateReqVO);
        return success(true);
    }

    @PutMapping("/updateAlone")
    @Operation(summary = "更新PMS BOM 关系 只同步没有BOM的设备")
    @PreAuthorize("@ss.hasPermission('rq:iot-bom:update')")
    public CommonResult<Boolean> updateAlone(@Valid @RequestBody IotBomSaveReqVO updateReqVO) {
        iotBomService.updateIotBomAlone(updateReqVO);
        return success(true);
    }

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

    @GetMapping("/get")
    @Operation(summary = "获得PMS BOM 关系")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('rq:iot-bom:query')")
    public CommonResult<IotBomRespVO> getIotBom(@RequestParam("id") Long id) {
        IotBomDO iotBom = iotBomService.getIotBom(id);
        return success(BeanUtils.toBean(iotBom, IotBomRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得PMS BOM 关系分页")
    @PreAuthorize("@ss.hasPermission('rq:iot-bom:query')")
    public CommonResult<PageResult<IotBomRespVO>> getIotBomPage(@Valid IotBomPageReqVO pageReqVO) {
        PageResult<IotBomDO> pageResult = iotBomService.getIotBomPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, IotBomRespVO.class));
    }

    @GetMapping("/deviceAssociateBomPage")
    @Operation(summary = "获得PMS 设备关联-BOM 关系分页")
    @PreAuthorize("@ss.hasPermission('rq:iot-bom:query')")
    public CommonResult<PageResult<IotBomRespVO>> deviceAssociateBomPage(@Valid IotBomPageReqVO pageReqVO) {
        PageResult<IotBomDO> pageResult = iotBomService.deviceAssociateBomPage(pageReqVO);

        return success(BeanUtils.toBean(pageResult, IotBomRespVO.class));
    }

    @GetMapping("/list")
    @Operation(summary = "获取 Bom树 列表")
    @PreAuthorize("@ss.hasPermission('rq:iot-bom:query')")
    public CommonResult<List<IotBomRespVO>> getBomList(IotBomListReqVO reqVO) {
        List<IotBomDO> list = iotBomService.getBomList(reqVO);
        if (CollUtil.isEmpty(list)) {
            return success(Collections.emptyList());
        }
        List<Long> bomNodeIds = list.stream()
                .map(IotBomDO::getId)
                .collect(Collectors.toList());
        IotCommonBomMaterialSaveReqVO bomMaterialSaveReqVO = new IotCommonBomMaterialSaveReqVO();
        bomMaterialSaveReqVO.setBomNodeIds(bomNodeIds);
        // 查询所有bom节点已经绑定的物料列表
        List<IotCommonBomMaterialDO> bomMaterials = iotCommonBomMaterialService.getIotCommonBomMaterials(bomMaterialSaveReqVO);
        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);
                }
            });
        }
        // 拼接所属 设备分类 名称
        Map<Long, IotProductClassifyDO> deviceCategoryMap = iotProductClassifyService.getIotProductClassifyMap(
                convertList(list, IotBomDO::getDeviceCategoryId));
        return success(BeanUtils.toBean(list, IotBomRespVO.class, bom -> {
            Integer materialCount = bomMaterialCount.getOrDefault(bom.getId(), 0);
            bom.setMaterials(materialCount);
            if (ObjUtil.isNotEmpty(bom.getDeviceCategoryId())) {
                if (ObjUtil.isNotEmpty(deviceCategoryMap.get(bom.getDeviceCategoryId()))) {
                    bom.setDeviceCategoryName(deviceCategoryMap.get(bom.getDeviceCategoryId()).getName());
                }
            }
        }));
    }

    @GetMapping("/listTree")
    @Operation(summary = "获取 Bom树 分页 列表")
    @PreAuthorize("@ss.hasPermission('rq:iot-bom:query')")
    public CommonResult<PageResult<IotBomRespVO>> getBomTreeList(@Valid IotBomListReqVO reqVO) {
        PageResult<IotBomRespVO> pageResult = iotBomService.getBomTreePage(reqVO);
        return success(pageResult);
    }

    @GetMapping(value = {"/list-all-simple", "/simple-list"})
    @Operation(summary = "获取Bom精简信息列表", description = "只包含被开启的Bom节点，主要用于前端的下拉选项")
    public CommonResult<List<IotBomSimpleRespVO>> getSimpleBomList(IotBomListReqVO reqVO) {
        if (ObjectUtil.isEmpty(reqVO.getDeviceCategoryId())) {
            return success(CollectionUtil.newArrayList());
        }
        reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
        List<IotBomDO> list = iotBomService.getBomList(reqVO);
        return success(BeanUtils.toBean(list, IotBomSimpleRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出PMS BOM 关系 Excel")
    @PreAuthorize("@ss.hasPermission('rq:iot-bom:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportIotBomExcel(@Valid IotBomPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<IotBomDO> list = iotBomService.getIotBomPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "PMS BOM 关系.xls", "数据", IotBomRespVO.class,
                        BeanUtils.toBean(list, IotBomRespVO.class));
    }

}