<template>
  <div class="timeline-container">
    <div class="timeline-header">
      <div class="timeline-controls">
        <div>时间轴</div>
        <div class="block">
          <span class="demonstration">时间段</span>

          <el-date-picker v-model="dateRange" type="daterange" popper-class="custom-date-picker" unlink-panels
            range-separator="→" start-placeholder="开始日期" end-placeholder="结束日期" :disabled-date="disabledDate"
            @change="pick_select_date_handFn" :popper-options="{
              placement: 'bottom-start',
              modifiers: [
                {
                  name: 'offset',
                  options: {
                    offset: [-650, -125] // [水平偏移, 垂直偏移]
                  }
                }
              ]
            }" />
          <div class="right_block">
            <!--限制 :disabled="!is_flag_confirmAndPauseAndSpeed" -->
            <el-button class="right_block_confirm_btn" size="small"
              @click="handleDateRangeChange(pick_select_date, false, true, 1)">确认</el-button>
            <div class="right_block_center">
              <!-- <el-button circle class="right_block_conter_btn" @click="playBackward">
                <el-icon>
                  <img src="@/assets/images/footers/videoPlay_left.png" alt="" style="width: 8px; height: 10px;" />
                </el-icon>
              </el-button> -->
              <!--限制 :disabled="!is_flag_confirmAndPauseAndSpeed" -->
              <el-button circle class="right_block_conter_btn_center" @click="toggleAutoPlay">
                <el-icon>
                  <img v-if="!isPlaying" src="@/assets/images/footers/videoPause.png" alt=""
                    style="width: 8px; height: 10px;" />
                  <img v-if="isPlaying" src="@/assets/images/footers/videoPlay.png" alt=""
                    style="width: 8px; height: 10px;" />
                </el-icon>
              </el-button>
            </div>
            <!-- 倍速选择 -->
            <el-select v-model="playbackSpeed" style="width: 70px" class="satellite-select"
              :disabled="is_flag_isRealtime">
              <el-option v-for="item in playbackSpeedOptions" :key="item.value" :label="item.label" :value="item.value"
                @click="() => {
                  //console.log('我是喧杂',playbackSpeed);
                  changeSpeed()
                }" />
            </el-select>
            <div v-if="!is_flag_isRealtime" class="resetClass" @click="resetclick">重置模式</div>
          </div>
        </div>
      </div>
    </div>

    <!-- 时间轴主体 -->
    <div class="timeline">
      <!-- 时间轴内容区域 -->
      <div class="timeline-content">
        <!-- 时间刻度 -->
        <div class="time-markers">
          <div v-for="(marker, index) in timeMarkers" :key="index" class="time-marker"
            :style="{ left: marker.position + '%' }">
            <div class="marker-line"
              :class="{ 'major-line': marker.isMajor, 'minor-line_color': (index) % showLengthmarkerLine === 0 || index === timeMarkers.length - 1 }">
            </div>
            <span class="marker-label" :class="{ 'selected-label': isMarkerInSelectedRange(marker) }"
              v-if="((index) % showLength === 0 || index === timeMarkers.length - 1)" v-html="marker.label"></span>
          </div>
        </div>

        <!-- 滑块和选中区域 -->
        <div class="slider-container">
          <div class="slider-track" ref="sliderTrack">
            <div class="selected-range" :style="selectedRangeStyle"></div>

            <!-- 开始滑块 -->
            <div class="slider-handle start-handle" :style="{ left: startHandlePosition }">
              <div class="handle-rail"></div>
              <div class="handle-tooltip">
                <div>{{ formatDateTime(selectedStartTime)?.split(' ')[1] }}</div>
                <div>{{ formatDateTime(selectedStartTime)?.split(' ')[0] }}</div>
              </div>
            </div>

            <!-- 结束滑块 -->
            <div class="slider-handle end-handle" :style="{ left: endHandlePosition }"
              @mousedown="startDrag('end', $event)">
              <div class="handle-rail">
                <div class="handle-tooltip" :class="{ 'handle-tooltip_auto': !is_flag_isRealtime }">
                  <div>{{ formatDateTime(selectedEndTime)?.split(' ')[1] }}</div>
                  <div>{{ formatDateTime(selectedEndTime)?.split(' ')[0] }}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ElLoading, ElMessage } from 'element-plus'
import Loading from '@/pages/all/components/loadingComponent/index.js'
import { ref, onMounted, onUnmounted, computed, watch, nextTick, watchEffect } from 'vue';
import wss from '@/utils/requestSocekt.js'
import { getTimewss, createWebSocket } from '@/utils/requestSocektTime.js'
import useAppStore from '@/store/module/app'
import dayjs from 'dayjs';

const wssInstance = ref(wss)
let wsTimeInstance = ""; //时间ws实例
// import { loading } from 'vxe-pc-ui';
// 用于表示速度改变时，正常数据返回后才能够再次改变速度
const speedChangedNormalDataBack = ref(false)
const playbackSpeedOptions = ref([
  {
    value: 1,
    label: '1x'
  },
  {
    value: 2,
    label: '2x'
  },
  {
    value: 4,
    label: '4x'
  },
  {
    value: 8,
    label: '8x'
  },
  {
    value: 10,
    label: '10x'
  },
])
const useAppStoreInstance = useAppStore();

// const is_flag_confirmAndPauseAndSpeed = ref(true)
// 跳转到指定时间点
const jumpToSpecificTime = (targetTime, PerformDrag = false) => {
  console.log('跳转到指定时间点:', targetTime);
  try {
    if (!startDateTime.value || !endDateTime.value) {
      ElMessage.error('时间轴未初始化');
      return false;
    }
    const start = new Date(startDateTime.value).getTime();
    const end = new Date(endDateTime.value).getTime();
    const totalMs = totalMilliseconds.value;

    // 校验目标时间是否有效
    if (!(targetTime instanceof Date) || isNaN(targetTime.getTime())) {
      console.error("目标时间无效:", targetTime);
      ElMessage.error('目标时间格式无效');
      return false;
    }

    const targetMs = targetTime.getTime();
    // 校验目标时间是否在范围内
    if (targetMs < start || targetMs > end) {
      console.error("目标时间不在时间轴范围内:", targetTime);
      ElMessage.warning('目标时间不在当前时间轴范围内');
      return false;
    }

    // 计算目标时间点的百分比位置
    const percentPosition = ((targetMs - start) / totalMs) * 100;
    // 只更新结束滑块位置
    endHandlePercent.value = Math.max(0, Math.min(100, percentPosition));
    // 更新选中时间
    updateSelectedTimes();
    // 标记为手动选择时间点
    isDraged.value = true;
    // is_flag_isRealtime.value = false;
    isConfirmedWithRange.value = false; // 设置为false以显示完整的选中区域
    // playForward();
    // if (PerformDrag) {
    //   endDrag();//拖动函数
    //   // moveEndHandle();
    // }

    return true;
  } catch (error) {
    console.error("跳转到指定时间点出错:", error);
    ElMessage.error('跳转时间点失败');
    return false;
  }
};

// websock发送数据（只发送，不注册消息处理器）
const wssOpenHandle = (data) => {
  console.log("发送数据", (wssInstance.value).readyState);
  if ((wssInstance.value).readyState === WebSocket.OPEN) {
    // 如果连接已打开，直接发送数据
    (wssInstance.value).send(JSON.stringify(data));
    // console.warn('WebSocket 已连接，无法发送数据:', data);
  } else if ((wssInstance.value).readyState === WebSocket.CLOSED) {
    console.warn('WebSocket 已关闭，无法发送数据:', data);
    const oldUrl = (wssInstance.value).url;  // 保存 URL
    (wssInstance.value) = new WebSocket(oldUrl);
    // 重连时重新注册消息处理器
    wssMessageHandle();
    (wssInstance.value).onopen = () => {
      (wssInstance.value).send(JSON.stringify(data));
    };
    console.log("发送数据1111");
  } else {
    // 否则等待连接打开后再发送
    (wssInstance.value).onopen = () => {
      (wssInstance.value).send(JSON.stringify(data));
    };
  }
};
const loading = ref('');




// 对比时间
const compareTime = (time1, time2) => {
  // console.log('cao每隔开始compareTime----------1', time1, time2);
  // 将时间字符串转换为 Date 对象
  const date1 = new Date(time1);
  if (time2 === null || time2 === "" || time2 === undefined) {
    time2 = new Date(
      new Date(selectedStartTime.value).getTime() + 60 * 1000
    ).toISOString();
    // //console.log('每隔开始compareTime----------', time1, time2);
  }
  const date2 = new Date(time2);

  // 检查时间是否有效
  if (isNaN(date1.getTime()) || isNaN(date2.getTime())) {
    throw new Error("无效的时间格式");
  }

  // 比较时间戳
  if (date1 >= date2) {
    return true;
  } else {
    return false;
  }
};

const wsTimeInstanceFn = () => {
  console.log('架子啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊', wsTimeInstance);
  wsTimeInstance.onmessage = (event) => {
    console.log(selectedEndTime.value, '时间对比------------------------');
    const data = JSON.parse(event.data);
    // console.log('data', data)
    console.log(data, '时间------------------------', useAppStoreInstance.globalLeftWssCONTINE.type);
    // if (useAppStoreInstance.globalLeftWssCONTINE.type === "realtime") {
    startDateTime.value = data.startTime;
    endDateTime.value = data.endTime;
    const currentEndTimeMs = selectedEndTime.value
      ? selectedEndTime.value.getTime()
      : null;

    nextTick(() => {
      // 只刷新刻度，不调 updateTimeline（它会重置滑块）
      generateTimelineDates();
      // 把滑块按比例映射到新时间范围
      if (currentEndTimeMs) {
        const newStartMs = new Date(data.startTime).getTime();
        const newEndMs = new Date(data.endTime).getTime();
        const newTotalMs = newEndMs - newStartMs;
        if (newTotalMs > 0) {
          // 当前时间在新范围中的百分比位置
          const newPercent = ((currentEndTimeMs - newStartMs) / newTotalMs) * 100;
          // 限制在 0~100
          endHandlePercent.value = Math.max(0, Math.min(100, newPercent));
        }
      }

      // 同步选中时间
      updateSelectedTimes();
    });
    // }
  }
}



const preTimeWindowEnd = ref(null);//下一个时间窗口结束时间
const preTimeAllDate = ref(null);//上一条完整数据

const onMessageIndex = ref(0);
// const hasPlayed = ref(false);//判断是否在自动播放中
const unlesscount = ref(0);
const wssMessageHandle = () => {
  // let WwflagToNext = 0
  (wssInstance.value).onmessage = (event) => {
    let data;
    // 修复问题2: 添加 try-catch 包裹 JSON.parse
    try {
      data = JSON.parse(event.data);
    } catch (error) {
      console.error('WebSocket 数据解析失败:', error);
      return;
    }
    console.log('data接受到返回的数据了----------------', data);

    // 修复问题1: 将 history 类型统一处理
    if (data.type === 'realtime') {
      console.log('是否开始播放');
      playForward();
      useAppStoreInstance.setGlobalLeftWssCONTINE(data);
      Loading.hide(); // 成功处理后隐藏 loading

      // 实时模式下，如果后端返回 SMOOTH 类型，说明是拖动后的同步数据
      // 需要通知 UE5 继续播放，与时间轴同步
      if (data.controlType === 'SMOOTH') {
        if (window.ue5) {
          window.ue5("callBackTimeFn", String(JSON.stringify({
            isRealtime: true,
            replayTime: formatDateTime(selectedEndTime.value),
            taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
            speed: playbackSpeed.value,
            status: "continue",  // 通知 UE5 继续播放
          })));
          console.log("SMOOTH类型，通知UE5继续播放");
        }
      }
    } else if (data.type === 'history') {
      // 发送确认（仅非插值数据）
      if (!(data?.isLagrangeInterpolation === true)) {
        wssOpenHandle({
          type: "confirm",
          taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
          clientType: "web"
        });
      }

      // 平滑插值处理
      if ((data?.isLagrangeInterpolation === true) && (data.controlType === 'SMOOTH')) {
        if (data.nextTimestamp) {
          console.log('时间值111');
          preTimeWindowEnd.value = data.nextTimestamp;
        }
        jumpToNextTime.value = data.remainingTimeMs || 0;
        hasDraged_first_falseToTrue.value = true;
        isChange_flag_firstBackDate.value = true;
        playForward();
        useAppStoreInstance.setGlobalLeftWssCONTINE(data);
      }

      // 普通历史数据处理
      if (!(data?.isLagrangeInterpolation === true)) {
        useAppStoreInstance.setGlobalLeftWssCONTINE(data);
        useAppStoreInstance.setglobalStartWss(true);
        speedChangedNormalDataBack.value = false;
        if (data.nextTimestamp || data.timeWindowEnd) {
          console.log('时间值333');
          preTimeWindowEnd.value = data.nextTimestamp || data.timeWindowEnd;
        }
        hasDraged_first_falseToTrue.value = false;
        preTimeAllDate.value = data;
        isChange_flag_firstBackDate.value = true;
        onMessageIndex.value += 1;

        // 修复问题6: 添加容差判断（2秒容差）
        // 添加空值保护
        if (endDateTime.value && selectedEndTime.value) {
          const toleranceMs = 2000; // 2秒容差
          const endTimeMs = new Date(endDateTime.value).getTime();
          const selectedTimeMs = selectedEndTime.value.getTime();
          const timeDiff = endTimeMs - selectedTimeMs;

          if (timeDiff <= toleranceMs && timeDiff >= 0) {
            console.log('接受值后，已到达终点容差范围');
            stopAutoPlay();
          } else {
            playForward();
          }
        } else {
          playForward();
        }
        Loading.hide(); // 成功处理后隐藏 loading
      }
    } else if (data.type === 'control') {
      // control 类型单独处理
      if (data.controlType === 'continue' && data?.messageTypeFalg === 'true') {
        // 跳到指定时间点
        console.log(tempDateTime.value, '试试模式的时间?-------');
        jumpToSpecificTime(new Date(subtractSecondsAndFormat(alignTo56Seconds(tempDateTime.value).toISOString(), data.remainingTimeMs + 1)), false);
        playForward();
        Loading.hide();
      } else if (!(data.controlType === 'stop') && !(data.controlType === 'continue')) {
        if (data.nextTimestamp) {
          console.log('时间值222');
          preTimeWindowEnd.value = data.nextTimestamp || data.dataTime;
        }
        hasDraged_first_falseToTrue.value = true;
        console.log('是否跳转');
        jumpToSpecificTime(new Date(subtractSecondsAndFormat(alignTo56Seconds(selectedEndTime.value).toISOString(), data.remainingTimeMs + 1)));
        isChange_flag_firstBackDate.value = true;
        Loading.hide();
      }
    } else if (data.type === 'error') {
      console.log(data.type, '为什么会进来33');
      ElMessage({
        type: 'error',
        message: data.message ? `主系统:${data.message} ` : `已暂停，没有查询到该时间段的历史数据！！！`,
      });
      useAppStoreInstance.setglobalStartWss(false);
      stopAutoPlay();
      // 错误情况不隐藏 loading，保持加载状态提示用户
    } else if (data.type === 'EndProcess') {
      useAppStoreInstance.setglobalStartWss(false);
      console.log(data.type, data.type === 'error', '为什么会进来11');
      ElMessage({
        type: 'error',
        message: data.message || `已暂停，没有查询到该时间段的历史数据！！！`,
      });
      stopAutoPlay();
    }

    unlesscount.value += 1;
  };
}






// 日期时间状态 (精确到秒)
const now = dayjs().format('YYYY-MM-DD HH:mm:ss')
const tomorrow = dayjs().add(1, 'day').format('YYYY-MM-DD HH:mm:ss')
// console.log('now', now, tomorrow)
// const startDateTime = ref(now);
// const endDateTime = ref(tomorrow);
const startDateTime = ref("");//2025-11-08 23:59:56
const endDateTime = ref("");//2025-11-09 23:59:56
// console.log('startDateTime', startDateTime.value)
const dateRange = ref([]);

// 滑块位置（百分比）
const startHandlePercent = ref(0);
const endHandlePercent = ref(0);

// 拖动状态
const isDragging = ref(false);
// const currentDragHandle = ref(null);

// 滑块DOM引用
const sliderTrack = ref(null);

// 选中的时间
const selectedStartTime = ref(new Date(startDateTime.value));
const selectedEndTime = ref(new Date(startDateTime.value));

// 自动播放相关状态
const isPlaying = ref(false);//true--代表正在播放,false---代表暂停

const playbackSpeed = ref(1); // 播放速度倍数
const playbackDirection = ref(1); // 1表示向前播放，-1表示向后播放
const playbackInterval = ref(null);//时间定时器

// 新增：标识是否是带时间范围的确认操作
const isConfirmedWithRange = ref(false);

// 时间轴总毫秒数
const totalMilliseconds = computed(() => {
  return new Date(endDateTime.value).getTime() - new Date(startDateTime.value).getTime();
});


const showLengthmarkerLine = computed(() => {
  return Math.round(timeMarkers.value.length / 8);
})
const showLength = computed(() => {
  return Math.round(timeMarkers.value.length / 8);
})


// 定义实时
const is_flag_isRealtime = ref(true);

// 禁用今天之后的日期
const disabledDate = (time) => {
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  return time.getTime() > today.getTime();
};


const pick_select_date = ref();
const pick_select_date_handFn = (val) => {
  if (pick_select_date.value == val) {
    return ElMessage({
      type: 'warning',
      message: `当前时间段未发生变化，请重新选时间段`,
    })
  }
  pick_select_date.value = val;
}
const taskCode_everyChange = ref('');

// 点击确认后，处理日期范围变化,speed--播放速度倍数,val--时间范围
const handleDateRangeChange = async (val, flag = false, RemoveSat, speed) => {
  console.log(val, '对比');
  // 判断如果是实时模式则储存当前时间开始时间和结束时间
  if (is_flag_isRealtime.value) {
    console.log(startDateTime.value, endDateTime.value, '实时');
    localStorage.setItem("isRealtimetime", JSON.stringify(
      [startDateTime.value, endDateTime.value]
    ));
  }
  // return
  if (RemoveSat) {
    is_flag_isRealtime.value = false;
    localStorage.setItem("is_flag_isRealtime", false);
    window.ue5("RemoveSat", String(JSON.stringify({
      Sat: true,
    })))
  } else {
    localStorage.setItem("is_flag_isRealtime", true);
  }
  useAppStoreInstance.setglobalSubsystemSelectedStartTime(val);
  jiangerTime.value = 0;
  isChange_flag_firstBackDate.value = false;
  // hasPlayed.value = false;
  if (!flag) {
    taskCode_everyChange.value = String(Date.now());
    useAppStoreInstance.setglobalSubsystemTaskCode(taskCode_everyChange.value);
    useAppStoreInstance.setGlobalRecordMainSysTaskCode(taskCode_everyChange.value)
    useAppStoreInstance.setFooterTimeHasedSelectTimeToSub(true);
  }

  if (val && val.length > 0) {
    isPlaying.value = false;//播放暂停
    if (!flag) {
      Loading.show()
    }
    if (val && val.length === 2) {
      //console.log("cao cao11",val);
      startDateTime.value = new Date((new Date(val[0])).setSeconds(56)).toISOString();
      endDateTime.value = new Date((new Date(val[1]))).toISOString();

      isDraged.value = false;
      isDateRangeNotEmpty.value = false;
      isConfirmedWithRange.value = true; // 标记为带范围确认
      clearInterval(autoUpdateDateRange.value);
      updateTimeline();

      // 重置滑块位置到开始位置--历史模式
      startHandlePercent.value = 0;
      endHandlePercent.value = 0;

      // 强制更新视图
      nextTick(() => {
        updateSelectedTimes();   //更新选中的时间滑块位置 → 实际时间的转换
      });
    }

    playbackSpeed.value = Number(speed);//倍速设置
    console.log("倍速设置", playbackSpeed.value, '类型');
    if (!flag) {
      wssOpenHandle({
        isRealtime: is_flag_isRealtime.value ? true : false,
        startTime: formatDateTime(val[0]),
        endTime: formatDateTime(val[1]),
        taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
      })
    }
    if (window.ue5) {

      window.ue5("callBackTimeFn", String(JSON.stringify({
        isRealtime: is_flag_isRealtime.value ? true : false,
        startTime: (formatDateTime(val[0])),
        speed: playbackSpeed.value,
        endTime: (formatDateTime(val[1])),
        taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
        currentTime: (formatDateTime(selectedEndTime.value)),
        status: isPlaying.value ? "stop" : "continue",
      })))
      console.log("走了这里3");

    }
  } else {
    ElMessage({
      type: 'warning',
      message: `时间范围为空，自动执行最近24小时`,
    })
    // useAppStoreInstance.setGlobalisFromTosub(false);
    // useAppStoreInstance.setFooterTimeHasedSelectTimeToSub(false);
    useAppStoreInstance.setFooterTimeHasedSelectTimeToSub(true);//true--历史模式,false--实时模式
    isDateRangeNotEmpty.value = true;
    isConfirmedWithRange.value = false; // 重置标记
    is_flag_isRealtime.value = true;
    playbackSpeed.value = 1;
    stopAutoPlay();

    // 强制更新视图
    nextTick(() => {
      updateTimeline();
    });
  }
};

const isDateRangeNotEmpty = ref(false);
const autoUpdateDateRange = ref(null);
autoUpdateDateRange.value = setInterval(() => {
  autoHandleDateRangeChange([startDateTime.value, endDateTime.value]);
}, 1000);

//isDateRangeNotEmpty    实时模式	true	每秒自动更新时间范围	滑块随着当前时间往前推24小时的窗口自动前进  历史模式	false	停止自动更新	使用用户手动选择的固定日期范围
watch(() => isDateRangeNotEmpty.value, (newVal) => {
  if (newVal) {
    // === 实时模式：开启自动更新 ===
    console.log('监听信息学,改变时间');

    autoUpdateDateRange.value = setInterval(() => {
      autoHandleDateRangeChange([new Date((new Date(useAppStoreInstance.globalSubsystemSelectedStartTime[0]))).toISOString(), new Date((new Date(useAppStoreInstance.globalSubsystemSelectedStartTime[1]))).toISOString()]);
    }, 1000);  // 每秒执行一次，让时间范围随着当前时间前进
  } else {
    // === 历史模式：关闭自动更新 ===
    clearInterval(autoUpdateDateRange.value);
    // 使用用户在日期选择器中手动选择的固定日期范围
  }
});


const autoHandleDateRangeChange = (val) => {
  useAppStoreInstance.setglobalSubsystemSelectedStartTime(val);
  if (val && val.length === 2) {
    // console.log("自动更新日期范围", val);
    if (val[0] instanceof Date && val[1] instanceof Date) {
      startDateTime.value = val[0]?.toISOString();
      endDateTime.value = val[1]?.toISOString();
      // console.log("自动更新日期范围格式正确", val);
    } else {
      // console.log("自动更新日期范围格式错误", val);
      return;
    }
    isDraged.value = false;
    updateTimeline();
  }
}

// 生成时间轴日期 - 只显示图片中的格式: MM-DD
const timelineDates = ref([]);
const generateTimelineDates = () => {
  const start = new Date(startDateTime.value);
  const end = new Date(endDateTime.value);
  const dates = [];

  // 重置到当天0点
  const current = new Date(start);
  current.setHours(0, 0, 0, 0);

  while (current <= end) {
    dates.push(new Date(current));
    current.setDate(current.getDate() + 60);
  }

  timelineDates.value = dates;
  updateSelectedTimes();
};
//时间刻度
const timeMarkers = computed(() => {
  const markers = [];
  const start = new Date(startDateTime.value);
  const end = new Date(endDateTime.value);
  const totalMs = totalMilliseconds.value;

  if (totalMs <= 0) return []; // 防止除零错误

  // 第一个刻度：直接使用 start 时间（保留原始分钟/秒）
  const firstMarkerTime = new Date(start);
  const firstPosition = 0; // 因为就是起点
  markers.push({
    time: firstMarkerTime,
    label: dayjs(firstMarkerTime).format('YYYY-MM-DD HH:mm'),
    position: firstPosition,
    isMajor: true, // 起始点视为主刻度
    showLabel: true
  });

  // 后续刻度：从 start 的下一个**整点**开始，每 60 分钟加一个
  // const nextHour = new Date(start);
  // nextHour.setMinutes(0, 0, 0); // 先对齐到当前小时整点
  // nextHour.setHours(nextHour.getHours() + 1); // 跳到下一个整点（避免重复）

  let current = dayjs(start).toDate();
  // console.log(dayjs(current).format('YYYY-MM-DD HH:mm'))
  console.log(dayjs(start).format('YYYY-MM-DD HH:mm'), '发送日期', dayjs(end).format('YYYY-MM-DD HH:mm'))
  while (current < end) {
    const position = ((current.getTime() - start.getTime()) / totalMs) * 100;
    markers.push({
      time: new Date(current),
      label: dayjs(current).format('YYYY-MM-DD HH:mm'),
      position,
      isMajor: true, // 每小时都是主刻度
      showLabel: true
    });
    current.setHours(current.getHours() + 1); // 每次 +1 小时
  }

  console.log('markers时间刻度信息----', markers)

  return markers;
});
//用于显示刻度样式
const isMarkerInSelectedRange = (marker) => {
  // //console.log("-----------------------,",marker);
  const markerTime = marker.time.getTime();
  const startTime = selectedStartTime.value.getTime();
  const endTime = selectedEndTime.value.getTime();

  return markerTime >= startTime && markerTime <= endTime;
};

// 日期时间格式化函数
const formatDateTime = (dates) => {
  if (!dates || dates == undefined) return '未选择';
  if (!isDateString(dates)) return
  let date = new Date(dates);
  const year = date?.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0');
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};
//判断字符串是不是时间
function isDateString(dateString) {
  var date = new Date(dateString);
  return date instanceof Date && !isNaN(date);
}
// 修改后的选中区域样式计算属性
const selectedRangeStyle = computed(() => {
  // 如果是带范围确认且未在播放状态，则选中区域宽度为0
  if (isConfirmedWithRange.value && !isPlaying.value) {
    return {
      left: startHandlePosition.value,
      width: '0%'
    };
  }
  // 自动播放状态或手动拖动状态
  else {
    const left = Math.min(startHandlePercent.value, endHandlePercent.value);
    const right = Math.max(startHandlePercent.value, endHandlePercent.value);
    return {
      left: `${left}%`,
      width: `${right - left}%`
    };
  }
});

// 滑块位置计算
const startHandlePosition = computed(() => `${startHandlePercent.value}%`);

// 结束时滑块距离左侧的位置
const endHandlePosition = computed(() => {
  if (isConfirmedWithRange.value && !isPlaying.value) {
    return `${startHandlePercent.value}%`;
  }

  return `${endHandlePercent.value}%`;
});

//更新时间
const updateSelectedTimes = () => {
  if (!startDateTime.value || !endDateTime.value) return;

  const start = new Date(startDateTime.value).getTime();
  const totalMs = totalMilliseconds.value;


  const startTime = new Date(start + (totalMs * startHandlePercent.value / 100));
  const endTime = new Date(start + (totalMs * endHandlePercent.value / 100));


  selectedStartTime.value = startTime;
  selectedEndTime.value = endTime;
  // 无论是实时还是历史模式，都要更新 globalTimeLineEndSelectTime
  // 这样从分系统返回时，tempDateTime 才能拿到正确的滑块位置（实时模式自动走时也需要保存）
  useAppStoreInstance.setGlobalTimeLineEndSelectTime(formatDateTime(selectedEndTime.value));

  // //console.log("************",useAppStoreInstance.globalTimeLineEndSelectTime);

};
const isDraged = ref(false);
// false: 播放方向为向前播放，true: 播放方向为向后播放
const curplaybackDirection = ref(false);

// 切换自动播放状态
const toggleAutoPlay = () => {
  if (is_flag_isRealtime.value) {//实时模式
    // ElMessage({
    //   type: 'warning',
    //   message: '当前为实时播放模式,不可执行播放操作！',
    // })
    //实时模式下的暂停后端还没有上线
    isPlaying.value = !isPlaying.value
    console.log('isPlaying-------------------------切换播放状态', isPlaying.value)
    if (isPlaying.value) { }//false--需要暂停,true--需要代表继续播放
    // stopAutoPlay();
    if (window.ue5) {
      console.log("触发3");
      if (isPlaying.value) {
        //开始播放
        startAutoPlay()
        wssOpenHandle({
          isRealtime: true,//实时模式
          isFastForward: false,//不加速,实时模式没有倍速概念
          status: "continue"
        })
      } else {
        wssOpenHandle({
          isRealtime: true,//实时模式
          isFastForward: false,//不加速,实时模式没有倍速概念
          status: "stop"
        })
        //暂停
        stopAutoPlay();
      }

      taskCode_everyChange.value = String(Date.now());
      useAppStoreInstance.setglobalSubsystemTaskCode(taskCode_everyChange.value);
      useAppStoreInstance.setGlobalRecordMainSysTaskCode(taskCode_everyChange.value)
      useAppStoreInstance.setFooterTimeHasedSelectTimeToSub(false);//true--历史模式,false--实时模式

      console.log('is_flag_isRealtime', is_flag_isRealtime.value)
      console.log('taskCode', taskCode_everyChange.value)
      // console.log('startTime',selectedStartTime.value)
      // console.log('endTime',selectedEndTime.value)
      console.log('startTime', formatDateTime(new Date(startDateTime.value)))
      console.log('endTime', formatDateTime(new Date(endDateTime.value)))
      console.log('currentTime', (formatDateTime(selectedEndTime.value)))
      // return
      // wssOpenHandle({
      //   isRealtime: is_flag_isRealtime.value ? true : false,
      //   startTime: formatDateTime(new Date(startDateTime.value)),
      //   endTime: formatDateTime(new Date(endDateTime.value)),
      //   taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
      // })
      console.log(String(JSON.stringify({
        isRealtime: true,
        startTime: formatDateTime(new Date(startDateTime.value)),
        endTime: formatDateTime(new Date(endDateTime.value)),
        speed: playbackSpeed.value,
        taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
        currentTime: (formatDateTime(selectedEndTime.value)),
        status: isPlaying.value ? "continue" : "stop",
        //时间参数
      })), '传给ue5的参数');

      window.ue5("callBackTimeFn", String(JSON.stringify({
        isRealtime: true,
        startTime: formatDateTime(new Date(startDateTime.value)),
        endTime: formatDateTime(new Date(endDateTime.value)),
        speed: playbackSpeed.value,
        taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
        currentTime: (formatDateTime(selectedEndTime.value)),
        status: isPlaying.value ? "continue" : "stop",
        // status: isPlaying.value ? "continue" : "stop",
        //时间参数
      })))
      console.log("走了这里4");

    }



  } else {//历史模式
    is_flag_playBackwarding.value = true;

    if (isPlaying.value) {

      //console.log("我是切换自动播放状态stopAutoPlay()",isPlaying.value);
      console.log("我走了这里7")
      stopAutoPlay();//停止自动播放
      if (window.ue5) {

        window.ue5("callBackSpeedFn", String(JSON.stringify({
          isRealtime: is_flag_isRealtime.value ? true : false,
          status: "stop",
          speed: playbackSpeed.value,
          taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
        })));

        wssOpenHandle({
          isRealtime: is_flag_isRealtime.value ? true : false,
          status: "stop",
          taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
        })
      }
    } else {

      isConfirmedWithRange.value = false; // 开始播放时重置标记
      jiangerTime.value = 0;
      playForward();//开始播放
      // 跳转到指定的时间点
      console.log('是否跳转222');

      jumpToSpecificTime(new Date(addOneSecond(formatDateTime(selectedEndTime.value), 1)));
      if (window.ue5) {
        window.ue5("callBackSpeedFn", String(JSON.stringify({
          isRealtime: is_flag_isRealtime.value ? true : false,
          status: 'continue',
          speed: playbackSpeed.value,
          taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
        })));
        wssOpenHandle({
          isRealtime: is_flag_isRealtime.value ? true : false,
          status: 'continue',
          taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
        })
      }
      // 强制更新视图
      nextTick(() => {
        updateSelectedTimes();
      });
    }

  }

};

const is_flag_playForwarding = ref(true);
const is_flag_playBackwarding = ref(true);


// 开始向前播放
const playForward = async () => {
  is_flag_playBackwarding.value = true;
  // if (flag_SetTimeOutCycle.value === null) {
  //   handleSetTimeOutCycle();
  // }
  if (1) {

    //console.log("再次我是开始向前播放stopAutoPlay()",isPlaying.value);
    // stopAutoPlay(); // 先停止当前播放
    isPlaying.value = true;
    isConfirmedWithRange.value = false; // 重置标记
    curplaybackDirection.value = false;
    playbackDirection.value = 1;
    console.log("触发4");
    startAutoPlay();

    // 强制更新视图
    nextTick(() => {
      updateSelectedTimes();
    });
  } else {
    ElMessage({
      type: 'warning',
      message: '正在前向播放！',
    })
  }

  is_flag_playForwarding.value = false;
};

// 第二版开始播放
const startAutoPlay = () => {
  console.log('开始播放?', !isPlaying.value);
  // 清除定时器（注意：playbackInterval 存储的是 setTimeout 返回值）
  if (playbackInterval.value) {
    clearTimeout(playbackInterval.value);
  }

  let expectedTime = Date.now() + (1000 / playbackSpeed.value);
  const update = () => {
    const drift = Date.now() - expectedTime;
    moveEndHandle();
    expectedTime += (1000 / playbackSpeed.value);
    // 第4步：递归调用（根据漂移量修正间隔）
    playbackInterval.value = setTimeout(update, Math.max(0, (1000 / playbackSpeed.value) - drift));
  };
  // hasPlayed.value = true;
  playbackInterval.value = setTimeout(update, 1000 / playbackSpeed.value);
};

// 停止自动播放
const stopAutoPlay = () => {
  isPlaying.value = false;
  console.log("停止自动播放", playbackInterval.value);
  if (playbackInterval.value) {
    clearTimeout(playbackInterval.value);
    playbackInterval.value = null;
  }

  if (flag_SetTimeOutCycle.value !== null) {
    clearTimeout(flag_SetTimeOutCycle.value);
    flag_SetTimeOutCycle.value = null;
  }

  // 强制更新视图
  nextTick(() => {
    updateSelectedTimes();
  });
};

// 移动结束滑块 - 以秒为单位移动
const moveEndHandle = () => {
  if (!isPlaying.value) return;
  // //console.log("开始进行移动滑块");

  // 计算每秒对应的百分比增量
  const totalMs = totalMilliseconds.value;
  const msPerSecond = 1000; // 1秒 = 1000毫秒
  const percentPerSecond = (msPerSecond / totalMs) * 100;

  // 根据播放方向和速度调整结束滑块位置
  const increment = percentPerSecond * playbackDirection.value;
  // 这里可以尝试
  endHandlePercent.value += increment;
  // //console.log("endHandlePercent.value",endHandlePercent.value);

  // 边界检查
  if (endHandlePercent.value >= 100) {
    // 向前播放到达终点，停止播放
    endHandlePercent.value = 100;
    useAppStoreInstance.setglobalStartWss(false)
    //console.log("我是移动结束滑块stopAutoPlay()",isPlaying.value);
    console.log("我走了这里8")
    stopAutoPlay();
  }
  //  else if (endHandlePercent.value <= 0 && playbackDirection.value < 0) {
  //   // 向后播放到达起点，停止播放
  //   endHandlePercent.value = 0;
  //   stopAutoPlay();
  // }

  // 确保值在有效范围内
  endHandlePercent.value = Math.max(0, Math.min(100, endHandlePercent.value));

  // 更新选中时间
  updateSelectedTimes();
};

// 切换播放速度
const changeSpeed = () => {
  //console.log("我是changeSpeed",playbackSpeed.value);
  speedChangedNormalDataBack.value = true;//多余
  // const speeds = [1, 2, 4, 8, 10];
  // const currentIndex = speeds.indexOf(playbackSpeed.value);
  // const nextIndex = (currentIndex + 1) % speeds.length;
  // hasPlayed.value = false;
  // playbackSpeed.value = speeds[nextIndex];
  jiangerTime.value = 0;
  if (window.ue5) {
    window.ue5("callBackSpeedFn", String(JSON.stringify({
      // isRealtime: is_flag_isRealtime.value? true: false,
      // isFastForward: playbackSpeed.value === 1 || playbackSpeed.value === '1'?false:true, 
      speed: playbackSpeed.value,
      // taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
    })))
    wssOpenHandle({
      isRealtime: is_flag_isRealtime.value ? true : false,
      isFastForward: playbackSpeed.value === 1 || playbackSpeed.value === '1' ? false : true,
      step: playbackSpeed.value,
      taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
    })
  }

  // 如果正在播放，重新开始自动播放以应用新的速度
  if (isPlaying.value) {
    console.log("触发5");
    startAutoPlay();
  }
};

//结束拖动
const startDrag = (handle, e) => {
  //console.log("开始拖动");
  // if (is_flag_isRealtime.value) {
  //   ElMessage({
  //     type: 'warning',
  //     message: '实时模式下无法进行拖拽',
  //   })
  //   return
  // }
  // is_flag_isRealtime.value = false;
  // isDateRangeNotEmpty.value = false;
  clearInterval(autoUpdateDateRange.value);
  isDraged.value = true;
  isDragging.value = true;
  // currentDragHandle.value = handle;
  e.preventDefault();
  // console.log("拖动开始", currentDragHandle.value);

  // 手动拖动时停止自动播放
  if (isPlaying.value) {
    stopAutoPlay();
  }

  // 移除旧的事件监听器，防止重复绑定
  window.removeEventListener('mousemove', handleDrag);
  window.removeEventListener('mouseup', endDrag);
  // 添加新的事件监听器
  window.addEventListener('mousemove', handleDrag);
  window.addEventListener('mouseup', endDrag);
};

// 拖动过程中函数回显样式等信息
const handleDrag = (e) => {
  if (!isDragging.value || !sliderTrack.value) return;
  const rect = sliderTrack.value.getBoundingClientRect();
  let percentage = ((e.clientX - rect.left) / rect.width) * 100;

  // 限制在0-100%之间
  percentage = Math.max(0, Math.min(100, percentage));
  //100份中的多少份
  endHandlePercent.value = percentage;
  // 更新选中时间
  updateSelectedTimes();
};


const alignTo56Seconds = (date) => {
  const d = new Date(date);
  const seconds = d.getSeconds();

  if (seconds <= 56) {
    d.setSeconds(56, 0); // 设置秒为56，毫秒为0
  } else {
    // 超过56秒，跳到下一分钟的56秒
    d.setMinutes(d.getMinutes() + 1);
    d.setSeconds(56, 0);
  }

  return d;
};

// 换算成指定的时间单位
const addOneSecond = (timeStr, sec = 1) => {
  // 解析输入字符串为 Date 对象（注意：需指定时区为本地时间）
  const [datePart, timePart] = timeStr.split(' ');
  const [year, month, day] = datePart.split('-').map(Number);
  const [hour, minute, second] = timePart.split(':').map(Number);

  // 创建本地时间的 Date 对象（避免 UTC 解析偏差）
  const date = new Date(year, month - 1, day, hour, minute, second);

  // 加 1 秒（1000 毫秒）
  date.setTime(date.getTime() + sec * 1000);

  // 格式化回 YYYY-MM-DD HH:mm:ss
  const pad = (n) => String(n).padStart(2, '0');
  const newYear = date.getFullYear();
  const newMonth = pad(date.getMonth() + 1);
  const newDay = pad(date.getDate());
  const newHour = pad(date.getHours());
  const newMinute = pad(date.getMinutes());
  const newSecond = pad(date.getSeconds());

  return `${newYear}-${newMonth}-${newDay} ${newHour}:${newMinute}:${newSecond}`;
};
//时间格式转换
const subtractSecondsAndFormat = (isoString, secondsToSubtract) => {


  // 1. 解析 ISO 字符串（它代表 UTC 时间）
  const date = new Date(isoString); // 这个 Date 对象内部是 UTC，但 JS 会按本地时区显示

  // 2. 减去指定秒数
  const newTime = date.getTime() - (secondsToSubtract * 1000);
  // （毫秒）的话
  // const newTime = date.getTime() - (secondsToSubtract /1000);
  const newDate = new Date(newTime);

  // 3. 使用本地时间（中国标准时间）格式化，秒不补零
  const year = newDate.getFullYear(); // 本地年
  const month = String(newDate.getMonth() + 1).padStart(2, '0');
  const day = String(newDate.getDate()).padStart(2, '0');
  const hours = String(newDate.getHours()).padStart(2, '0'); // 本地小时
  const minutes = String(newDate.getMinutes()).padStart(2, '0');
  const seconds = newDate.getSeconds(); // 不补零！

  //console.log("我走了isoString",isoString,secondsToSubtract,`${year}-${month}-${day} ${hours}:${minutes}:${seconds}`);
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};

const jumpToNextTime = ref(0);

const hasDraged_first_falseToTrue = ref(false);
//拖动结束
const endDrag = () => {
  isDragging.value = false;
  // currentDragHandle.value = null;
  // hasPlayed.value = false;

  if (window.ue5) {
    // console.log(window.ue5, "拖动结束", isDraged.value, is_flag_isRealtime.value, useAppStoreInstance.globalLeftWssCONTINE);
    if (isDraged.value) {
      if (is_flag_isRealtime.value || useAppStoreInstance.globalLeftWssCONTINE.type === "realtime") {
        //实时
        wssOpenHandle({
          isRealtime: true,
          replayTime: formatDateTime(selectedEndTime.value),
          // taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
          isFastForward: false,
        })
        console.log(isPlaying.value, '判断拖动后赋值----------');

        window.ue5("callBackTimeFn", String(JSON.stringify({
          isRealtime: true,
          replayTime: (formatDateTime(selectedEndTime.value)),
          taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
          speed: playbackSpeed.value,
          status: isPlaying.value ? "continue" : "stop",
        })));
        console.log("走了这里5");
      } else {
        window.ue5("callBackTimeFn", String(JSON.stringify({
          isRealtime: false,
          replayTime: (formatDateTime(selectedEndTime.value)),
          taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
          speed: playbackSpeed.value,
          status: isPlaying.value ? "continue" : "stop",
        })));
        console.log("走了这里6");
        wssOpenHandle({
          isRealtime: false,
          replayTime: formatDateTime(selectedEndTime.value),
          taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
        })
      }



      // 发送时轴de 当前时间给ue
      window.ue5("callTimeLineCurrentTimeFn", String(JSON.stringify({
        year: selectedEndTime.value.getFullYear(),
        month: selectedEndTime.value.getMonth() + 1,
        day: selectedEndTime.value.getDate(),
        hour: selectedEndTime.value.getHours(),
        minute: selectedEndTime.value.getMinutes(),
        second: selectedEndTime.value.getSeconds(),
      })));

      // }
    } else {
    }
  }

  window.removeEventListener('mousemove', handleDrag);
  window.removeEventListener('mouseup', endDrag);
  updateSelectedTimes();
  // is_flag_confirmAndPauseAndSpeed.value = false;
  console.log('触发了暂停');

  stopAutoPlay();

  // 问题4修复：拖动结束后，如果处于实时模式，恢复自动更新定时器
  if (isDateRangeNotEmpty.value) {
    clearInterval(autoUpdateDateRange.value);
    autoUpdateDateRange.value = setInterval(() => {
      autoHandleDateRangeChange([new Date((new Date(useAppStoreInstance.globalSubsystemSelectedStartTime[0]))).toISOString(), new Date((new Date(useAppStoreInstance.globalSubsystemSelectedStartTime[1]))).toISOString()]);
    }, 1000);
  }
};

// 重置滑块-重置当天日期
const updateTimeline = () => {
  // 验证时间范围
  if (new Date(startDateTime.value) >= new Date(endDateTime.value)) {
    alert('结束时间必须大于开始时间');
    return;
  }

  generateTimelineDates();

  // 重置滑块位置
  startHandlePercent.value = 0;
  endHandlePercent.value = 100;
};
const flag_SetTimeOutCycle = ref(null)
// 转化年月日时分秒
const formatDateTimeOne = (timeStr) => {
  // 支持传入 Date 对象或字符串
  const date = timeStr instanceof Date ? timeStr : new Date(timeStr);

  if (isNaN(date.getTime())) {
    console.error('Invalid time string:', timeStr);
    return '';
  }
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0');

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
// const handleSetTimeOutCycle = () => {
//   if (flag_SetTimeOutCycle.value === null) {
//     flag_SetTimeOutCycle.value = setInterval(() => {
//       // //console.log("我走了setInterval",(formatDateTimeOne(selectedEndTime.value)));

//       if (window.ue5) {
//         window.ue5("callBackCycleTimePointFn", String(JSON.stringify({
//           // currentTime: trackCycleTimePoint(formatDateTime(selectedEndTime.value)), 
//           currentTime: (formatDateTimeOne(selectedEndTime.value)),
//         })));
//       }
//     }, 1000 * 2);
//   }

// }
// 重置模式为实时模式
const resetclick = () => {
  console.log('切换到实时模式', useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode));

  if (is_flag_isRealtime.value) {
    ElMessage.warning("当前已经是实时模式!");
    return;
  }

  // 停止当前播放
  stopAutoPlay();

  // 实时模式时间范围：当前时间往前推24小时
  const now = new Date();
  const twentyFourHoursAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000);
  const newTimeRange = [twentyFourHoursAgo.toISOString(), now.toISOString()];

  // 同步更新 store 中的时间范围（供 autoUpdateDateRange 定时器使用）
  useAppStoreInstance.setglobalSubsystemSelectedStartTime(newTimeRange);

  // 设置为实时模式
  is_flag_isRealtime.value = true;
  isDateRangeNotEmpty.value = true; // 开启实时模式自动更新
  startHandlePercent.value = 0;
  endHandlePercent.value = 100; // 实时模式滑块为100
  dateRange.value = [];
  playbackSpeed.value = Number(localStorage.getItem("playbackSpeed")) || 1;

  // 更新本地时间变量
  startDateTime.value = newTimeRange[0];
  endDateTime.value = newTimeRange[1];
  selectedEndTime.value = now; // 滑块在100%位置对应当前时间

  // 更新 timeline 和选中时间显示
  nextTick(() => {
    updateTimeline();
    updateSelectedTimes();
  });

  // 向 UE5 发送实时模式消息（页面初始加载时的参数格式）
  if (window.ue5) {
    // 给ue发送消息让ue切换模式
    window.ue5("callBackTimeFn", String(JSON.stringify({
      isRealtime: true,
      taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
      speed: playbackSpeed.value,
    })));
    //给ue发送消息让ue移除卫星
    window.ue5("RemoveSat", String(JSON.stringify({
      Sat: false,
    })))
    console.log("实时模式切换：发送UE5消息");
  }

  // 向后端发送实时模式消息
  wssOpenHandle({
    isRealtime: true,
    speed: playbackSpeed.value,
    // startTime: formatDateTime(twentyFourHoursAgo),
    // endTime: formatDateTime(now),
    taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
  });
}
const tempDateTime = ref(new Date(useAppStoreInstance.globalTimeLineEndSelectTime))
onMounted(() => {
  createWebSocket();
  // console.log();
  wsTimeInstance = getTimewss()
  wsTimeInstanceFn();//接受实时模式下的数据
  wssMessageHandle();// 只在初始化时注册一次消息处理器
  //进入前时间
  tempDateTime.value = ""
  console.log(useAppStoreInstance.footerTimeHasedSelectTimeToSub, '逻辑对比');
  console.log(localStorage.getItem("is_flag_isRealtime"), '跳转前模式');

  if (useAppStoreInstance.footerTimeHasedSelectTimeToSub) {//判断是实时模式还是历史模式
    is_flag_isRealtime.value = localStorage.getItem("is_flag_isRealtime") === "true";
    console.log("初始化走上面（历史模式恢复）", is_flag_isRealtime.value, useAppStoreInstance.globalLeftWssCONTINE.mode);
    tempDateTime.value = useAppStoreInstance.globalTimeLineEndSelectTime
    // subSysToMainSysFirstDataBack.value = false;

    //历史模式时间范围
    if (!is_flag_isRealtime.value) {
      dateRange.value = [new Date((new Date(useAppStoreInstance.globalSubsystemSelectedStartTime[0]))).toISOString(), new Date((new Date(useAppStoreInstance.globalSubsystemSelectedStartTime[1]))).toISOString()]
      pick_select_date.value = [new Date(dateRange.value[0]).toString(), new Date(dateRange.value[1]).toString()]
    }
    {
      //跳出判断,一直执行
      console.log(localStorage.getItem("playbackSpeed"), '判断是否走了历史模式', useAppStoreInstance.globalSubsystemSelectedStartTime);

      // ⚠️ 保存离开前的 isRealtime 状态，因为 handleDateRangeChange 内部会把 is_flag_isRealtime 设为 false
      // const wasRealtime = useAppStoreInstance.globalLeftWssCONTINE.type === "realtime";
      //点击了确认按钮---下拉时间框的
      handleDateRangeChange(useAppStoreInstance.globalSubsystemSelectedStartTime, true, false, localStorage.getItem("playbackSpeed"));
      // handleDateRangeChange 之后恢复 isRealtime 标志（否则实时模式会变成历史模式）
      // if (wasRealtime) {
      //   is_flag_isRealtime.value = true;
      // }
      // 正确顺序：
      // 1. handleDateRangeChange → 重置 endHandlePercent=0、isPlaying=false
      // 2. nextTick → DOM 更新完毕
      // 3. jumpToSpecificTime → 恢复 endHandlePercent 到离开前位置
      // 4. isPlaying = true → 允许 moveEndHandle 运行
      // 5. wssOpenHandle → 末尾调用 startAutoPlay，从正确位置开始播放
      nextTick(() => {
        if (tempDateTime.value) {
          const restored = new Date(tempDateTime.value);
          if (!isNaN(restored.getTime())) {
            //跳转到指定时间
            console.log('走这厉害');

            jumpToSpecificTime(restored, false);
            console.log("滑块恢复到离开前位置:", tempDateTime.value);
          }
          isPlaying.value = true;
        }
        // handleDateRangeChange 内部把 isPlaying 设为 false，重新设为 true
        // 否则 moveEndHandle() 会因为 isPlaying=false 立即返回，滑块不会动
        // wssOpenHandle 放在 nextTick 内，保证 endHandlePercent 已恢复后再触发 startAutoPlay
      });
      wssOpenHandle({
        isRealtime: is_flag_isRealtime.value,
        status: 'continue',
        messageTypeFalg: true,
        taskCode: useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode),
      })
    }

  } else {
    //实时模式
    updateTimeline();
    console.log("初始化走下面");
    if (window.ue5) {
      window.ue5("callBackTimeFn", String(JSON.stringify({
        isRealtime: is_flag_isRealtime.value,
        taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
        speed: playbackSpeed.value,
        // status: isPlaying.value ? "continue" : "stop",
      })))
      console.log("走了这里1");
    }
  }
  // useAppStoreInstance.setGlobalisFromTosub(false)

  // ⚠️ 如果是从分系统返回，上面已经在 nextTick 里恢复了滑块和 wssOpenHandle
  // 不能再调 realTimeData()，否则会生成新 taskCode、重置 WS，把之前的恢复全部覆盖
  if (useAppStoreInstance.footerTimeHasedSelectTimeToSub) {
    return;
  }

  console.log('isPlaying这是第几个', isPlaying.value)
  if (!isPlaying.value) {
    if (window.ue5) {
      realTimeData()

    }
  }
  // console.log(selectedEndTime.value, '时间走动大傻逼固定板苏大哥火速');

});


// 定义定时器引用--时间开始
const realTimeData = () => {
  // startAutoPlay()
  taskCode_everyChange.value = String(Date.now());
  useAppStoreInstance.setglobalSubsystemTaskCode(taskCode_everyChange.value);
  useAppStoreInstance.setGlobalRecordMainSysTaskCode(taskCode_everyChange.value)
  useAppStoreInstance.setFooterTimeHasedSelectTimeToSub(true);//判断是实时模式还是历史模式
  wssOpenHandle({
    isRealtime: true,
    taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
    speed: 1
  })

  if (window.ue5) {
    window.ue5("callBackTimeFn", String(JSON.stringify({
      isRealtime: is_flag_isRealtime.value ? true : false,
      startTime: dayjs(startDateTime.value).format('YYYY-MM-DD HH:mm'),
      speed: playbackSpeed.value,
      endTime: dayjs(endDateTime.value).format('YYYY-MM-DD HH:mm'),
      taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),

      currentTime: dayjs(selectedEndTime.value).format('YYYY-MM-DD HH:mm'),
      // status: "continue",
      // status: isPlaying.value ? "continue" : "stop",
      //时间参数

    })))
    console.log("走了这里2");
  }




}

const isChange_flag_firstBackDate = ref(false)
const intervalTimer = ref(null);
// 监听 selectedEndTime(拖动后的当前时间) 的变化，二无停，时间是2025-11-02 16:01:00
// 检测时间间隔
const jiangerTime = ref(0)
const isFirst = ref(true)
watch(
  () => selectedEndTime.value,
  (val) => {
    // console.log("每隔1秒，callBackTimeFn", val);

    // //console.log("每隔111111111122222-----bianhua");
    // 每次改变时间时向ue发送当前时间
    if (window.ue5) {
      window.ue5("callBackCycleTimePointFn", String(JSON.stringify({
        // currentTime: trackCycleTimePoint(formatDateTime(selectedEndTime.value)), 
        currentTime: (formatDateTimeOne(selectedEndTime.value)),
      })));
    }
    // 检查是否满足条件
    if (isChange_flag_firstBackDate.value) {
      // 间隔5分钟即300秒，发送时轴de 当前时间给ue
      const adjustedStep = Math.ceil(300 / playbackSpeed.value);
      if (jiangerTime.value % adjustedStep === 0) {
        if (window.ue5) {
          window.ue5("callTimeLineCurrentTimeFn", String(JSON.stringify({
            year: selectedEndTime.value.getFullYear(),
            month: selectedEndTime.value.getMonth() + 1,
            day: selectedEndTime.value.getDate(),
            hour: selectedEndTime.value.getHours(),
            minute: selectedEndTime.value.getMinutes(),
            second: selectedEndTime.value.getSeconds(),
          })));
        }
      }
      jiangerTime.value += 1;
      // console.log(formatDateTime(selectedEndTime.value), preTimeWindowEnd.value, '时间对比');

      //对比时间----判断是否需要停止,拖动后后端连续返回三条数据,第一条是提示,第二第三条是ue用来定位和平滑的数据,这是后不应该停止时间,到56秒后应该接收到下一条数据时
      // if (compareTime(formatDateTime(selectedEndTime.value), preTimeWindowEnd.value)) {
      //   if (isPlaying.value) {
      //     console.log('歘告诉过');

      //     stopAutoPlay();
      //     // hasPlayed.value = false;
      //     isChange_flag_firstBackDate.value = false;
      //   }

      //   // clearInterval(intervalTimer.value);
      //   // intervalTimer.value = null;
      // }
    }

  },
  { deep: true, immediate: true }
);
// 年月日时间函数
const getDayRangeFromTime = (timeStr) => {
  const [datePart] = timeStr.split(' ');
  const [year, month, day] = datePart.split('-').map(Number);
  const startOfDay = new Date(year, month - 1, day, 0, 0, 0);
  const endOfDay = new Date(year, month - 1, day + 1, 0, 0, 0);
  return [startOfDay, endOfDay];
};
onUnmounted(() => {
  stopAutoPlay();
  window.removeEventListener('mousemove', handleDrag);
  window.removeEventListener('mouseup', endDrag);
  // 保存进入子系统前的实时/历史状态，供 onMounted 恢复时使用
  // 不能依赖 globalLeftWssCONTINE，因为它会被 lefts/index.vue 用 wss 实例覆盖
  useAppStoreInstance.setGlobalIsRealtimeBeforeSub(is_flag_isRealtime.value);
  useAppStoreInstance.setGlobalSubsystemSelectedTimeRange(getDayRangeFromTime(useAppStoreInstance.globalTimeLineEndSelectTime));
  console.log(is_flag_isRealtime.value, '判断状态');
  wsTimeInstance.close()
  // is_flag_isRealtime--true代表实时模式,false--代表历史模式
  //console.log("jieshuli 1，组件卸载时要发暂停",getDayRangeFromTime(useAppStoreInstance.globalTimeLineEndSelectTime)[0],getDayRangeFromTime(useAppStoreInstance.globalTimeLineEndSelectTime)[1]);
  //  储存跳转前的模式--实时模式-true,还是历史模式-false
  localStorage.setItem("is_flag_isRealtime", is_flag_isRealtime.value)
  localStorage.setItem("playbackSpeed", playbackSpeed.value)//储存倍速
  if (is_flag_isRealtime.value) {
    // 实时传输时，组件卸载时要发暂停
    if (window.ue5) {
      window.ue5("callBackSpeedFn", String(JSON.stringify({
        isRealtime: true,
        status: "stop",
        speed: playbackSpeed.value,
        taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
      })));
    }
    wssOpenHandle({
      isRealtime: true,
      status: "stop",
      taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
    })
  } else {
    // 非实时传输时，组件卸载时要发暂停
    if (window.ue5) {

      window.ue5("callBackSpeedFn", String(JSON.stringify({
        isRealtime: is_flag_isRealtime.value ? true : false,
        status: "stop",
        speed: playbackSpeed.value,
        taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
      })));
      wssOpenHandle({
        isRealtime: is_flag_isRealtime.value ? true : false,
        status: "stop",
        taskCode: String(taskCode_everyChange.value) === "" ? useAppStoreInstance.globalRecordMainSysTaskCode || (useAppStoreInstance.globalSubsystemTaskCode) : String(taskCode_everyChange.value),
      })
    }
  }
});

</script>



<style scoped>
.timeline-container {
  /* min-width: 800px; */
  max-width: 1600px;
  height: 140px;
  margin: 0 auto;
  padding: 10px 45px;
  /* font-family: 'Consolas', monospace;  */
  background-color: #000000;
  border-radius: 8px;
  /* box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); */
  opacity: 1 !important;
}

.timeline-controls {
  display: flex;
  justify-content: space-between;
  font-weight: 600;
  font-size: 13px;
  align-items: center;
}

.block {
  display: flex;
  align-items: center;
}

.demonstration {
  margin-right: 10px;
  color: #ababab;
}

.right_block {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 10px;
}

.right_block_center {
  margin: 0 30px;
}

.right_block_conter_btn {
  border: none;
}

.right_block_conter_btn_playbackSpeed {
  background: none;
  border: none;
  color: rgba(255, 255, 255, 1);
  font-size: 20px;
}

.right_block_conter_btn {
  background-color: #404040;
}

.right_block_conter_btn:hover {
  background-color: #8b8b8b;
}

.right_block_conter_btn_center {
  background-color: #2e7dff;
}

.right_block_conter_btn_center:hover {
  background-color: #8CB8FF;
}

:deep(.right_block_confirm_btn) {
  background: linear-gradient(to bottom, #2E7DFF 0%, #000000 100%) !important;
  border: none;
  border-radius: 0;
  border-bottom: 1px solid #062ee1 !important;
  color: rgba(255, 255, 255, 1);
}

/* 时间轴主体 */
.timeline {
  position: relative;
  /* padding-top: -16px; */
  top: 60px;
  background-color: #f80808;
}

/* 时间刻度 - 调整为图片中的样式 */
.time-markers {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 24px;
  z-index: 1;
}

.time-marker {
  position: absolute;
  transform: translateX(-50%);
}

.marker-line {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 8px;
}

/* 修改为主刻度样式 - 红色 */
.marker-line.major-line {
  height: 6px;
  background-color: #929292;
}

.marker-line.minor-line_color {
  height: 10px;
  background-color: rgba(255, 255, 255, 1);
}

/* 时间标签 - 调整为图片中的样式 */
.marker-label {
  position: absolute;
  top: -40px;
  left: -33px;
  font-size: 10px;
  color: #b6b8b8;
  font-weight: 500;
  text-align: center;
  /* white-space: nowrap; */
  padding: 2px 6px;
  border-radius: 4px;
  width: 80px;
  overflow-wrap: break-word;
}

/* 选中区域内的标签样式 */
.marker-label.selected-label {
  color: #ffffff;
  font-weight: bold;
}

/* 滑块容器 */
.slider-container {
  position: absolute;
  top: -6px;
  left: -7px;
  right: -9px;
  margin-top: 8px;
  padding: 0 8px;
}

.slider-track {
  position: relative;
  height: 8px;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s;
}

/* 选中区域 */
.selected-range {
  position: absolute;
  top: -2px;
  height: 100%;
  border-radius: 4px;
  background: #3498db;
  transition: left 0.1s ease, width 0.1s ease;
}

/* 滑块样式 */
.slider-handle {
  position: absolute;
  top: 50%;
  width: 24px;
  height: 24px;
  transform: translate(-50%, -50%);
  cursor: grab;
  z-index: 1;
  transition: transform 0.1s;
}

.slider-handle:active {
  cursor: grabbing;
  transform: translate(-50%, -50%) scale(1.1);
}

.handle-rail {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 5px;
  height: 16px;
  background-color: white;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.8);
  transform: translate(-50%, -50%);
}

.handle-rail:after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 4px;
  height: 15px;
  background-color: #3498db;
  transform: translate(-50%, -50%);
}

/* 滑块提示框 */
.handle-tooltip {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background-color: #2c3e50;
  color: white;
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 12px;
  white-space: nowrap;
  margin-bottom: 12px;
  opacity: 0;
  transition: opacity 0.2s;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.1);
  pointer-events: none;
  z-index: 10000;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* 当鼠标悬停在.handle-rail上时显示.tooltip */
.handle-rail:hover .handle-tooltip,
.handle-rail:hover+.handle-tooltip,
.handle-rail:hover~.handle-tooltip {
  opacity: 1;
}

/* 自动播放时始终显示 */
.handle-tooltip_auto {
  opacity: 1 !important;
}

/* 强制穿透 Scoped CSS，覆盖 Element Plus 默认样式 */
:deep(.el-date-editor.el-input__wrapper) {
  background-color: #1a1a1a !important;
  border-color: #424242 !important;
  box-shadow: none !important;
}

:deep(.el-date-editor .el-input__inner) {
  background-color: #1a1a1a !important;
  color: #ffffff !important;
}

:deep(.el-range-input) {
  color: #ffffff !important;
}

:deep(.el-range-separator) {
  color: #ffffff !important;
}

:deep(.right_block_conter_btn_center) {
  border: none;
}

:deep(.right_block_conter_btn_center:focus) {
  outline: none;
}

:deep(.right_block_conter_btn_playbackSpeed) {
  border: none;
}

:deep(.right_block_conter_btn_playbackSpeed:focus) {
  outline: none;
}

:deep(.satellite-select .el-select__wrapper) {
  height: 12.5px;
}

:deep(.satellite-select .el-select__selected-item) {
  color: #ffffff;
  /* font-size: 10px; */
}

:deep(.satellite-select .el-tooltip__trigger) {
  background-color: #000000 !important;
  color: #f9fafd !important;
  border: none !important;
  box-shadow: none;
}

:deep(.el-select__suffix) {
  opacity: 0;
}

.resetClass {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
</style>