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

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.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.pms.controller.admin.failure.vo.IotFailureReportPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.failure.vo.IotFailureReportRespVO;
import cn.iocoder.yudao.module.pms.controller.admin.maintain.vo.IotMaintainPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.stat.vo.ReportCost;
import cn.iocoder.yudao.module.pms.dal.dataobject.failure.IotFailureReportDO;
import cn.iocoder.yudao.module.pms.dal.mysql.failure.IotFailureReportMapper;
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.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Set;
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/report/failure")
@Validated
@PermitAll
public class IotReportFailureController {
    private final DeptUtil deptUtil;
    private final DeptService deptService;
    private final IotFailureReportMapper iotFailureReportMapper;
    private final DictDataService dictDataService;

    public IotReportFailureController(DeptUtil deptUtil, DeptService deptService, IotFailureReportMapper iotFailureReportMapper, DictDataService dictDataService) {
        this.deptUtil = deptUtil;
        this.deptService = deptService;
        this.iotFailureReportMapper = iotFailureReportMapper;
        this.dictDataService = dictDataService;
    }

    @GetMapping("/status")
    public CommonResult<ImmutableMap> getFailureStat(@Valid IotFailureReportPageReqVO iotFailureReportPageReqVO) {
        Set<Long> ids;
        String companyCode;
        if (Objects.isNull(iotFailureReportPageReqVO.getDeptId())){
            Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
            companyCode = deptUtil.getCompanyCode(loginUserDeptId);
            ids = deptUtil.getDeptIds(companyCode);
            ids.add(loginUserDeptId);
        } else {
            ids = deptService.getChildDeptIdListFromCache(iotFailureReportPageReqVO.getDeptId());
            ids.add(iotFailureReportPageReqVO.getDeptId());
        }
        iotFailureReportPageReqVO.setStatus("reporting");
        Long reporting = iotFailureReportMapper.selectCountByTimeAndStatus(iotFailureReportPageReqVO, ids);
        iotFailureReportPageReqVO.setStatus("trans");
        Long trans = iotFailureReportMapper.selectCountByTimeAndStatus(iotFailureReportPageReqVO, ids);
        iotFailureReportPageReqVO.setStatus("finished");
        Long finished = iotFailureReportMapper.selectCountByTimeAndStatus(iotFailureReportPageReqVO, ids);
        iotFailureReportPageReqVO.setStatus("close");
        Long close = iotFailureReportMapper.selectCountByTimeAndStatus(iotFailureReportPageReqVO, ids);
        return CommonResult.success(ImmutableMap.of("reporting", reporting, "trans", trans, "finished", finished,"close", close));
    }

    @GetMapping("/page")
    public CommonResult<PageResult<IotFailureReportRespVO>> getFailureReportPage(@Valid IotFailureReportPageReqVO iotFailureReportPageReqVO) {
        Set<Long> ids;
        String companyCode;
        if (Objects.isNull(iotFailureReportPageReqVO.getDeptId())){
            Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
            companyCode = deptUtil.getCompanyCode(loginUserDeptId);
            ids = deptUtil.getDeptIds(companyCode);
        } else {
            ids = deptService.getChildDeptIdListFromCache(iotFailureReportPageReqVO.getDeptId());
            ids.add(iotFailureReportPageReqVO.getDeptId());
        }
        PageResult<IotFailureReportDO> iotFailureReportDOPageResult = iotFailureReportMapper.selectPage(iotFailureReportPageReqVO, ids);
        List<IotFailureReportDO> list = iotFailureReportDOPageResult.getList();
        List<IotFailureReportRespVO> collect = iotFailureReportDOPageResult.getList().stream().map(e -> {
            IotFailureReportRespVO bean = BeanUtils.toBean(e, IotFailureReportRespVO.class);
            long count = list.stream().filter(f -> f.getDeviceId().equals(e.getDeviceId())).count();
            bean.setFailureNum(count);
            return bean;
        }).collect(Collectors.toList());
        return CommonResult.success(new PageResult<>(collect, iotFailureReportDOPageResult.getTotal()));
    }

    @GetMapping("/report/export-excel")
    @Operation(summary = "故障上报 Excel")
    @ApiAccessLog(operateType = EXPORT)
    public void exportReport(@Valid IotFailureReportPageReqVO iotFailureReportPageReqVO,
                             HttpServletResponse response) throws IOException {
        Set<Long> ids;
        String companyCode;
        if (Objects.isNull(iotFailureReportPageReqVO.getDeptId())){
            Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
            companyCode = deptUtil.getCompanyCode(loginUserDeptId);
            ids = deptUtil.getDeptIds(companyCode);
        } else {
            ids = deptService.getChildDeptIdListFromCache(iotFailureReportPageReqVO.getDeptId());
            ids.add(iotFailureReportPageReqVO.getDeptId());
        }
        iotFailureReportPageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        PageResult<IotFailureReportDO> iotFailureReportDOPageResult = iotFailureReportMapper.selectPage(iotFailureReportPageReqVO, ids);

        List<IotFailureReportDO> list = iotFailureReportDOPageResult.getList();
        List<DictDataDO> failureStatus = dictDataService.getDictDataListByDictType("pms_failure_status");
        List<DictDataDO> failureType = dictDataService.getDictDataListByDictType("failure_type");
        List<IotFailureReportRespVO> collect = iotFailureReportDOPageResult.getList().stream().map(e -> {
            IotFailureReportRespVO bean = BeanUtils.toBean(e, IotFailureReportRespVO.class);
            long count = list.stream().filter(f -> f.getDeviceId().equals(e.getDeviceId())).count();
            bean.setFailureNum(count);
            if (Objects.nonNull(e.getIfStop())) {
                bean.setStop(e.getIfStop()?"是":"否");
            }
            if (Objects.nonNull(e.getNeedHelp())) {
                bean.setIfNeedHelp(e.getNeedHelp()?"是":"否");
            }
            if (Objects.nonNull(e.getIfDeal())) {
                bean.setDeal(e.getIfDeal()?"是":"否");
            }
            failureType.stream().filter(f -> f.getValue().equals(e.getFailureType())).findFirst().ifPresent(f -> {
                bean.setFailureType(f.getLabel());
            });
            failureStatus.stream().filter(f -> f.getValue().equals(e.getStatus())).findFirst().ifPresent(f -> {
                bean.setStatus(f.getLabel());
            });
            return bean;
        }).collect(Collectors.toList());
        // 导出 Excel
        ExcelUtils.write(response, "故障上报报表统计.xls", "数据", IotFailureReportRespVO.class, collect);
    }
}
