package cn.iocoder.yudao.module.pms.service.iotopeationfill;

import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsRespVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.*;
import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceRespVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotcountdata.IotCountDataDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicecountdata.IotDeviceCountData;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicerunlog.IotDeviceRunLogDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs.IotModelTemplateAttrsDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillOrderDO;
import cn.iocoder.yudao.module.pms.dal.mysql.iotopeationfill.IotOpeationFillMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.iotopeationfill.IotOpeationFillOrderMapper;
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 org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import cn.iocoder.yudao.framework.common.pojo.PageResult;

import cn.iocoder.yudao.framework.common.util.object.BeanUtils;


import java.security.SecureRandom;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_OPEATION_FILL_NOT_EXISTS;

/**
 * 运行记录填报 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class IotOpeationFillServiceImpl implements IotOpeationFillService {

    @Resource
    private IotOpeationFillMapper iotOpeationFillMapper;
    @Resource
    private IotOpeationFillOrderMapper iotOpeationFillOrderMapper;
    @Resource
    private DeptService deptService;

    private static Long RH_CLASS_ID = 226L;

    private static Long RY_ZJ_CLASS_ID = 227L;

    private static Long RY_XJ_CLASS_ID = 228L;

    @Override
    public Long createIotOpeationFill(IotOpeationFillSaveReqVO createReqVO) {
        // 插入
        IotOpeationFillDO iotOpeationFill = BeanUtils.toBean(createReqVO, IotOpeationFillDO.class);
        iotOpeationFillMapper.insert(iotOpeationFill);
        // 返回
        return iotOpeationFill.getId();
    }

    @Override
    public void updateIotOpeationFill(IotOpeationFillSaveReqVO updateReqVO) {
        // 校验存在
        validateIotOpeationFillExists(updateReqVO.getId());
        // 更新
        IotOpeationFillDO updateObj = BeanUtils.toBean(updateReqVO, IotOpeationFillDO.class);
        iotOpeationFillMapper.updateById(updateObj);
    }

    @Override
    public void deleteIotOpeationFill(Long id) {
        // 校验存在
        validateIotOpeationFillExists(id);
        // 删除
        iotOpeationFillMapper.deleteById(id);
    }

    @Override
    public int upFill1(IotOpeationFillSaveReqVO vo) {
        int a = iotOpeationFillMapper.upFill1(vo);
        vo.setOrderId(vo.getId());
        iotOpeationFillMapper.upFill2(vo);
        return a;
    }

    @Override
    public int upFill2(IotOpeationFillSaveReqVO vo) {
        return iotOpeationFillMapper.upFill2(vo);
    }

    private void validateIotOpeationFillExists(Long id) {
        if (iotOpeationFillMapper.selectById(id) == null) {
            throw exception(IOT_OPEATION_FILL_NOT_EXISTS);
        }
    }

    @Override
    public IotOpeationFillDO getIotOpeationFill(Long id) {
        return iotOpeationFillMapper.selectById(id);
    }

    @Override
    public IotOpeationFillDO getFillById(IotOpeationFillDO fillDO) {
        return iotOpeationFillMapper.getFillById(fillDO);
    }

    @Override
    public PageResult<IotOpeationFillDO> getIotOpeationFillPage(IotOpeationFillPageReqVO pageReqVO) {
        return iotOpeationFillMapper.selectPage(pageReqVO);
    }


    @Override
    public List<IotOpeationFillDO> getFillDevices(List<Long> deviceIds) {
        return iotOpeationFillMapper.getFillDevices(deviceIds);
    }

    @Override
    public List<IotModelTemplateAttrsDO> getAttrsById(IotModelTemplateAttrsRespVO vo) {




        return iotOpeationFillMapper.getAttrsById(vo);
    }

    @Override
    public int insertFill(List<IotOpeationFillDO> vo) {
        return iotOpeationFillMapper.insertFill(vo);
    }

    @Override
    public List<IotOpeationFillDO> fillList(IotOpeationFillPageReqVO vo) {
        return iotOpeationFillMapper.fillList(vo);
    }

    @Override
    public List<IotOpeationFillDO> fillListByUserId(IotOpeationFillRespVO vo) {
        return iotOpeationFillMapper.fillListByUserId(vo);
    }

    @Override
    public IotOpeationFillDO selectRyFillReports(Long deptId, String reportDateStr) {
        return iotOpeationFillMapper.selectRyFillReports(deptId, reportDateStr);
    }

    @Override
    public IotOpeationFillDO selectRhFillReports(Long deptId, String reportDateStr) {
        return iotOpeationFillMapper.selectRhFillReports(deptId, reportDateStr);
    }


    @Override
    public PageResult<IotOpeationFillOrderDO> fillRecords(IotOpeationFillPageReqVO vo) {
        IPage<IotOpeationFillOrderDO> fillOrderDOIPage = iotOpeationFillMapper.fillRecords(Page.of(vo.getPageNo(), vo.getPageSize()),vo.getDeviceId(),vo.getOrderName(),vo.getOrderStatus());
        return new PageResult<>(fillOrderDOIPage.getRecords(),fillOrderDOIPage.getTotal());
    }

    @Override
    public PageResult<IotOpeationFillDO> fillListPage(IotOpeationFillPageVO vo) {

        IPage<IotOpeationFillDO> fillPage = iotOpeationFillMapper.fillListPage(Page.of(vo.getPageNo(), vo.getPageSize()),vo.getOrderId());

        return new PageResult<>(fillPage.getRecords(),fillPage.getTotal());
    }

    @Override
    public void syncWordOrderData(List<Long> deviceIds, List<Long> oldDeptIds, Long deptId) {
        /**
         * 1、判断设备
         */

        List<IotOpeationFillDO> fills = iotOpeationFillMapper.fills(deviceIds);
        if(fills.size()>0){
            iotOpeationFillMapper.upFill(deptId,deviceIds);
        }
    }

    @Override
    public List<IotOpeationFillDO> fillListByDeptId(IotOpeationFillRespVO vo) {
        return iotOpeationFillMapper.fillListByDeptId(vo);
    }

    @Override
    public IotOpeationFillDO devListByOrderId(IotOpeationFillRespVO vo) {
        return iotOpeationFillMapper.devListByOrderId(vo);
    }

    @Override
    public List<IotOpeationFillDO> deviceList(IotOpeationFillRespVO vo) {
        return iotOpeationFillMapper.deviceList(vo);
    }

    @Override
    public PageResult<IotOpeationFillOrderDO> fillList1(IotOpeationFillPageReqVO vo) {
        return iotOpeationFillOrderMapper.selectPage(vo);
    }

    @Override
    public List<IotOpeationFillDO> pdList1(IotOpeationFillDO vo) {
        return iotOpeationFillMapper.pdList1(vo);
    }

    @Override
    public List<IotOpeationFillDO> flList(IotOpeationFillDO vo) {
        return iotOpeationFillMapper.flList(vo);
    }

    @Override
    public PageResult<IotOpeationFillOrderDO> fillList2(IotOpeationFillPageReqVO vo, Collection<Long> deptIds) {
        IotOpeationFillRespVO fillRespVO = new IotOpeationFillRespVO();
        fillRespVO.setOrgName(vo.getOrderName());
        fillRespVO.setDeptId(vo.getDeptId());
        List<IotOpeationFillDO> fillList = iotOpeationFillMapper.getOrderIds(fillRespVO);
        List<Long> orderIds = fillList.stream().map(IotOpeationFillDO::getOrderId).collect(Collectors.toList());
        return iotOpeationFillOrderMapper.selectPage1(vo,deptIds,orderIds);
    }




    @Override
    public int insertLog(List<IotDeviceRunLogDO> logDO) {
        return iotOpeationFillMapper.insertLog(logDO);
    }

    @Override
    public int insertLog1(IotDeviceRunLogDO logDO) {
        return iotOpeationFillMapper.insertLog1(logDO);
    }

    @Override
    public int updateLog(IotDeviceRunLogDO logDO) {
        return iotOpeationFillMapper.updateLog(logDO);
    }

    @Override
    public int updateSumLog(IotDeviceRunLogDO logDO) {
        return iotOpeationFillMapper.updateSumLog(logDO);
    }

    @Override
    public int updateFill(IotOpeationFillSaveReqVO vo) {
        return iotOpeationFillMapper.updateFill(vo);
    }

    @Override
    public int batchUpdateFill(List<IotOpeationFillSaveReqVO> list) {
        return iotOpeationFillMapper.batchUpdateFill(list);
    }

    @Override
    public List<IotOpeationFillRespVO> getFillList(IotOpeationFillRespVO vo) {
        return iotOpeationFillMapper.getFillList(vo);
    }

    @Override
    public List<IotDeviceRunLogDO> getDeivceFillInfo(IotDeviceRunLogDO vo) {
        return iotOpeationFillMapper.getDeivceFillInfo(vo);
    }

    @Override
    public IotDeviceRunLogDO getLogInfo(IotDeviceRunLogDO vo) {
        return iotOpeationFillMapper.getLogInfo(vo);
    }

    @Override
    public IotDeviceRunLogDO getMaxFillInfo(IotDeviceRunLogDO vo) {
        return iotOpeationFillMapper.getMaxFillInfo(vo);
    }

    @Override
    public int updateFillOrder(IotDeviceRunLogDO vo) {
        return iotOpeationFillMapper.updateFillOrder(vo);
    }

    @Override
    public int updateFillOrder1(IotDeviceRunLogDO vo) {
        return iotOpeationFillMapper.updateFillOrder1(vo);
    }

    @Override
    public int updateFillOrder2(IotDeviceRunLogDO vo) {
        return iotOpeationFillMapper.updateFillOrder2(vo);
    }

    @Override
    public List<IotOpeationFillDO> devList(IotOpeationFillDO fillDO) {
        return iotOpeationFillMapper.devList(fillDO);
    }

    @Override
    public List<IotOpeationFillDO> orderList(IotOpeationFillDO fillDO) {
        return iotOpeationFillMapper.orderList(fillDO);
    }

    @Override
    public List<IotOpeationFillDO> delList(IotOpeationFillDO fillDO) {
        return iotOpeationFillMapper.delList(fillDO);
    }

    @Override
    public int delRepeat(IotOpeationFillDO fillDO) {
        return iotOpeationFillMapper.delRepeat(fillDO);
    }

    @Override
    public int delRepeatOrder(IotOpeationFillDO fillDO) {
        return iotOpeationFillMapper.delRepeatOrder(fillDO);
    }



    @Override
    public PageResult<IotDeviceRespVO> getFillDevices1(IotOpeationFillPageReqVO vo) {

        Set<Long> idList = new HashSet<>();
        if(Objects.nonNull(vo.getDeptId())){
            idList =  deptService.getChildDeptIdListFromCache(vo.getDeptId());
            idList.add(vo.getDeptId());
        }


        IPage<IotDeviceRespVO> fillOrderDOIPage = iotOpeationFillMapper.getFillDevices1(Page.of(vo.getPageNo(), vo.getPageSize()), idList);
        return new PageResult<>(fillOrderDOIPage.getRecords(),fillOrderDOIPage.getTotal());
    }

    @Override
    public PageResult<IotDeviceCountData> deviceCountList(IotOpeationFillPageReqVO vo) {
        IPage<IotDeviceCountData> countDataIPage = iotOpeationFillMapper.deviceCountList(Page.of(vo.getPageNo(),vo.getPageSize()),
                vo.getDeptId(),vo.getCreateTime(),vo.getIsFill(),vo.getOrderName());
        return new PageResult<>(countDataIPage.getRecords(),countDataIPage.getTotal());
    }

    @Override
    public List<IotCountDataDO> countList(IotCountDataDO dataDO) {
        return iotOpeationFillMapper.countList(dataDO);
    }

    @Override
    public List<IotCountDataDO> countDeviceList(IotCountDataDO dataDO) {
        return iotOpeationFillMapper.countDeviceList(dataDO);
    }

    @Override
    public List<IotOpeationFillDO> reportMethod(List<IotOpeationFillOrderDO> orderList) {
        List<IotOpeationFillDO> devList = new ArrayList<>();


        Set<Long> rhIdList = deptService.getChildDeptIdListFromCache(157L);
        rhIdList.add(157L);


        Set<Long> ryIdList =  deptService.getChildDeptIdListFromCache(158L);
        ryIdList.add(158L);


        //判断工单主数据是否有值
        if(orderList.size()>0){
            //遍历工单主数据，根据dept_id查询是否为小队
            for (IotOpeationFillOrderDO orderDO:orderList) {

                IotDeviceRunLogDO runLogDO = new IotDeviceRunLogDO();
                runLogDO.setDeptId(orderDO.getDeptId());
                //获取队伍类型
                IotDeviceRunLogDO teamType = iotOpeationFillMapper.getTeamType(runLogDO);

                List<IotOpeationFillOrderDO> childList = iotOpeationFillMapper.childList(orderDO);

                int randomNum;
                IotOpeationFillDO exitDev;
                IotOpeationFillDO fillDO = new IotOpeationFillDO();

                do {
                    // 生成8位随机整数
                    randomNum = generate8DigitInteger();
                    // 设置设备ID
                    fillDO.setDeviceId((long) randomNum);
                    // 检查数据库中是否已存在
                    exitDev = iotOpeationFillMapper.orderDO1(fillDO);
                } while (exitDev != null); // 如果存在则继续循环生成新的随机数


                //如果是小队，则证明该部门为小队，创建对应日报虚拟设备
                if(childList.size()==0){
                    IotOpeationFillDO devOrder = new IotOpeationFillDO();
                    devOrder.setDeviceCode("");
                    devOrder.setDeviceName("生产日报");

                    if(rhIdList.contains(orderDO.getDeptId())){
                        devOrder.setDeviceCategoryId(RH_CLASS_ID);
                    }else if(ryIdList.contains(orderDO.getDeptId())&&teamType!=null){
                        //队伍类型为zj则日报设备分类为钻井，否则为修井
                        if(teamType.getPointCode().equals("zj")){
                            devOrder.setDeviceCategoryId(RY_ZJ_CLASS_ID);
                        }else{
                            devOrder.setDeviceCategoryId(RY_XJ_CLASS_ID);
                        }
                    }

                    devOrder.setDeptId(orderDO.getDeptId());
                    devOrder.setIsReport(1);
                    devOrder.setOrderId(orderDO.getId());
                    devOrder.setDeviceId((long) randomNum);
                    devOrder.setCreateTime(orderDO.getCreateTime());
                    devList.add(devOrder);
                }
            }
        }

        return devList;
    }


    // 使用SecureRandom确保随机数的安全性
    private static final SecureRandom random = new SecureRandom();

    // 8位数字的最小值和最大值
    private static final int MIN_8_DIGIT = 10000000;  // 最小的8位整数
    private static final int MAX_8_DIGIT = 99999999;  // 最大的8位整数

    /**
     * 生成8位整型随机数
     * @return 8位整数（范围：10000000 - 99999999）
     */
    public static int generate8DigitInteger() {
        // 生成范围内的随机整数：[min, max]
        return MIN_8_DIGIT + random.nextInt(MAX_8_DIGIT - MIN_8_DIGIT + 1);
    }



    @Override
    public IotOpeationFillDO isReport(IotOpeationFillDO fillDO) {
        return iotOpeationFillMapper.isReport(fillDO);
    }

    @Override
    public IotOpeationFillDO orderDO(IotOpeationFillDO fillDO) {
        return iotOpeationFillMapper.orderDO(fillDO);
    }

    @Override
    public List<IotOpeationFillDO> reportList(IotOpeationFillDO fillDO) {
        return iotOpeationFillMapper.reportList(fillDO);
    }

    @Override
    public List<IotOpeationFillDO> reportList1(IotOpeationFillDO fillDO) {
        return iotOpeationFillMapper.reportList1(fillDO);
    }

    @Override
    public IotDeviceRunLogDO reportData(IotDeviceRunLogDO runLogDO) {
        return iotOpeationFillMapper.reportData(runLogDO);
    }

    @Override
    public List<IotDeviceRunLogDO> batchQueryExistingLogs(List<IotDeviceRunLogDO> logList) {
        return iotOpeationFillMapper.batchQueryExistingLogs(logList);
    }

    @Override
    public int batchInsertLogs(List<IotDeviceRunLogDO> logList) {
        return iotOpeationFillMapper.batchInsertLogs(logList);
    }

    @Override
    public int batchUpdateLogs(List<IotDeviceRunLogDO> logList) {
        return iotOpeationFillMapper.batchUpdateLogs(logList);
    }

    @Override
    public int batchUpdateSumLogs(List<IotDeviceRunLogDO> logList) {
        return iotOpeationFillMapper.batchUpdateSumLogs(logList);
    }

    @Override
    public IotDeviceRunLogDO maxReportData(IotDeviceRunLogDO runLogDO) {
        return iotOpeationFillMapper.maxReportData(runLogDO);
    }

    @Override
    public List<IotDeviceRunLogDO> batchQueryMaxReportData(List<IotDeviceRunLogDO> queryLogs) {
        return iotOpeationFillMapper.batchQueryMaxReportData(queryLogs);
    }

    @Override
    public IotDeviceRunLogDO reportData1(IotDeviceRunLogDO runLogDO) {
        return iotOpeationFillMapper.reportData1(runLogDO);
    }

    @Override
    public IotDeviceRunLogDO getDesc(IotDeviceRunLogDO runLogDO) {
        return iotOpeationFillMapper.getDesc(runLogDO);
    }

    @Override
    public List<IotDeviceRunLogDO> batchGetDescByPointNames(Set<String> pointNameSet) {
        return iotOpeationFillMapper.batchGetDescByPointNames(pointNameSet);
    }

    @Override
    public Map<Long, Integer> batchGetIsReport(List<IotOpeationFillDO> queries) {
        List<IotOpeationFillDO> result = iotOpeationFillMapper.batchGetIsReport(queries);
        Map<Long, Integer> map = result.stream()
                // 过滤 null 元素（避免空指针，可选但推荐）
                .filter(doObj -> doObj != null)
                // 生成 Map：Key 为 DO 的 Long 字段，Value 为 DO 的 Integer 字段
                .collect(Collectors.toMap(
                        // Key 映射：替换为你的实际字段 getter（如 getId()、getDeviceId()）
                        IotOpeationFillDO::getDeviceId,
                        // Value 映射：替换为你的实际字段 getter（如 getIsReport()、getStatus()）
                        IotOpeationFillDO::getIsReport,
                        // 冲突解决策略（可选）：若 Key 重复，取第一个值（或自定义逻辑）
                        (v1, v2) -> v1
                ));
        return map;
    }

    @Override
    public List<IotModelTemplateAttrsDO> getAttrsByIdBatch(List<IotModelTemplateAttrsRespVO> vos) {
        return iotOpeationFillMapper.getAttrsByIdBatch(vos);
    }

    @Override
    public List<IotDeviceRunLogDO> batchGetLogInfo(List<IotDeviceRunLogDO> queries) {
        return iotOpeationFillMapper.batchGetLogInfo(queries);
    }

    @Override
    public List<IotDeviceRunLogDO> batchGetMaxFillInfo(List<IotDeviceRunLogDO> queries) {
        return iotOpeationFillMapper.batchGetMaxFillInfo(queries);
    }

    @Override
    public List<IotDeviceRunLogDO> batchReportData(List<IotDeviceRunLogDO> queries) {
        return iotOpeationFillMapper.batchReportData(queries);
    }

    @Override
    public Map<Long, IotOpeationFillDO> batchGetOrderDO(List<IotOpeationFillDO> queries) {
        List<IotOpeationFillDO> result = iotOpeationFillMapper.batchGetOrderDO(queries);
        // 核心：替换 -> 后的 getXXX() 为实际的 Long 类型字段 getter 方法
        Map<Long, IotOpeationFillDO> fillDOMap = result.stream()
                // 第一个参数：Map 的 Key（取自 DO 的 Long 字段）
                // 第二个参数：Map 的 Value（DO 本身）
                .collect(Collectors.toMap(
                        IotOpeationFillDO::getDeviceId,  // 示例：用 id 作为 Key，替换为实际字段（如 getOrderId()）
                        Function.identity(),       // Value：DO本身（简化写法）
                        (oldValue, newValue) -> oldValue  // 重复Key时保留旧值（核心修复点）
                        // 可选：如需保留新值，改为 (oldValue, newValue) -> newValue           // Value 直接是 DO 实例（可简化为 Function.identity()）
                ));
        return fillDOMap;
    }

    @Override
    public List<IotOpeationFillDO> reportList2(IotOpeationFillDO fillDO) {
        return iotOpeationFillMapper.reportList2(fillDO);
    }

}
