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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.iotmainworkorderbom.vo.IotMainWorkOrderBomPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotprojecttask.vo.IotProjectTaskPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.IotRdDailyReportPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotrhdailyreport.vo.IotRhDailyReportPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.maintain.vo.IotMaintainPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.stat.vo.AllOrderResp;
import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDevicePageReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorderbom.IotMainWorkOrderBomDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttask.IotProjectTaskDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotrddailyreport.IotRdDailyReportDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotrhdailyreport.IotRhDailyReportDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotrydailyreport.IotRyDailyReportDO;
import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderDeviceMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.iotmainworkorder.IotMainWorkOrderMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.iotmainworkorderbom.IotMainWorkOrderBomMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.iotopeationfill.IotOpeationFillMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.iotprojecttask.IotProjectTaskMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.iotrddailyreport.IotRdDailyReportMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.iotrhdailyreport.IotRhDailyReportMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.iotrydailyreport.IotRyDailyReportMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.maintain.IotMaintainMapper;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.ImmutableMap;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
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.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "报表所有工单接口")
@RestController
@RequestMapping("/rq/report/order")
@Validated
@PermitAll
@AllArgsConstructor
public class IotReportOrderController {
    private final IotMaintainMapper iotMaintainMapper;
    private final IotInspectOrderMapper iotInspectOrderMapper;
    private final IotOpeationFillMapper iotOpeationFillMapper;
    private final IotMainWorkOrderMapper iotMainWorkOrderMapper;
    private final DeptUtil deptUtil;
    private final DeptService deptService;
    private final DeptApi deptApi;
    private final IotInspectOrderDeviceMapper iotInspectOrderDeviceMapper;
    private final IotMainWorkOrderBomMapper iotMainWorkOrderBomMapper;
    private final IotDeviceMapper iotDeviceMapper;
    private final IotRhDailyReportMapper iotRhDailyReportMapper;
    private final IotRyDailyReportMapper iotRyDailyReportMapper;
    private final IotRdDailyReportMapper iotRdDailyReportMapper;
    private final IotProjectTaskMapper iotProjectTaskMapper;

    @Operation(summary = "各工单状态数量统计")
    @GetMapping("/number")
    public CommonResult<ImmutableMap> getOrderStat(@Valid IotMaintainPageReqVO pageReqVO) {
        LocalDateTime startTime = pageReqVO.getCreateTime()[0];
        LocalDateTime endTime = pageReqVO.getCreateTime()[1];
        Set<Long> ids;
        if (Objects.isNull(pageReqVO.getDeptId())){
            Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
            String companyCode = deptUtil.getCompanyCode(loginUserDeptId);
            ids = deptUtil.getDeptIds(companyCode);
        } else {
            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
            ids.add(pageReqVO.getDeptId());
        }
        pageReqVO.setDeptIds(ids);
        List<AllOrderResp> maintains = iotMaintainMapper.selectStatusNumber(pageReqVO);
        List<AllOrderResp> inspects = iotInspectOrderMapper.selectStatusNumber(pageReqVO);
        List<AllOrderResp> operations = iotOpeationFillMapper.selectStatusNumber(pageReqVO);
        Long wxTotal = maintains.stream().mapToLong(AllOrderResp::getNum).sum();
        Long xjTotal = inspects.stream().mapToLong(AllOrderResp::getNum).sum();
        Long yxTotal = operations.stream().mapToLong(AllOrderResp::getNum).sum();
        // 保养
        List<AllOrderResp> workOrders = iotMainWorkOrderMapper.selectStatusNumber(pageReqVO);
        // 保养工单总数量
        Long byNum = 0l;
        if (CollUtil.isNotEmpty(workOrders)) {
            for (AllOrderResp order : workOrders) {
                if (ObjUtil.isNotEmpty(order.getNum())) {
                    byNum = byNum + order.getNum();
                }
            }
        }

        List<AllOrderResp> dailyReports = iotRhDailyReportMapper.selectStatusNumber(pageReqVO);
        List<AllOrderResp> ryDailyReports = iotRyDailyReportMapper.selectStatusNumber(pageReqVO);
        List<AllOrderResp> rdDailyReports = iotRdDailyReportMapper.selectStatusNumber(pageReqVO);

        Long hbWxNum = 0L;
        Long hbXjNum = 0L;
        Long hbYxNum = 0L;
        Long tbWxNum = 0L;
        Long tbXjNum = 0L;
        Long tbYxNum = 0L;
        LocalDateTime lastYearStart = pageReqVO.getCreateTime()[0].minusYears(1);
        LocalDateTime lastYearEnd = pageReqVO.getCreateTime()[1].minusYears(1);
        LocalDateTime[] createTime = pageReqVO.getCreateTime();
        createTime[0] = lastYearStart;
        createTime[1] = lastYearEnd;
        pageReqVO.setCreateTime(createTime);
        tbWxNum = iotMaintainMapper.selectStatusNumber(pageReqVO).stream().mapToLong(AllOrderResp::getNum).sum();
        tbXjNum = iotInspectOrderMapper.selectStatusNumber(pageReqVO).stream().mapToLong(AllOrderResp::getNum).sum();
        tbYxNum = iotOpeationFillMapper.selectStatusNumber(pageReqVO).stream().mapToLong(AllOrderResp::getNum).sum();

        Long tbByNum = 0l;
        Long hbByNum = 0l;
        // 日报
        Long tbRbNum = 0l;
        Long hbRbNum = 0l;
        // 同比 去年同期相同统计数据对比 无数据
        tbByNum = tbByNum == null ? 0l : tbByNum;

        List<AllOrderResp> reports = new ArrayList<>();
        AtomicReference<Long> noStatus = new AtomicReference<>(0l);
        AtomicReference<Long> yesStatus = new AtomicReference<>(0l);
        if (CollUtil.isNotEmpty(dailyReports)) {
            dailyReports.forEach(report -> {
                if ("0".equals(report.getStatus())) {
                    noStatus.set(noStatus.get() + report.getNum());
                } else {
                    yesStatus.set(yesStatus.get() + report.getNum());
                }
            });
        }
        if (CollUtil.isNotEmpty(ryDailyReports)) {
            ryDailyReports.forEach(report -> {
                if ("0".equals(report.getStatus())) {
                    noStatus.set(noStatus.get() + report.getNum());
                } else {
                    yesStatus.set(yesStatus.get() + report.getNum());
                }
            });
        }
        if (CollUtil.isNotEmpty(rdDailyReports)) {
            rdDailyReports.forEach(report -> {
                if ("0".equals(report.getStatus())) {
                    noStatus.set(noStatus.get() + report.getNum());
                } else {
                    yesStatus.set(yesStatus.get() + report.getNum());
                }
            });
        }
        AllOrderResp noReport = new AllOrderResp();
        noReport.setStatus("0");
        noReport.setNum(noStatus.get());
        reports.add(noReport);
        AllOrderResp yesReport = new AllOrderResp();
        yesReport.setStatus("1");
        yesReport.setNum(yesStatus.get());
        reports.add(yesReport);
        // 当前日报总数量
        Long rbNum = yesStatus.get() + noStatus.get();

        if ("year".equals(pageReqVO.getTimeType())){
            // 保养 年 无同比环比数据
            hbByNum = hbByNum==null ? 0l : hbByNum;
            hbWxNum = tbWxNum == null?0L:tbWxNum;
            hbXjNum = tbXjNum == null?0L:tbXjNum;
            hbYxNum = tbYxNum == null?0L:tbYxNum;
        }  else if ("month".equals(pageReqVO.getTimeType())){
            LocalDateTime lastMonthStart = startTime.minusMonths(1);
            LocalDateTime lastMonthEnd = endTime.minusMonths(1);
            LocalDateTime[] monthTime = pageReqVO.getCreateTime();
            monthTime[0] = lastMonthStart;
            monthTime[1] = lastMonthEnd;
            pageReqVO.setCreateTime(monthTime);
            hbWxNum = iotMaintainMapper.selectStatusNumber(pageReqVO).stream().mapToLong(AllOrderResp::getNum).sum();
            hbXjNum = iotInspectOrderMapper.selectStatusNumber(pageReqVO).stream().mapToLong(AllOrderResp::getNum).sum();
            hbYxNum = iotOpeationFillMapper.selectStatusNumber(pageReqVO).stream().mapToLong(AllOrderResp::getNum).sum();

            List<AllOrderResp> monthWorkOrders = iotMainWorkOrderMapper.selectStatusNumber(pageReqVO);
            if (CollUtil.isNotEmpty(monthWorkOrders)) {
                for (AllOrderResp order : monthWorkOrders) {
                    if (ObjUtil.isNotEmpty(order.getNum())) {
                        hbByNum = hbByNum + order.getNum();
                    }
                }
            }
            IotRhDailyReportPageReqVO reqVO = new IotRhDailyReportPageReqVO();
            reqVO.setCreateTime(monthTime);
            reqVO.setDeptIds(ids);
            List<IotRhDailyReportDO> monthDailyReports = iotRhDailyReportMapper.dailyReports(reqVO);
            if (CollUtil.isNotEmpty(monthDailyReports)) {
                hbRbNum = hbRbNum + monthDailyReports.size();
            }
            IotRyDailyReportPageReqVO ryReqVO = new IotRyDailyReportPageReqVO();
            ryReqVO.setCreateTime(monthTime);
            ryReqVO.setDeptIds(ids);
            List<IotRyDailyReportDO> monthRyDailyReports = iotRyDailyReportMapper.dailyReports(ryReqVO);
            if (CollUtil.isNotEmpty(monthRyDailyReports)) {
                hbRbNum = hbRbNum + monthRyDailyReports.size();
            }
            IotRdDailyReportPageReqVO rdReqVO = new IotRdDailyReportPageReqVO();
            rdReqVO.setCreateTime(monthTime);
            rdReqVO.setDeptIds(ids);
            List<IotRdDailyReportDO> monthRdDailyReports = iotRdDailyReportMapper.dailyReports(rdReqVO);
            if (CollUtil.isNotEmpty(monthRdDailyReports)) {
                hbRbNum = hbRbNum + monthRdDailyReports.size();
            }

        }  else if ("day".equals(pageReqVO.getTimeType())){
            LocalDateTime lastDayStart = startTime.minusDays(1);
            LocalDateTime lastDayEnd = endTime.minusDays(1);
            LocalDateTime[] dayTime = pageReqVO.getCreateTime();
            dayTime[0] = lastDayStart;
            dayTime[1] = lastDayEnd;
            pageReqVO.setCreateTime(dayTime);
            hbWxNum = iotMaintainMapper.selectStatusNumber(pageReqVO).stream().mapToLong(AllOrderResp::getNum).sum();
            hbXjNum = iotInspectOrderMapper.selectStatusNumber(pageReqVO).stream().mapToLong(AllOrderResp::getNum).sum();
            hbYxNum = iotOpeationFillMapper.selectStatusNumber(pageReqVO).stream().mapToLong(AllOrderResp::getNum).sum();

            List<AllOrderResp> dayWorkOrders = iotMainWorkOrderMapper.selectStatusNumber(pageReqVO);
            if (CollUtil.isNotEmpty(dayWorkOrders)) {
                for (AllOrderResp order : dayWorkOrders) {
                    if (ObjUtil.isNotEmpty(order.getNum())) {
                        hbByNum = hbByNum + order.getNum();
                    }
                }
            }
            IotRhDailyReportPageReqVO reqVO = new IotRhDailyReportPageReqVO();
            reqVO.setCreateTime(dayTime);
            reqVO.setDeptIds(ids);
            List<IotRhDailyReportDO> monthDailyReports = iotRhDailyReportMapper.dailyReports(reqVO);
            if (CollUtil.isNotEmpty(monthDailyReports)) {
                hbRbNum = hbRbNum + monthDailyReports.size();
            }
            IotRyDailyReportPageReqVO ryReqVO = new IotRyDailyReportPageReqVO();
            ryReqVO.setCreateTime(dayTime);
            ryReqVO.setDeptIds(ids);
            List<IotRyDailyReportDO> monthRyDailyReports = iotRyDailyReportMapper.dailyReports(ryReqVO);
            if (CollUtil.isNotEmpty(monthRyDailyReports)) {
                hbRbNum = hbRbNum + monthRyDailyReports.size();
            }
            IotRdDailyReportPageReqVO rdReqVO = new IotRdDailyReportPageReqVO();
            rdReqVO.setCreateTime(dayTime);
            rdReqVO.setDeptIds(ids);
            List<IotRdDailyReportDO> monthRdDailyReports = iotRdDailyReportMapper.dailyReports(rdReqVO);
            if (CollUtil.isNotEmpty(monthRdDailyReports)) {
                hbRbNum = hbRbNum + monthRdDailyReports.size();
            }
        }

        Map<String, Object> wxMap = new HashMap<>();
        wxMap.put("total", wxTotal);
        wxMap.put("hb", (hbWxNum==null || hbWxNum==0l) ? hbWxNum :
                ((new BigDecimal(wxTotal).subtract(new BigDecimal(hbWxNum))).divide(new BigDecimal(hbWxNum),2, RoundingMode.HALF_UP)));
        wxMap.put("tb", (tbWxNum==null || tbWxNum==0l) ? tbWxNum :
                ((new BigDecimal(wxTotal).subtract(new BigDecimal(tbWxNum))).divide(new BigDecimal(tbWxNum),2, RoundingMode.HALF_UP)));
        Map<String, Object> xjMap = new HashMap<>();
        xjMap.put("total", xjTotal);
        xjMap.put("hb", (hbXjNum==null || hbXjNum==0l) ? hbXjNum :
                ((new BigDecimal(xjTotal).subtract(new BigDecimal(hbXjNum))).divide(new BigDecimal(hbXjNum),2, RoundingMode.HALF_UP)));
        xjMap.put("tb", (tbXjNum==null || tbXjNum==0l) ? tbXjNum :
                ((new BigDecimal(xjTotal).subtract(new BigDecimal(tbXjNum))).divide(new BigDecimal(tbXjNum),2, RoundingMode.HALF_UP)));

        Map<String, Object> yxMap = new HashMap<>();
        yxMap.put("total", yxTotal);
        yxMap.put("hb", (hbYxNum==null || hbYxNum==0l) ? hbYxNum :
                ((new BigDecimal(yxTotal).subtract(new BigDecimal(hbYxNum))).divide(new BigDecimal(hbYxNum),2, RoundingMode.HALF_UP)));
        yxMap.put("tb", (tbYxNum==null || tbYxNum==0l) ? tbYxNum :
                ((new BigDecimal(yxTotal).subtract(new BigDecimal(tbYxNum))).divide(new BigDecimal(tbYxNum),2, RoundingMode.HALF_UP)));

        Map<String, Object> byMap = new HashMap<>();
        byMap.put("total", byNum);
        byMap.put("hb", (hbByNum==null || hbByNum==0l) ? hbByNum :
                ((new BigDecimal(byNum).subtract(new BigDecimal(hbByNum))).divide(new BigDecimal(hbByNum),2, RoundingMode.HALF_UP)));
        byMap.put("tb", (tbByNum==null || tbByNum==0l) ? tbByNum :
                ((new BigDecimal(byNum).subtract(new BigDecimal(tbByNum))).divide(new BigDecimal(tbByNum),2, RoundingMode.HALF_UP)));

        Map<String, Object> rbMap = new HashMap<>();
        rbMap.put("total", rbNum);
        rbMap.put("hb", (hbRbNum==null || hbRbNum==0l) ? hbRbNum :
                ((new BigDecimal(rbNum).subtract(new BigDecimal(hbRbNum))).divide(new BigDecimal(hbRbNum),2, RoundingMode.HALF_UP)));
        rbMap.put("tb", (tbRbNum==null || tbRbNum==0l) ? tbRbNum :
                ((new BigDecimal(rbNum).subtract(new BigDecimal(tbRbNum))).divide(new BigDecimal(tbRbNum),2, RoundingMode.HALF_UP)));

        return CommonResult.success(ImmutableMap.of("wx", ImmutableMap.of("total", wxMap,"status",maintains), "xj", ImmutableMap.of("total", xjMap, "status", inspects),
                "yx", ImmutableMap.of("total",yxMap, "status",operations), "by", ImmutableMap.of("total", byMap,"status",workOrders), "rb", ImmutableMap.of("total", rbMap,"status", reports)));
    }


    @Operation(summary = "各工单统计")
    @GetMapping("/page")
    public CommonResult<PageResult<AllOrderResp>> getOrderPage(@Valid IotMaintainPageReqVO pageReqVO) {
        Set<Long> ids;
        if (Objects.isNull(pageReqVO.getDeptId())){
            Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
            String companyCode = deptUtil.getCompanyCode(loginUserDeptId);
            ids = deptUtil.getDeptIds(companyCode);
        } else {
            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
            ids.add(pageReqVO.getDeptId());
        }
        pageReqVO.setDeptIds(ids);
        IPage<AllOrderResp> allOrder = iotMaintainMapper.getAllOrder(new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO);
        PageResult<AllOrderResp> result = new PageResult<>(allOrder.getRecords(), allOrder.getTotal());
        Map<Long, String> orderPair = new HashMap<>();
        Map<Long, Long> orderDeviceIdPair = new HashMap<>();
        Map<Long, String> devicePair = new HashMap<>();
        // 任务列表
        Set<Long> taskIds = new HashSet<>();
        // 设备id列表
        Set<Long> totalDeviceIds = new HashSet<>();
        // 日报设备列表 key设备id   value设备信息
        Map<Long, String> reportDevicePair = new HashMap<>();
        // 日报设备列表 key任务id   value多个设备信息列表
        Map<Long, Set<Long>> taskDevicesPair = new HashMap<>();
        // 日报设备列表 key任务id   value多个设备信息 分号分隔
        Map<Long,String> taskDevicesStrPair = new HashMap<>();
        if (CollUtil.isNotEmpty(result.getList())) {
            Set<Long> orderIds = new HashSet<>();
            result.getList().forEach(order -> {
                if ("保养工单".equals(order.getType())) {
                    orderIds.add(order.getId());
                }
                if ("瑞都日报".equals(order.getType()) || "瑞鹰日报".equals(order.getType()) || "瑞恒日报".equals(order.getType())) {
                    taskIds.add(order.getTaskId());
                }
            });
            if (CollUtil.isNotEmpty(taskIds)) {
                IotProjectTaskPageReqVO reqVO = new IotProjectTaskPageReqVO();
                reqVO.setTaskIds(new ArrayList<>(taskIds));
                List<IotProjectTaskDO> tasks = iotProjectTaskMapper.selectList(reqVO);
                if (CollUtil.isNotEmpty(tasks)) {
                    tasks.forEach(task -> {
                        Set<Long> deviceIds = task.getDeviceIds();
                        if (CollUtil.isNotEmpty(deviceIds)) {
                            totalDeviceIds.addAll(deviceIds);
                            taskDevicesPair.put(task.getId(), task.getDeviceIds());
                        }
                    });
                }
                // 查询所有设备信息
                IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
                deviceReqVO.setDeviceIds(new ArrayList<>(totalDeviceIds));
                List<IotDeviceDO> devices = iotDeviceMapper.selectListAlone(deviceReqVO);
                if (CollUtil.isNotEmpty(devices)) {
                    devices.forEach(device -> {
                        reportDevicePair.put(device.getId(), StrUtil.join("|", device.getDeviceCode(), device.getDeviceName()));
                    });
                }
                // 建立日报关联的任务id 与 任务下所有设备 编码名称 的对应关系
                if (CollUtil.isNotEmpty(taskDevicesPair) && CollUtil.isNotEmpty(reportDevicePair)) {
                    for (Map.Entry<Long, Set<Long>> entry : taskDevicesPair.entrySet()) {
                        Long taskId = entry.getKey();
                        Set<Long> deviceIds = entry.getValue();

                        // 使用流处理获取设备名称，并用分号连接
                        String deviceStr = deviceIds.stream()
                                .map(reportDevicePair::get)  // 从 reportDevicePair 获取设备字符串
                                .filter(StrUtil::isNotBlank)  // 过滤掉空值
                                .collect(Collectors.joining(";"));  // 用分号连接

                        if (StrUtil.isNotBlank(deviceStr)) {
                            taskDevicesStrPair.put(taskId, deviceStr);
                        }
                    }
                }
            }
            if (CollUtil.isNotEmpty(orderIds)) {
                Set<Long> deviceIds = new HashSet<>();
                // 查询所有保养工单的设备名称
                IotMainWorkOrderBomPageReqVO bomReqVO = new IotMainWorkOrderBomPageReqVO();
                bomReqVO.setWorkOrderIds(new ArrayList<>(orderIds));
                List<IotMainWorkOrderBomDO> orderBoms = iotMainWorkOrderBomMapper.selectList(bomReqVO);
                if (CollUtil.isNotEmpty(orderBoms)) {
                    orderBoms.forEach(bom -> {
                        deviceIds.add(bom.getDeviceId());
                        orderDeviceIdPair.put(bom.getWorkOrderId(), bom.getDeviceId());
                    });
                    // 查询所有设备的编码 名称
                    IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
                    deviceReqVO.setDeviceIds(new ArrayList<>(deviceIds));
                    List<IotDeviceDO> devices = iotDeviceMapper.selectListAlone(deviceReqVO);
                    if (CollUtil.isNotEmpty(devices)) {
                        devices.forEach(device -> {
                            devicePair.put(device.getId(), StrUtil.join("|", device.getDeviceCode(), device.getDeviceName()));
                        });
                    }
                    orderDeviceIdPair.forEach((orderId, deviceId) -> {
                        if (devicePair.containsKey(deviceId)) {
                            orderPair.put(orderId, devicePair.get(deviceId));
                        }
                    });
                }
            }
        }
        List<AllOrderResp> collect = result.getList().stream().map(e -> {
            if ("巡检工单".equals(e.getType())){
                String deviceInfo = iotInspectOrderDeviceMapper.getDeviceInfo(e.getId());
                e.setDevice(deviceInfo);
            } else if ("运行记录".equals(e.getType())) {
                List<IotOpeationFillDO> orderId = iotOpeationFillMapper.getListByOrderId(e.getId());
                StringJoiner joiner = new StringJoiner(", ");
                for (IotOpeationFillDO fillDO : orderId) {
                    joiner.add(fillDO.getDeviceCode() + "/" + fillDO.getDeviceName());
                }
                e.setDevice(joiner.toString());
            }  else if ("保养工单".equals(e.getType())) {
                if (orderPair.containsKey(e.getId())) {
                    e.setDevice(orderPair.get(e.getId()));
                }
            } else if ("瑞都日报".equals(e.getType()) || "瑞鹰日报".equals(e.getType()) || "瑞恒日报".equals(e.getType())) {
                // 设置日报的设备信息
                if (taskDevicesStrPair.containsKey(e.getTaskId())) {
                    e.setDevice(taskDevicesStrPair.get(e.getTaskId()));
                }
            }
            return e;
        }).collect(Collectors.toList());
        return success(new PageResult<>(collect, allOrder.getTotal()));

    }

    @GetMapping("/export-excel")
    public void downloadExcelByStringHeader(@Valid IotMaintainPageReqVO pageReqVO,
                                            HttpServletResponse response) throws IOException {
        Set<Long> ids;
        if (Objects.isNull(pageReqVO.getDeptId())){
            Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
            String companyCode = deptUtil.getCompanyCode(loginUserDeptId);
            ids = deptUtil.getDeptIds(companyCode);
        } else {
            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
            ids.add(pageReqVO.getDeptId());
        }
        pageReqVO.setDeptIds(ids);
        List<AllOrderResp> allOrder = iotMaintainMapper.getAllOrderNoPage(pageReqVO);
//        PageResult<AllOrderResp> result = new PageResult<>(allOrder.getRecords(), allOrder.getTotal());
        Map<Long, String> orderPair = new HashMap<>();
        Map<Long, Long> orderDeviceIdPair = new HashMap<>();
        Map<Long, String> devicePair = new HashMap<>();
        // 任务列表
        Set<Long> taskIds = new HashSet<>();
        // 设备id列表
        Set<Long> totalDeviceIds = new HashSet<>();
        // 日报设备列表 key设备id   value设备信息
        Map<Long, String> reportDevicePair = new HashMap<>();
        // 日报设备列表 key任务id   value多个设备信息列表
        Map<Long, Set<Long>> taskDevicesPair = new HashMap<>();
        // 日报设备列表 key任务id   value多个设备信息 分号分隔
        Map<Long,String> taskDevicesStrPair = new HashMap<>();
        if (CollUtil.isNotEmpty(allOrder)) {
            Set<Long> orderIds = new HashSet<>();
            allOrder.forEach(order -> {
                if ("保养工单".equals(order.getType())) {
                    orderIds.add(order.getId());
                }
                if ("瑞都日报".equals(order.getType()) || "瑞鹰日报".equals(order.getType()) || "瑞恒日报".equals(order.getType())) {
                    taskIds.add(order.getTaskId());
                }
            });
            if (CollUtil.isNotEmpty(taskIds)) {
                IotProjectTaskPageReqVO reqVO = new IotProjectTaskPageReqVO();
                reqVO.setTaskIds(new ArrayList<>(taskIds));
                List<IotProjectTaskDO> tasks = iotProjectTaskMapper.selectList(reqVO);
                if (CollUtil.isNotEmpty(tasks)) {
                    tasks.forEach(task -> {
                        Set<Long> deviceIds = task.getDeviceIds();
                        if (CollUtil.isNotEmpty(deviceIds)) {
                            totalDeviceIds.addAll(deviceIds);
                            taskDevicesPair.put(task.getId(), task.getDeviceIds());
                        }
                    });
                }
                // 查询所有设备信息
                IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
                deviceReqVO.setDeviceIds(new ArrayList<>(totalDeviceIds));
                List<IotDeviceDO> devices = iotDeviceMapper.selectListAlone(deviceReqVO);
                if (CollUtil.isNotEmpty(devices)) {
                    devices.forEach(device -> {
                        reportDevicePair.put(device.getId(), StrUtil.join("|", device.getDeviceCode(), device.getDeviceName()));
                    });
                }
                // 建立日报关联的任务id 与 任务下所有设备 编码名称 的对应关系
                if (CollUtil.isNotEmpty(taskDevicesPair) && CollUtil.isNotEmpty(reportDevicePair)) {
                    for (Map.Entry<Long, Set<Long>> entry : taskDevicesPair.entrySet()) {
                        Long taskId = entry.getKey();
                        Set<Long> deviceIds = entry.getValue();

                        // 使用流处理获取设备名称，并用分号连接
                        String deviceStr = deviceIds.stream()
                                .map(reportDevicePair::get)  // 从 reportDevicePair 获取设备字符串
                                .filter(StrUtil::isNotBlank)  // 过滤掉空值
                                .collect(Collectors.joining(";"));  // 用分号连接

                        if (StrUtil.isNotBlank(deviceStr)) {
                            taskDevicesStrPair.put(taskId, deviceStr);
                        }
                    }
                }
            }
            if (CollUtil.isNotEmpty(orderIds)) {
                Set<Long> deviceIds = new HashSet<>();
                // 查询所有保养工单的设备名称
                IotMainWorkOrderBomPageReqVO bomReqVO = new IotMainWorkOrderBomPageReqVO();
                bomReqVO.setWorkOrderIds(new ArrayList<>(orderIds));
                List<IotMainWorkOrderBomDO> orderBoms = iotMainWorkOrderBomMapper.selectList(bomReqVO);
                if (CollUtil.isNotEmpty(orderBoms)) {
                    orderBoms.forEach(bom -> {
                        deviceIds.add(bom.getDeviceId());
                        orderDeviceIdPair.put(bom.getWorkOrderId(), bom.getDeviceId());
                    });
                    // 查询所有设备的编码 名称
                    IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
                    deviceReqVO.setDeviceIds(new ArrayList<>(deviceIds));
                    List<IotDeviceDO> devices = iotDeviceMapper.selectListAlone(deviceReqVO);
                    if (CollUtil.isNotEmpty(devices)) {
                        devices.forEach(device -> {
                            devicePair.put(device.getId(), StrUtil.join("|", device.getDeviceCode(), device.getDeviceName()));
                        });
                    }
                    orderDeviceIdPair.forEach((orderId, deviceId) -> {
                        if (devicePair.containsKey(deviceId)) {
                            orderPair.put(orderId, devicePair.get(deviceId));
                        }
                    });
                }
            }
        }
//        List<AllOrderResp> collect = allOrder.stream().map(e -> {
//            if ("巡检工单".equals(e.getType())){
//                String deviceInfo = iotInspectOrderDeviceMapper.getDeviceInfo(e.getId());
//                e.setDevice(deviceInfo);
//            } else if ("运行记录".equals(e.getType())) {
//                List<IotOpeationFillDO> orderId = iotOpeationFillMapper.getListByOrderId(e.getId());
//                StringJoiner joiner = new StringJoiner(", ");
//                for (IotOpeationFillDO fillDO : orderId) {
//                    joiner.add(fillDO.getDeviceCode() + "/" + fillDO.getDeviceName());
//                }
//                e.setDevice(joiner.toString());
//            }  else if ("保养工单".equals(e.getType())) {
//                if (orderPair.containsKey(e.getId())) {
//                    e.setDevice(orderPair.get(e.getId()));
//                }
//            } else if ("瑞都日报".equals(e.getType()) || "瑞鹰日报".equals(e.getType()) || "瑞恒日报".equals(e.getType())) {
//                // 设置日报的设备信息
//                if (taskDevicesStrPair.containsKey(e.getTaskId())) {
//                    e.setDevice(taskDevicesStrPair.get(e.getTaskId()));
//                }
//            }
//            return e;
//        }).collect(Collectors.toList());
        ExcelUtils.write(response, "工单完成情况.xls", "数据", AllOrderResp.class, allOrder);
    }
}
