<script lang="ts" setup>
import { h, onMounted, ref, watch } from 'vue';
import { NButton, NSelect, NSpace, useMessage } from 'naive-ui';
import { Pause } from '@vicons/ionicons5';
import { PlayCircle48Regular } from '@vicons/fluent';
import { create3D } from '@/api/utils/cesium';
import { createModel, createPolyLine, getElevationFromRay, startVehicleMovement, cleanLine, getElevationFromRays } from '@/api/utils/cesiumUtil';
import { remove } from 'nprogress';
import { toConvertLongitudeAndLatitude } from '@/api/utils/coordinateUtil';
import { getModel } from '@/api/utils/cesiumModel';
import { getModelAllApi, getPersonPointApi } from '@/api';

let viewer: any = null;
const range = ref<any>(null);
const personValue = ref('');
const serarchData = ref({
  username: '',
  startTime: '',
  endTime: ''
});
const isShow = ref(false);
const value = ref(null);
const options = ref();
const message = useMessage();
// 进度条相关状态
const speed = ref('1x');
const speedOptions = [
  { label: '1x', value: '50' },
  { label: '10x', value: '100' },
  { label: '20x', value: '200' },
  { label: '30x', value: '300' },
];
const elapsedSeconds = ref(0);
const position = ref([])

// zhangyang
const positions = ref<any[]>([]);
const lineValue = ref<any>();
const model = ref<any>();
const progressFill = ref<HTMLDListElement | null>(null);

let totalSeconds = 3600;
let stepPercent = 100 / totalSeconds;
let currentProgress: any = 0;
let elapsed = 0;
let intervalId: any = null;

// 修改为响应式变量，用于记录暂停状态
const pausedPosition = ref(null);
const remainingSeconds = ref(0);
const isPaused = ref(false);

// 禁用超出一小时范围的日期选择
function disabledDate(current: number, type: string) {
  // 如果是日期范围选择器的结束日期，并且已经选择了开始日期
  if (type === 'end' && range.value && range.value[0]) {
    const startDate = new Date(range.value[0]);
    const minEndDate = new Date(startDate);
    const maxEndDate = new Date(startDate);

    // 设置最大结束时间为开始时间加1小时
    maxEndDate.setHours(maxEndDate.getHours() + 1);

    // 禁用超出一小时范围的日期
    return current > maxEndDate.getTime();
  }
  return false;
}

// 更新进度
function updateProgress() {
  if (elapsed >= totalSeconds) return;
  elapsed++;

  if (elapsed === totalSeconds) currentProgress = 100;

  progressFill.value.style.width = `${currentProgress}%`;
  stepPercent = 100 / totalSeconds;
  currentProgress += stepPercent;

  if (currentProgress > 99) {
    isShow.value = false;
  }

  if (elapsed >= totalSeconds) {
    pauseProgress();
    resetProgress();
  }
}

// 开始进度
function startProgress() {
  if(!model.value && !lineValue.value){
    message.warning("请选择指定车辆和时间")
  }
  if (viewer.clock.shouldAnimate) {
    // 暂停状态
    isShow.value = false;
    viewer.clock.shouldAnimate = false;
    pauseProgress();
    isPaused.value = true;
    pausedPosition.value = viewer.clock.currentTime; // 保存当前时间位置
  } else if (model.value && lineValue.value) {
    isShow.value = true;
    // 开始或恢复播放
    if (isPaused.value) {
      // 从暂停状态恢复，不重置任何进度
      viewer.clock.shouldAnimate = true;
      if (intervalId) return;
      intervalId = setInterval(updateProgress, 1000);
      isPaused.value = false;
    } else {
      // 全新开始
      totalSeconds = totalSeconds / speed.value;
      startVehicleMovement(viewer, totalSeconds);
      if (intervalId) return;
      if (elapsed >= totalSeconds) return;
      intervalId = setInterval(updateProgress, 1000);
    }
  }
}

function resetProgress() {
  pauseProgress();
  stepPercent = 100 / totalSeconds;
  currentProgress = 0;
  elapsed = 0;
  // UI 归零
  setTimeout(() => {
    progressFill.value.style.width = '0%';
  }, 500)
}

// 暂停进度
function pauseProgress() {
  if (!intervalId) return;
  clearInterval(intervalId);
  intervalId = null;
}

// 监听选取的人员
function selectChange(item:any) {
  personValue.value = item;
}
// 监听时间范围变化
function watchTimeData(newRange: any) {
  if (newRange && newRange.length === 2) {
    const startDate = new Date(newRange[0]);
    const endDate = new Date(newRange[1]);

    // 计算时间差（毫秒）
    const durationMs = endDate.getTime() - startDate.getTime();
    const durationHours = durationMs / (1000 * 60 * 60);

    // 如果超出一小时，给出提示
    if (durationHours > 1) {
      message.warning('时间范围不能超过一小时，请重新选择');
      range.value = null;
      serarchData.value.startTime = '';
      serarchData.value.endTime = '';
      return;
    }

    serarchData.value.startTime = newRange[0];
    serarchData.value.endTime = newRange[1];

    // 计算总时长（毫秒转秒）
    const durationMs1 = endDate.getTime() - startDate.getTime();
    totalSeconds = Math.floor(durationMs1 / 1000);
    elapsedSeconds.value = 0;
    updateProgress();
  }
}

function add3dtiles() {
  const CesiumConfig = {
    defaultAccessToken:
      'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2NTE1OTUxOS1jNTc5LTQwNmMtOWU5My1jNTI3NTIyYzAxNTUiLCJpZCI6MjUwODM5LCJpYXQiOjE3Mjk5MjE1MzV9.xromwPD3oA1e0YsWV035DE5KmYvivkC6fxt344vwObA'
  };

  Cesium.Ion.defaultAccessToken = CesiumConfig.defaultAccessToken;

  viewer = new Cesium.Viewer('cesiumcontainer', {
    geocoder: false,
    homeButton: false,
    infoBox: false,
    animation: false,
    fullscreenButton: false,
    enableCompass: true, // 启用指南针
    enableCompassOuterRing: true, // 启用指南针外环
    sceneModePicker: false,
    timeline: false,
    navigationHelpButton: false,
    baseLayerPicker: false,
    enableZoomControls: false, // 禁用缩放控件
    enableDistanceLegend: false // 禁用比例尺
  });

  viewer.scene.globe.depthTestAgainstTerrain = true;
  viewer.scene.globe.depthTestAgainstTerrain = true;
  viewer.cesiumWidget.creditContainer.style.display = 'none';
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

  getModel().then(item => {
    create3D(viewer, item, 0);
  });
}

function handleclear() {
  serarchData.value.startTime = '';
  serarchData.value.endTime = '';
}

function handleReset() {
  isShow.value = false;
  //删除模型
  if (model.value) {
    viewer.entities.remove(model.value);
    
  }
  viewer.entities.remove(positions.value);
  serarchData.value.startTime = '';
  serarchData.value.endTime = '';
  //进度条清空
  resetProgress();
  value.value = null;
  range.value = null;
  //删除线
  cleanLine(viewer, positions.value);
  personValue.value = '';
  positions.value = [];
  lineValue.value = [];
}

function handlerClean() {
  isShow.value = false;
  //删除模型
  if (model.value) {
    viewer.entities.remove(model.value);
  }
  //进度条清空
  resetProgress();
  //删除线
  cleanLine(viewer, positions.value);
  viewer.entities.remove(positions.value);
  positions.value = [];
  lineValue.value = [];
}

function selectSpeed(e) {
  speed.value = e;
  totalSeconds = 3600 / Number(e);
  isShow.value = false;
  // 重置所有进度相关变量
  resetProgress();

  // 确保viewer.clock处于正确状态
  if (viewer) {
    viewer.clock.shouldAnimate = false;
    viewer.clock.currentTime = Cesium.JulianDate.now();
  }

  // 移除并重新创建模型
  if (model.value) {
    viewer.entities.remove(model.value);
    model.value = null;
  }

  // 确保positions数组有数据才创建模型
  if (positions.value && positions.value.length > 0) {
    model.value = createModel(positions.value, viewer);

    // 确保路线也存在
    if (!lineValue.value && positions.value.length >= 2) {
      lineValue.value = createPolyLine(positions.value, viewer);
    }

    // 手动触发开始进度，确保车辆开始移动
    // setTimeout(() => {
    if (model.value && lineValue.value) {
      // 重置isPaused状态，确保是全新开始
      isPaused.value = false;
      // 直接调用startVehicleMovement开始车辆移动
      startVehicleMovement(viewer, totalSeconds);

      // 启动进度条更新
      if (intervalId) clearInterval(intervalId);
      intervalId = setInterval(updateProgress, 1000);

      // 更新UI状态
      isShow.value = true;
    }
    // }, 100);
  }
}
async function handleSearch() {
  handlerClean()
  if (serarchData.value.startTime && serarchData.value.endTime) {
    let data = {
      cardId: personValue.value,
      startTime: serarchData.value.startTime,
      endTime: serarchData.value.endTime
    }
      
    let res = await getPersonPointApi(data);
    if(res.data.code == 200) {
      for(let item of res.data.data){
        const cartographic = Cesium.Cartographic.fromDegrees(item.lon, item.lat);
        const height = await getElevationFromRays(cartographic, viewer);
        const adjustedHeight = height;
        const cartesian = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, adjustedHeight);
        positions.value.push(cartesian)
      }
       
      model.value = createModel(positions.value, viewer);
      undataLine();
    } else {
      message.error(res.data.msg);
    }
  } else {
    message.info('请先选择您要看的时间点');
  }
}
// 添加开始和结束时间显示
function formatDateTime(date: any) {
  if (!date) return '';
  const d = new Date(date);
  return d.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  });
}

async function undataLine() {
  lineValue.value = createPolyLine(positions.value, viewer);
}

async function search() {
  let res = await getModelAllApi();
  options.value = res.data.data;
}

onMounted(() => {
  add3dtiles();
  updateProgress();
  search();
});
</script>

<template>
  <div class="track-page">
    <div style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center">
      <NSpace>
        <div style="display: flex; align-items: center">
          人员姓名
          <NSpace vertical style="width: 200px; margin-left: 10px">
            <NSelect v-model:value="value" :options="options" label-field="realName" value-field="cardId" @update:value="selectChange" />
          </NSpace>
        </div>
        <div style="display: flex; align-items: center; margin-left: 30px">
          <NDatePicker v-model:value="range" type="datetimerange" clearable style="margin-left: 10px"
            :disabled-date="disabledDate" @update:value="watchTimeData" @clear="handleclear" />
        </div>

        <NButton color="#2198f2" style="padding: 0px 17px; border-radius: 5px; margin-left: 40px" @click="handleSearch">
          查询
        </NButton>
        <NButton style="padding: 0px 17px; border-radius: 5px" @click="handleReset">重置</NButton>
      </NSpace>
    </div>

    <!-- cesium -->
    <div id="cesiumcontainer">
      <div class="progress-container">
        <!-- 添加开始和结束时间显示 -->
        <div class="time-range-display">
          <div class="start-time">{{ formatDateTime(serarchData.startTime) }}</div>
          <div class="end-time">{{ formatDateTime(serarchData.endTime) }}</div>
        </div>
        <div class="left-controls">
          <NIcon v-if="!isShow" class="control-btn" size="35px" @click="startProgress()">
            <PlayCircle48Regular />
          </NIcon>
          <NIcon v-if="isShow" class="control-btn" size="35px" @click="startProgress()">
            <Pause />
          </NIcon>
        </div>
        <!-- 进度条 -->
        <div class="progress-bar">
          <div ref="progressFill" class="progress-fill"></div>
          <div class="progress-dots">
            <div class="progress-dot"></div>
            <div class="progress-dot"></div>
            <div class="progress-dot"></div>
            <div class="progress-dot"></div>
            <div class="progress-dot"></div>
            <div class="progress-dot"></div>
            <div class="progress-dot"></div>
            <div class="progress-dot"></div>
            <div class="progress-dot"></div>
            <div class="progress-dot"></div>
            <div class="progress-dot"></div>
            <div class="progress-dot"></div>
          </div>
          <div id="progressText" class="progress-text"></div>
        </div>
        <div class="progress-time">60分</div>
        <div class="right-controls">
          <NSelect v-model:value="speed" :options="speedOptions" style="width: 80px; margin-left: 10px"
            @update:value="selectSpeed" />
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
#home {
  width: 100%;
  height: 100%;
}

#cesiumcontainer {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  box-sizing: border-box;
  contain: strict;
  isolation: isolate;
}

.progress-container {
  position: absolute;
  width: 100%;
  height: 100px;
  background-color: rgba(0, 0, 0, 0.85);
  top: 90%;
  z-index: 3;
}

.progress-bar {
  width: 85%;
  height: 15px;
  background: rgba(46, 46, 46);
  border-radius: 15px;
  overflow: hidden;
  margin-bottom: 10px;
  position: relative;
  margin-left: 80px;
  margin-top: 40px;
  display: flex;
  align-items: center;
}

.progress-dots {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: space-around;
  align-items: center;
  padding: 0 5%;
  box-sizing: border-box;
  pointer-events: none;
}

.progress-dot {
  width: 12px;
  height: 12px;
  background-image: url('@/assets/dian.png');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #00c6ff, #0072ff);
  transition: width 0.3s ease;
  border-radius: 15px;
  box-shadow: 0 0 15px rgba(0, 114, 255, 0.5);
}

.progress-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: white;
  font-weight: bold;
  font-size: 14px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}

.left-controls {
  position: absolute;
  color: white;
  margin: 30px 0 0 30px;
}

.right-controls {
  position: absolute;
  top: 30px;
  left: 94%;
}

.progress-time {
  position: absolute;
  top: 35px;
  left: 90%;
  color: white;
}

.time-range-display {
  height: 0px;
  display: flex;
  justify-content: space-between;
  padding: 0px 205px 0px 80px;
  color: #e8e8e7;
  font-size: 14px;
}

.start-time {
  text-align: left;
  margin-top: 10px;
}

.end-time {
  text-align: right;
  margin-top: 10px;
}

.control-btn {
  border: none;
  color: white;
  font-size: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
}
</style>
