package cn.iocoder.yudao.module.smartfactory.service.screendata;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.Month;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.enums.AssetsTypeCodeEnum;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factorydata.vo.FactoryDataTotalVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factoryforklift.vo.FactoryForkliftRespVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.screendata.factory.vo.*;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.device.cameradevice.CameraDeviceDO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factorydata.FactoryDataDO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factorydataoverview.FactoryDataOverviewDO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factoryforklift.FactoryForkliftDO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factoryinfo.FactoryInfoDO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factorykiln.FactoryKilnDO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factorypackingline.FactoryPackingLineDO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.packagedata.PackageDataDO;
import cn.iocoder.yudao.module.smartfactory.dal.mysql.factorydataoverview.FactoryDataOverviewMapper;
import cn.iocoder.yudao.module.smartfactory.dal.mysql.factoryforklift.FactoryForkliftMapper;
import cn.iocoder.yudao.module.smartfactory.dal.mysql.screendata.ScreenDataMapper;
import cn.iocoder.yudao.module.smartfactory.framework.util.HttpUtil;
import cn.iocoder.yudao.module.smartfactory.service.device.cameradevice.CameraDeviceService;
import cn.iocoder.yudao.module.smartfactory.service.factorydata.FactoryDataService;
import cn.iocoder.yudao.module.smartfactory.service.factoryinfo.FactoryInfoService;
import cn.iocoder.yudao.module.smartfactory.service.factorykiln.FactoryKilnService;
import cn.iocoder.yudao.module.smartfactory.service.factorypackingline.FactoryPackingLineService;
import cn.iocoder.yudao.module.smartfactory.service.hik.HikService;
import cn.iocoder.yudao.module.smartfactory.service.packagedata.PackageDataService;
import cn.iocoder.yudao.module.smartfactory.service.screenfactoryextra.ScreenFactoryExtraService;
import cn.iocoder.yudao.module.smartfactory.service.staff.StaffService;
import cn.iocoder.yudao.module.system.api.assets.AssetsTypeApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.vo.AdminUserRpcVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jodd.util.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 功能描述
 *
 * @author: yj
 * @date: 2024年03月06日 11:54
 */
@Service
@Validated
public class ScreenDataServiceImpl implements ScreenDataService {
    @Resource
    private FactoryInfoService factoryInfoService;
    @Resource
    private ScreenFactoryExtraService screenFactoryExtraService;
    @Resource
    private StaffService staffService;
    @Resource
    private PackageDataService packageDataService;
    @Resource
    private FactoryDataService factoryDataService;
    @Resource
    private FactoryDataOverviewMapper factoryDataOverviewMapper;

    @Resource
    private CameraDeviceService cameraDeviceService;

    @Resource
    private HikService hikService;

    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private FactoryKilnService factoryKilnService;
    @Resource
    private FactoryPackingLineService factoryPackingLineService;
    @Resource
    private AssetsTypeApi assetsTypeApi;
    @Resource
    private FactoryForkliftMapper factoryForkliftMapper;
    @Resource
    private ScreenDataMapper screenDataMapper;

    @Override
    public List<ProvincesDataRespVO> getProvincesData(String code) {
        return factoryInfoService.getProvincesData(code);
    }

    @Override
    public StaffDataRespVO getStaffData(Long factoryId) {
        return staffService.getStaffData(factoryId);
    }

    @Override
    public PropertyDataRespVO getPropertyData(Long factoryId) {
        return screenFactoryExtraService.getPropertyData(factoryId);
    }

    @Override
    public List<ScreenTotalDataVO> getFactoryOperateData(Long factoryId) {

        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 获取本周的开始日期（周一）
        LocalDate startOfWeek = currentDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        // 获取本周的结束日期（周日）
        LocalDate endOfWeek = currentDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
        // 获取本月的开始日期
        LocalDate startOfMonth = currentDate.with(TemporalAdjusters.firstDayOfMonth());
        // 获取本月的结束日期
        LocalDate endOfMonth = currentDate.with(TemporalAdjusters.lastDayOfMonth());

        // 获取今日出入库总数
        FactoryDataTotalVO toDayVO = factoryDataService.getDataTotal(factoryId, new LocalDate[]{currentDate, currentDate});
        // 设置今日出入数据
        ScreenTotalDataVO toDayTotalDataVO = new ScreenTotalDataVO()
                .setDateType(1)
                .setInNum(toDayVO.getInTotal())
                .setOutNum(toDayVO.getOutTotal())
                .setDamageNum(toDayVO.getDamageNum());

        // 获取昨日出入库总数
        FactoryDataTotalVO yesterdayVO = factoryDataService.getDataTotal(factoryId,
                new LocalDate[]{currentDate.minusDays(1), currentDate.minusDays(1)});
        // 设置昨日出入数据
        ScreenTotalDataVO yesterdayTotalDataVO = new ScreenTotalDataVO()
                .setDateType(2)
                .setInNum(yesterdayVO.getInTotal())
                .setOutNum(yesterdayVO.getOutTotal())
                .setDamageNum(yesterdayVO.getDamageNum());

        // 获取本周出入库总数
        FactoryDataTotalVO weekVO = factoryDataService.getDataTotal(factoryId, new LocalDate[]{startOfWeek, endOfWeek});
        // 设置本周出入数据
        ScreenTotalDataVO weekTotalDataVO = new ScreenTotalDataVO()
                .setDateType(3)
                .setInNum(weekVO.getInTotal())
                .setOutNum(weekVO.getOutTotal())
                .setDamageNum(weekVO.getDamageNum());

        // 获取本月出入库总数
        FactoryDataTotalVO monthVO = factoryDataService.getDataTotal(factoryId, new LocalDate[]{startOfMonth, endOfMonth});
        // 设置本月出入数据
        ScreenTotalDataVO monthTotalDataVO = new ScreenTotalDataVO()
                .setDateType(4)
                .setInNum(monthVO.getInTotal())
                .setOutNum(monthVO.getOutTotal())
                .setDamageNum(monthVO.getDamageNum());

        return Arrays.asList(toDayTotalDataVO, yesterdayTotalDataVO, weekTotalDataVO, monthTotalDataVO);
    }

    @Override
    public List<FactoryRollDataRespVO> getFactoryRollData() {
        return factoryInfoService.getFactoryRollData();
    }

    @Override
    public List<FactoryCameraDataRespVO> getFactoryCamerasData(Long factoryId) {

        List<CameraDeviceDO> cameraDeviceDOS = cameraDeviceService.getListCameraByFactoryId(factoryId);
        cameraDeviceDOS.forEach(data -> {

            String url = hikService.getPreviewUrlsApi(data.getCode(), 1);
            if (!StringUtil.isEmpty(url)) {
                data.setStreamUrl(url);
            }
        });
        return BeanUtils.toBean(cameraDeviceDOS, FactoryCameraDataRespVO.class);
    }


    private static final String WEATHER_URL = "https://d1.weather.com.cn/sk_2d/";
    private static final String REFERER = "referer";
    private static final String REFERER_URL = "http://www.weather.com.cn/";
    private static final String WEATHER_SPLIT = "dataSK=";

    @Override
    public FactoryWeatherDataRespVO getFactoryWeatherInfo(Long factoryId) {
        //根据factoryId 查询areaCode;
        // 通过工厂id获取到天气数据code
        FactoryInfoDO factoryInfoDO = factoryInfoService.getFactoryInfo(factoryId);
        if (factoryInfoDO != null) {
            String areaCode = "";
            if (factoryInfoDO.getAdCode() != null) {
                areaCode = factoryInfoService.getWeatherCodeByFactoryId(factoryId, String.valueOf(factoryInfoDO.getAdCode()));
            } else if (StrUtil.isEmpty(areaCode)) {
                areaCode = factoryInfoService.getWeatherCodeByFactoryId(factoryId, String.valueOf(factoryInfoDO.getCityId()));
            } else if (StrUtil.isEmpty(areaCode)) {
                areaCode = factoryInfoService.getWeatherCodeByFactoryId(factoryId, String.valueOf(factoryInfoDO.getProvinceId()));
            } else {
                return null;
            }
            String url = WEATHER_URL + areaCode + ".html";
            Map<String, String> headers = new HashMap<>();
            headers.put(REFERER, REFERER_URL);
            String result = HttpUtil.doGetSetHeader(url, headers);
            String[] str = result.split(WEATHER_SPLIT);
            if (str.length > 1) {
                FactoryWeatherDataRespVO vo = new FactoryWeatherDataRespVO();
                JSONObject jsonObject = JSONUtil.parseObj(str[1]);
                vo.setFactoryId(factoryId);
                vo.setAreaCode(areaCode);
                vo.setTemperature(jsonObject.getStr("temp")); //温度
                vo.setHumidity(jsonObject.getStr("sd"));       //湿度
                vo.setWeather(jsonObject.getStr("weather"));  //天气
                vo.setDate(jsonObject.getStr("date"));         //日期
                return vo;
            } else {
                return null;
            }
        }
        return null;
    }

    @Override
    public List<FactoryPackLineInfoVO> getFactoryPackLineInfo(Long factoryId) {
        List<FactoryPackLineInfoVO> vos = new ArrayList<>();
        List<PackageDataDO> list = packageDataService.getFactoryPackLineInfo(factoryId);
        Map<Long, List<PackageDataDO>> map = list.stream().collect(Collectors.groupingBy(PackageDataDO::getSizeId));
        Date today = new Date();
        //本日打包数
        Date beginDay = DateUtil.beginOfDay(today);
        Date endDay = DateUtil.endOfDay(today);
        List<PackageDataDO> todayList = packageDataService.getFactoryPackLineInfoByTime(factoryId, beginDay, endDay);
        Map<Long, List<PackageDataDO>> todayMap = todayList.stream().collect(Collectors.groupingBy(PackageDataDO::getSizeId));
        //本周打包數
        Date beginWeek = DateUtil.beginOfWeek(today);
        Date endWeek = DateUtil.endOfWeek(today);
        List<PackageDataDO> weekList = packageDataService.getFactoryPackLineInfoByTime(factoryId, beginWeek, endWeek);
        Map<Long, List<PackageDataDO>> weekMap = weekList.stream().collect(Collectors.groupingBy(PackageDataDO::getSizeId));

        //本月打包數
        Date beginMonth = DateUtil.beginOfMonth(today);
        Date endMonth = DateUtil.endOfMonth(today);
        List<PackageDataDO> monthList = packageDataService.getFactoryPackLineInfoByTime(factoryId, beginMonth, endMonth);
        Map<Long, List<PackageDataDO>> monthMap = monthList.stream().collect(Collectors.groupingBy(PackageDataDO::getSizeId));

        for (Long id : map.keySet()) {
            PackageDataDO item = map.get(id).get(0);
            FactoryPackLineInfoVO vo = new FactoryPackLineInfoVO();
            vo.setId(item.getSizeId());
            vo.setName(item.getSizeName());
            List<PackageDataDO> todayItemList = todayMap.get(item.getSizeId());
            if (!CollUtil.isEmpty(todayItemList)) {
                vo.setDayNum(todayItemList.stream().mapToInt(PackageDataDO::getNum).sum());
            }
            List<PackageDataDO> weekItemList = weekMap.get(item.getSizeId());
            if (!CollUtil.isEmpty(weekItemList)) {
                vo.setWeekNum(weekItemList.stream().mapToInt(PackageDataDO::getNum).sum());
            }
            List<PackageDataDO> monthItemList = monthMap.get(item.getSizeId());
            if (!CollUtil.isEmpty(monthItemList)) {
                vo.setMonthNum(monthItemList.stream().mapToInt(PackageDataDO::getNum).sum());
            }
            vos.add(vo);
        }
        return vos;
    }

    @Override
    public String getAliYunGeo(String code, Integer type) {
        String url = "";
        if (type == 1) {
            url = "https://geo.datav.aliyun.com/areas_v3/bound/%s_full.json";
        } else {
            url = "https://geo.datav.aliyun.com/areas_v3/bound/%s.json";
        }
        url = String.format(url, code);
        return cn.hutool.http.HttpUtil.get(url);
    }

    @Override
    public DataOverviewVO getDataOverview(Long factoryId) {
        DataOverviewVO vo = new DataOverviewVO();
//        List<ScreenFactoryExtraDO> extras = screenFactoryExtraService.list();
//        List<FactoryDataOverviewDO> list = factoryDataOverviewService.list();
        //获取工厂列表

        List<FactoryInfoDO> factoryList = factoryInfoService.getFactoryList(Collections.singletonList(factoryId));
        Map<Long, FactoryInfoDO> factoryMap = factoryList.stream().collect(Collectors.toMap(FactoryInfoDO::getId, v -> v));
        // ----------------------------------  用户 ----------------------------------
        // -- 通过工厂id获取部门列表 -> 再通过部门列表获取用户列表
        List<AdminUserRpcVO> users = adminUserApi.getFactoryUsers(factoryId).getData();
        int total = 0;
        int femaleTotal = 0;
        int maleTotal = 0;
        if (CollectionUtil.isNotEmpty(users)) {
            total = users.size();
            femaleTotal = (int) users.stream().filter(a -> a.getSex() == 2).count();
            maleTotal = users.size() - femaleTotal;
        } else {
            users = Collections.emptyList();
        }
        vo.setTotal(total);
        vo.setFemaleTotal(femaleTotal);
        vo.setMaleTotal(maleTotal);
        vo.setUsers(users);

        // ----------------------------------  窑炉 ----------------------------------
        List<FactoryKilnDO> factoryKilnDOS = factoryKilnService.getFactoryKilnByFactoryId(factoryId);
        vo.setYlNum(factoryKilnDOS.size());
        vo.setYlCapacity(factoryKilnDOS.stream().map(FactoryKilnDO::getCapacity).reduce(BigDecimal.ZERO, BigDecimal::add));
        Map<Long, List<FactoryKilnDO>> factoryKilnMap = factoryKilnDOS.stream().collect(Collectors.groupingBy(FactoryKilnDO::getFactoryId));
        List<FactoryKilnVO> factoryKilnList = new ArrayList<>();
        for (Map.Entry<Long, List<FactoryKilnDO>> entry : factoryKilnMap.entrySet()) {
            FactoryKilnVO factoryKilnVO = new FactoryKilnVO();
            factoryKilnVO.setFactoryId(entry.getKey());
            factoryKilnVO.setFactoryName(factoryMap.get(entry.getKey()) == null ? "未分配到工厂部门" : factoryMap.get(entry.getKey()).getName());
            factoryKilnVO.setNumber(entry.getValue().size());
            BigDecimal totalCapacity = entry.getValue().stream()
                    .filter(f -> f.getCapacity() != null)
                    .map(FactoryKilnDO::getCapacity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            factoryKilnVO.setCapacity(totalCapacity);
            factoryKilnList.add(factoryKilnVO);
        }
        vo.setFactoryKilnList(factoryKilnList);
        // ----------------------------------  打包线 ----------------------------------
        List<FactoryPackingLineDO> factoryPackingLineDOS = factoryPackingLineService.getFactoryPackingLineByFactoryId(Collections.singletonList(factoryId));
        Map<Long, List<FactoryPackingLineDO>> factoryPackingLineMap = factoryPackingLineDOS.stream().collect(Collectors.groupingBy(FactoryPackingLineDO::getFactoryId));
        vo.setDbxNum(factoryPackingLineDOS.size());
        List<FactoryPackingLineVO> FactoryPackingLineList = new ArrayList<>();
        for (Map.Entry<Long, List<FactoryPackingLineDO>> entry : factoryPackingLineMap.entrySet()) {
            FactoryPackingLineVO factoryPackingLineVO = new FactoryPackingLineVO();
            factoryPackingLineVO.setFactoryId(entry.getKey());
            factoryPackingLineVO.setFactoryName(factoryMap.get(entry.getKey()).getName());
            factoryPackingLineVO.setNumber(entry.getValue().size());
            FactoryPackingLineList.add(factoryPackingLineVO);
        }
        vo.setFactoryPackingLineList(FactoryPackingLineList);

        // ----------------------------------  叉车 ----------------------------------
        List<ForkliftVO> forkliftList = new ArrayList<>();
        List<Long> forkliftOilTypeIds = assetsTypeApi.getAssetsTypeIdsByCode(AssetsTypeCodeEnum.FORKLIFT_OIL).getData();
        List<Long> forkliftElectricityTypeIds = assetsTypeApi.getAssetsTypeIdsByCode(AssetsTypeCodeEnum.FORKLIFT_ELECTRICITY).getData();
        List<FactoryForkliftRespVO> factoryForkliftOil = factoryForkliftMapper.getFactoryForkliftByFactoryIdAndTypeIds(Collections.singletonList(factoryId), forkliftOilTypeIds);
        List<FactoryForkliftRespVO> forkliftElectricity = factoryForkliftMapper.getFactoryForkliftByFactoryIdAndTypeIds(Collections.singletonList(factoryId), forkliftElectricityTypeIds);
        vo.setForkliftTotal(factoryForkliftOil.size() + forkliftElectricity.size());

        // -- 插入未分配数量
        List<FactoryForkliftRespVO> notAllocatedFactoryForkliftOil = factoryForkliftOil.stream().filter(a -> a.getFactoryId() == null).collect(Collectors.toList());
        List<FactoryForkliftRespVO> notAllocatedForkliftElectricity = forkliftElectricity.stream().filter(a -> a.getFactoryId() == null).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(notAllocatedFactoryForkliftOil) || CollectionUtil.isNotEmpty(notAllocatedForkliftElectricity)) {
            forkliftList.add(new ForkliftVO().setFactoryName("未分配")
                    .setTotalNum(notAllocatedFactoryForkliftOil.size() + notAllocatedForkliftElectricity.size())
                    .setOilNum(notAllocatedFactoryForkliftOil.size())
                    .setElectricityNum(notAllocatedForkliftElectricity.size()));
        }
        List<FactoryForkliftRespVO> allocatedFactoryForkliftOil = factoryForkliftOil.stream().filter(a -> a.getFactoryId() != null).collect(Collectors.toList());
        List<FactoryForkliftRespVO> allocatedForkliftElectricity = forkliftElectricity.stream().filter(a -> a.getFactoryId() != null).collect(Collectors.toList());
        Map<Long, List<FactoryForkliftRespVO>> allocatedFactoryForkliftOilMap = allocatedFactoryForkliftOil.stream().collect(Collectors.groupingBy(FactoryForkliftRespVO::getFactoryId));
        Map<Long, List<FactoryForkliftRespVO>> allocatedForkliftElectricityMap = allocatedForkliftElectricity.stream().collect(Collectors.groupingBy(FactoryForkliftRespVO::getFactoryId));


        List<Long> allocatedFactoryForkliftOilFactoryIdIds = allocatedFactoryForkliftOil.stream().map(FactoryForkliftRespVO::getFactoryId).collect(Collectors.toList());
        List<Long> allocatedForkliftElectricityFactoryIdIds = allocatedForkliftElectricity.stream().map(FactoryForkliftRespVO::getFactoryId).collect(Collectors.toList());
        Set<Long> mergeFactoryIdIds = CollectionUtil.unionDistinct(allocatedFactoryForkliftOilFactoryIdIds, allocatedForkliftElectricityFactoryIdIds);

        for (Long mergeFactoryIdId : mergeFactoryIdIds) {
            FactoryInfoDO factoryInfoDO = factoryMap.get(mergeFactoryIdId);
            if (factoryInfoDO != null) {
                List<FactoryForkliftRespVO> allocatedFactoryForkliftOilItems = allocatedFactoryForkliftOilMap.get(mergeFactoryIdId);
                List<FactoryForkliftRespVO> allocatedForkliftElectricityItems = allocatedForkliftElectricityMap.get(mergeFactoryIdId);
                Integer oilNum = CollectionUtil.isNotEmpty(allocatedFactoryForkliftOilItems) ? allocatedFactoryForkliftOilItems.size() : 0;
                Integer electricityNum = CollectionUtil.isNotEmpty(allocatedForkliftElectricityItems) ? allocatedForkliftElectricityItems.size() : 0;
                forkliftList.add(new ForkliftVO().setFactoryName(factoryInfoDO.getName())
                        .setTotalNum(oilNum + electricityNum)
                        .setOilNum(oilNum)
                        .setElectricityNum(electricityNum));
            }
        }
        vo.setForkliftList(forkliftList);
        // -- 工厂叉车列表
        List<FactoryForkliftDO> factoryForkliftDOS = new ArrayList<>();
        if (factoryId != null) {
            factoryForkliftDOS = factoryForkliftMapper.selectList(new LambdaQueryWrapper<FactoryForkliftDO>().eq(FactoryForkliftDO::getFactoryId, factoryId));
        }
        vo.setFactoryForkliftList(factoryForkliftDOS);

        // ----------------------------------  托盘 ----------------------------------
        List<Long> trayAssetsTypeIds = assetsTypeApi.getAssetsTypeIdsByCode(AssetsTypeCodeEnum.TRAY).getData();
        List<AssetsStockVO> trayList = screenDataMapper.getAssetsNumByFactoryIdAndTypeIds(Collections.singletonList(factoryId), trayAssetsTypeIds);
        vo.setTpNum(trayList.stream().mapToInt(AssetsStockVO::getStock).sum());
        vo.setTrayList(trayList);


        // ----------------------------------  绑带 ----------------------------------
        List<Long> strapsAssetsTypeIds = assetsTypeApi.getAssetsTypeIdsByCode(AssetsTypeCodeEnum.STRAPS).getData();
        List<AssetsStockVO> strapsList = screenDataMapper.getAssetsNumByFactoryIdAndTypeIds(Collections.singletonList(factoryId), strapsAssetsTypeIds);
        vo.setBdNum(strapsList.stream().mapToInt(AssetsStockVO::getStock).sum());
        vo.setStrapsList(strapsList);

        // ----------------------------------  摄像头 ----------------------------------
        List<CameraVO> cameraVOS = new ArrayList<>();
        List<CameraDeviceDO> cameraDeviceDOS = cameraDeviceService.getListCameraByFactoryId(factoryId);
        Map<Long, List<CameraDeviceDO>> cameraDeviceMaps = cameraDeviceDOS.stream().collect(Collectors.groupingBy(CameraDeviceDO::getFactoryId));
        for (Map.Entry<Long, List<CameraDeviceDO>> entry : cameraDeviceMaps.entrySet()) {
            CameraVO cameraVO = new CameraVO();
            cameraVO.setFactoryId(entry.getKey());
            cameraVO.setFactoryName(factoryMap.get(entry.getKey()).getName());
            cameraVO.setNumber(entry.getValue().size());
            cameraVOS.add(cameraVO);
        }
        vo.setCameraNum(cameraDeviceDOS.size());
        vo.setCameraVOS(cameraVOS);

//
//        vo.setForkliftTotal(list.stream().mapToInt(FactoryDataOverviewDO::getTruckTotalNum).sum());
//        vo.setTruckOnNum(extras.stream().mapToInt(ScreenFactoryExtraDO::getTruckOnNum).sum());
//        vo.setTruckOffNum(extras.stream().mapToInt(ScreenFactoryExtraDO::getTruckOffNum).sum());
//
//        vo.setTpNum(list.stream().mapToInt(FactoryDataOverviewDO::getTpNum).sum());
//        vo.setBdNum(list.stream().mapToInt(FactoryDataOverviewDO::getBdNum).sum());


        List<FactoryDataDO> factoryDataDOS = factoryDataService.getTodayInboundAndOutboundOverview(null);
        Integer outTotalNum = factoryDataDOS.stream().filter(a -> a.getDataType() == 1).mapToInt(FactoryDataDO::getTotalNum).sum();
        Integer inTotalNum = factoryDataDOS.stream().filter(a -> a.getDataType() == 2).mapToInt(FactoryDataDO::getTotalNum).sum();
        vo.setOutTotalNum(outTotalNum);
        vo.setInTotalNum(inTotalNum);
        return vo;
    }

    @Override
    public List<InboundAndOutboundOverviewVO> getInboundAndOutboundOverview() {
        List<InboundAndOutboundOverviewVO> vos = new ArrayList<>();
        //获取当天的所有数据
        List<FactoryDataDO> list = factoryDataService.getTodayInboundAndOutboundOverview(new Date());
        //根据工厂分组
        Map<Long, List<FactoryDataDO>> map = list.stream().collect(Collectors.groupingBy(FactoryDataDO::getFactoryId));
        List<FactoryInfoDO> factoryInfos = factoryInfoService.list();
        Map<Long, List<FactoryInfoDO>> factoryInfoMap = factoryInfos.stream().collect(Collectors.groupingBy(FactoryInfoDO::getId));
        for (Map.Entry<Long, List<FactoryDataDO>> entry : map.entrySet()) {
            List<FactoryDataDO> items = entry.getValue();
            Integer outTotalNum = items.stream().filter(a -> a.getDataType() == 1).mapToInt(FactoryDataDO::getTotalNum).sum();
            Integer inTotalNum = items.stream().filter(a -> a.getDataType() == 2).mapToInt(FactoryDataDO::getTotalNum).sum();
            List<FactoryInfoDO> itemDo = factoryInfoMap.get(entry.getKey());
            if (!CollUtil.isEmpty(itemDo)) {
                InboundAndOutboundOverviewVO vo = new InboundAndOutboundOverviewVO();
                vo.setName(itemDo.get(0).getShortName());
                vo.setOutTotalNum(outTotalNum);
                vo.setInTotalNum(inTotalNum);
                vos.add(vo);
            }
        }
        // -- list排序
        vos = vos.stream()
                .sorted(Comparator.comparingInt(InboundAndOutboundOverviewVO::getInTotalNum).reversed())
                .collect(Collectors.toList());
        return vos;
    }

    @Override
    public List<ExcellentRateRankingVO> excellentRateRanking() {
        List<ExcellentRateRankingVO> list = new ArrayList<>();
        List<FactoryInfoDO> factoryInfos = factoryInfoService.list();
        for (FactoryInfoDO factoryInfo : factoryInfos) {
            // 创建 Random 对象
            Random random = new Random();
            // 生成 90 到 100 之间的随机数（包括 90 和 100）
            double randomNumber = random.nextDouble() * 11 + 85;
            // 将随机数保留两位小数
            randomNumber = Math.round(randomNumber * 100.0) / 100.0;
            if (randomNumber > 100) {
                randomNumber = 100.00;
            }
            ExcellentRateRankingVO vo = new ExcellentRateRankingVO();
            vo.setName(factoryInfo.getName());
            vo.setExcellentRate(randomNumber);
            list.add(vo);
        }
        // -- list排序
        list = list.stream()
                .sorted(Comparator.comparingDouble(ExcellentRateRankingVO::getExcellentRate).reversed())
                .collect(Collectors.toList());
        return list;
    }

    @Override
    public List<EnergyConservationVO> energyConservation(Long factoryId) {
        List<EnergyConservationVO> vos = new ArrayList<>();
        List<FactoryInfoDO> factoryInfos = factoryInfoService.list();
        List<Long> ids = factoryInfos.stream().map(FactoryInfoDO::getId).collect(Collectors.toList());
        List<FactoryDataOverviewDO> dos = factoryDataOverviewMapper.selectList(new LambdaQueryWrapperX<FactoryDataOverviewDO>()
                .in(FactoryDataOverviewDO::getFactoryId, ids));
        Map<Long, List<FactoryDataOverviewDO>> doMaps = dos.stream().collect(Collectors.groupingBy(FactoryDataOverviewDO::getFactoryId));
        if (factoryId != null) {
            Map<Long, List<FactoryInfoDO>> map = factoryInfos.stream().collect(Collectors.groupingBy(FactoryInfoDO::getId));
            List<FactoryInfoDO> items = map.get(factoryId);
            if (!CollUtil.isEmpty(items)) {
                for (int i = 0; i < 3; i++) {
                    Month month = DateUtil.monthEnum(DateUtil.offsetMonth(DateUtil.date(), -i));
                    EnergyConservationVO vo = new EnergyConservationVO();
                    vo.setName(items.get(0).getShortName());
                    vo.setTime((month.getValue() == 0 ? "12" : String.valueOf(month.getValue())) + "月");
                    Random random = new Random();
                    // 生成50到100之间的随机数
                    int randomNumber = random.nextInt(51) + 50;
                    vo.setEmissions(randomNumber);
                    List<FactoryDataOverviewDO> doItems = doMaps.get(items.get(0).getId());
                    if (CollUtil.isNotEmpty(doItems)) {
                        vo.setForkliftTotal(doItems.get(0).getTruckTotalNum());
                    } else {
                        vo.setForkliftTotal(0);
                    }
                    vos.add(vo);
                }
            }
        } else {
            for (FactoryInfoDO factoryInfo : factoryInfos) {
                EnergyConservationVO vo = new EnergyConservationVO();
                vo.setName(factoryInfo.getShortName());
                //vo.setTime(String.valueOf(factoryInfo.getValue()));
                Random random = new Random();
                // 生成50到100之间的随机数
                int randomNumber = random.nextInt(51) + 50;
                vo.setEmissions(randomNumber);
                List<FactoryDataOverviewDO> doItems = doMaps.get(factoryInfo.getId());
                if (CollUtil.isNotEmpty(doItems) && doItems.get(0).getTruckTotalNum() != null && doItems.get(0).getTruckTotalNum() > 0) {
                    vo.setForkliftTotal(doItems.get(0).getTruckTotalNum());
                    vos.add(vo);
                }
            }
        }
        Collections.reverse(vos);
        return vos;
    }

    @Override
    public ObtainFactoryInboundAndOutboundStatusVO getObtainFactoryInboundAndOutboundStatus(Long factoryId) {
        ObtainFactoryInboundAndOutboundStatusVO vo = new ObtainFactoryInboundAndOutboundStatusVO();

        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 获取本月的开始日期
        LocalDate startOfMonth = currentDate.with(TemporalAdjusters.firstDayOfMonth());
        // 获取本月的结束日期
        LocalDate endOfMonth = currentDate.with(TemporalAdjusters.lastDayOfMonth());

        // 获取今日出入库总数
        FactoryDataTotalVO toDayVO = factoryDataService.getDataTotal(factoryId, new LocalDate[]{currentDate, currentDate});
        vo.setOutToday(toDayVO.getOutTotal());
        vo.setInToday(toDayVO.getInTotal());

        //本月打包數
        FactoryDataTotalVO monthVO = factoryDataService.getDataTotal(factoryId, new LocalDate[]{startOfMonth, endOfMonth});
        vo.setOutMonth(monthVO.getOutTotal());
        vo.setInMonth(monthVO.getInTotal());

        // 获取昨日出入库总数
        FactoryDataTotalVO yesterdayVO = factoryDataService.getDataTotal(factoryId,
                new LocalDate[]{currentDate.minusDays(1), currentDate.minusDays(1)});

        // 设置今日破损数
        vo.setDamagedTotal(toDayVO.getDamageNum());

        // 设置同昨日比较 百分比
        double increaseCompared = Math.round(toDayVO.getDamageNum() == null ? 0 : toDayVO.getDamageNum() -
                (yesterdayVO.getDamageNum() == null ? 0 : yesterdayVO.getDamageNum()) * 100.0) / 100.0; // 保留两位小数
        vo.setIncreaseCompared(increaseCompared);

        return vo;
    }

    @Override
    public StaffDataRespVO getStaffDataV2(Long factoryId) {
        return staffService.getStaffDataV2(factoryId);
    }
}
