package cn.iocoder.yudao.module.pms.controller.admin.qhse.danger;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
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.qhse.danger.vo.IotDangerSourcePageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.danger.vo.IotDangerSourceRespVO;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.danger.vo.IotDangerSourceSaveReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.measure.IotMeasureBookController;
import cn.iocoder.yudao.module.pms.dal.dataobject.qhse.danger.IotDangerSourceDO;
import cn.iocoder.yudao.module.pms.dal.mysql.qhse.danger.IotDangerSourceMapper;
import cn.iocoder.yudao.module.pms.service.qhse.danger.IotDangerSourceService;
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
import com.google.common.collect.ImmutableMap;
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.beans.factory.annotation.Autowired;
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.*;
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 = "管理后台 - 危险源")
@RestController
@RequestMapping("/rq/iot-danger-source")
@Validated
public class IotDangerSourceController {

    @Resource
    private IotDangerSourceService iotDangerSourceService;
    @Autowired
    private DeptService deptService;
    @Autowired
    private IotDangerSourceMapper iotDangerSourceMapper;
    @Autowired
    private DictDataService dictDataService;

    @PostMapping("/create")
    @Operation(summary = "创建危险源")
    @PreAuthorize("@ss.hasPermission('rq:iot-danger-source:create')")
    public CommonResult<Long> createIotDangerSource(@Valid @RequestBody IotDangerSourceSaveReqVO createReqVO) {
        return success(iotDangerSourceService.createIotDangerSource(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新危险源")
    @PreAuthorize("@ss.hasPermission('rq:iot-danger-source:update')")
    public CommonResult<Boolean> updateIotDangerSource(@Valid @RequestBody IotDangerSourceSaveReqVO updateReqVO) {
        iotDangerSourceService.updateIotDangerSource(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除危险源")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('rq:iot-danger-source:delete')")
    public CommonResult<Boolean> deleteIotDangerSource(@RequestParam("id") Long id) {
        iotDangerSourceService.deleteIotDangerSource(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得危险源")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('rq:iot-danger-source:query')")
    public CommonResult<IotDangerSourceRespVO> getIotDangerSource(@RequestParam("id") Long id) {
        IotDangerSourceDO iotDangerSource = iotDangerSourceService.getIotDangerSource(id);
        return success(BeanUtils.toBean(iotDangerSource, IotDangerSourceRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得危险源分页")
    @PreAuthorize("@ss.hasPermission('rq:iot-danger-source:query')")
    public CommonResult<PageResult<IotDangerSourceRespVO>> getIotDangerSourcePage(@Valid IotDangerSourcePageReqVO pageReqVO) {
        PageResult<IotDangerSourceDO> pageResult = iotDangerSourceService.getIotDangerSourcePage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, IotDangerSourceRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出危险源 Excel")
    @PreAuthorize("@ss.hasPermission('rq:iot-danger-source:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportIotDangerSourceExcel(@Valid IotDangerSourcePageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<IotDangerSourceDO> list = iotDangerSourceService.getIotDangerSourcePage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "危险源.xls", "数据", IotDangerSourceRespVO.class,
                        BeanUtils.toBean(list, IotDangerSourceRespVO.class));
    }


    @GetMapping("/stat")
    @Operation(summary = "危险源统计")
    public CommonResult<ImmutableMap> generateNum(Long deptId) {
        Set<Long> ids = new HashSet<>();
        if (Objects.nonNull(deptId)) {
            ids = deptService.getChildDeptIdListFromCache(deptId);
            ids.add(deptId);
        }
        IotDangerSourcePageReqVO reqVO = new IotDangerSourcePageReqVO();
        List<IotDangerSourceDO> iotDangerSourceDOS = iotDangerSourceMapper.selectListByDept(reqVO, ids);
        Map<String, Long> classifyCountMap = iotDangerSourceDOS.stream()
                .collect(Collectors.groupingBy(
                        IotDangerSourceDO::getRiskGrade,
                        Collectors.counting()  // 直接统计每个分组的数量
                ));
        List<IotMeasureBookController.ClassifyMeasureBookStatVo> results = new ArrayList<>();
        List<DictDataDO> dictType = dictDataService.getDictDataListByDictType("danger_grade");
        classifyCountMap.forEach((key, value) -> dictType.stream().filter(e -> e.getValue().equals(key)).findFirst().ifPresent(f ->{
            IotMeasureBookController.ClassifyMeasureBookStatVo statVo = new IotMeasureBookController.ClassifyMeasureBookStatVo();
            statVo.setClassify(f.getLabel());
            statVo.setCount(value);
            statVo.setSort(f.getSort());
            results.add(statVo);
        }));

        return success(ImmutableMap.of("classify", results.stream().sorted(Comparator.comparing(IotMeasureBookController.ClassifyMeasureBookStatVo::getSort))));
    }
}