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

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
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.hazard.vo.IotHazardPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.hazard.vo.IotHazardRectifyVO;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.hazard.vo.IotHazardRespVO;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.hazard.vo.IotHazardSaveReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.measure.IotMeasureBookController;
import cn.iocoder.yudao.module.pms.dal.dataobject.qhse.hazard.IotHazardDO;
import cn.iocoder.yudao.module.pms.dal.mysql.qhse.hazard.IotHazardMapper;
import cn.iocoder.yudao.module.pms.service.qhse.hazard.IotHazardService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
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.apache.commons.lang3.StringUtils;
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.annotation.security.PermitAll;
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 = "管理后台 - QHSE隐患排查及整改")
@RestController
@RequestMapping("/rq/iot-hazard")
@Validated
public class IotHazardController {

    @Resource
    private IotHazardService iotHazardService;
    @Autowired
    private DeptApi deptApi;
    @Autowired
    private IotHazardMapper iotHazardMapper;
    @Autowired
    private DeptService deptService;
    @Autowired
    private DictDataService dictDataService;

    @PostMapping("/create")
    @Operation(summary = "创建QHSE隐患排查及整改")
    @PreAuthorize("@ss.hasPermission('rq:iot-hazard:create')")
    public CommonResult<Long> createIotHazard(@Valid @RequestBody IotHazardSaveReqVO createReqVO) {
        return success(iotHazardService.createIotHazard(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新QHSE隐患排查及整改")
    @PreAuthorize("@ss.hasPermission('rq:iot-hazard:update')")
    public CommonResult<Boolean> updateIotHazard(@Valid @RequestBody IotHazardSaveReqVO updateReqVO) {
        iotHazardService.updateIotHazard(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除QHSE隐患排查及整改")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('rq:iot-hazard:delete')")
    public CommonResult<Boolean> deleteIotHazard(@RequestParam("id") Long id) {
        iotHazardService.deleteIotHazard(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得QHSE隐患排查及整改")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('rq:iot-hazard:query')")
    public CommonResult<IotHazardRespVO> getIotHazard(@RequestParam("id") Long id) {
        IotHazardDO iotHazard = iotHazardService.getIotHazard(id);
        return success(BeanUtils.toBean(iotHazard, IotHazardRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得QHSE隐患排查及整改分页")
    @PreAuthorize("@ss.hasPermission('rq:iot-hazard:query')")
    public CommonResult<PageResult<IotHazardRespVO>> getIotHazardPage(@Valid IotHazardPageReqVO pageReqVO) {
        PageResult<IotHazardDO> pageResult = iotHazardService.getIotHazardPage(pageReqVO);
        List<IotHazardRespVO> collect = pageResult.getList().stream().map(e -> {
            IotHazardRespVO iotHazardRespVO = new IotHazardRespVO();
            BeanUtils.copyProperties(e, iotHazardRespVO);
            if (Objects.nonNull(iotHazardRespVO.getDeptId())) {
                DeptRespDTO dept = deptApi.getDept(iotHazardRespVO.getDeptId());
                if(Objects.nonNull(dept)){
                    iotHazardRespVO.setDeptName(dept.getName());
                }
            }
            return iotHazardRespVO;
        }).collect(Collectors.toList());
        return success(new PageResult<>(collect, pageResult.getTotal()));
    }

    @PutMapping("/rectify")
    @Operation(summary = "隐患排查整改")
    @PreAuthorize("@ss.hasPermission('rq:iot-hazard:update')")
    public CommonResult<String> rectifyHazard(@Valid @RequestBody IotHazardRectifyVO iotHazardRectifyVO) {
        if (Objects.isNull(iotHazardRectifyVO.getRectifyDesc())|| StringUtils.isBlank(iotHazardRectifyVO.getRectifyDesc())
            ||Objects.isNull(iotHazardRectifyVO.getRectifyFile())|| StringUtils.isBlank(iotHazardRectifyVO.getRectifyFile())) {
            throw new ServiceException(new ErrorCode(1,"整改信息缺失"));
        }
        iotHazardService.rectifyHazard(iotHazardRectifyVO);
        return success("整改完成");
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出QHSE隐患排查及整改 Excel")
    @PreAuthorize("@ss.hasPermission('rq:iot-hazard:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportIotHazardExcel(@Valid IotHazardPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<IotHazardDO> list = iotHazardService.getIotHazardPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "QHSE隐患排查及整改.xls", "数据", IotHazardRespVO.class,
                        BeanUtils.toBean(list, IotHazardRespVO.class));
    }

    @GetMapping("/stat")
    @PermitAll
    public CommonResult<ImmutableMap<String, Object>> statHazard(Long deptId) {
        Set<Long> ids = new HashSet<>();
        if (Objects.nonNull(deptId)) {
            ids = deptService.getChildDeptIdListFromCache(deptId);
            ids.add(deptId);
        }
        IotHazardPageReqVO pageReqVO = new IotHazardPageReqVO();
        List<IotHazardDO> iotHazardDOS = iotHazardMapper.selectListByDept(pageReqVO, ids);
        int total = iotHazardDOS.size();
        pageReqVO.setStatus("todo");
        int todoSize = iotHazardMapper.selectListByDept(pageReqVO, ids).size();
        List<IotMeasureBookController.ClassifyMeasureBookStatVo> results = new ArrayList<>();
        List<DictDataDO> dictType = dictDataService.getDictDataListByDictType("hazard_soure");
        Map<String, Long> sourceMap = iotHazardDOS.stream().filter(it -> Objects.nonNull(it.getSource()))
                .collect(Collectors.groupingBy(
                        IotHazardDO::getSource,
                        Collectors.counting()  // 直接统计每个分组的数量
                ));
        sourceMap.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);
            results.add(statVo);
        }));
        return success(ImmutableMap.of("total",total,"todo",todoSize,"source", results));
    }

}