<script lang="ts" setup>
import { computed, nextTick, ref } from "vue";
import monitorVideo from "../assets/循环背景动画.mp4";

type GridMode = 1 | 4 | 9;

interface CameraItem {
  id: string;
  name: string;
  type: string;
  status: string;
}

interface DeviceNode {
  id: string;
  name: string;
  cameras: CameraItem[];
}

interface ProjectNode {
  id: string;
  name: string;
  devices: DeviceNode[];
}

interface ProjectCameraItem extends CameraItem {
  deviceId: string;
  deviceName: string;
}

const projectData: ProjectNode = {
  id: "project-1",
  name: "西江隧道",
  devices: [
    {
      id: "ROBOT-001",
      name: "巡检机器人 R1",
      cameras: [
        { id: "CAM-001", name: "白光镜头", type: "白光", status: "在线" },
        { id: "CAM-002", name: "红外镜头", type: "红外", status: "在线" },
        { id: "CAM-003", name: "云台辅助镜头", type: "辅助", status: "在线" },
      ],
    },
    {
      id: "ROBOT-002",
      name: "巡检机器人 R2",
      cameras: [
        { id: "CAM-004", name: "白光镜头", type: "白光", status: "在线" },
        { id: "CAM-005", name: "红外镜头", type: "红外", status: "在线" },
      ],
    },
  ],
};

const gridMode = ref<GridMode>(4);
const activeCameraId = ref(projectData.devices[0].cameras[0].id);
const playbackDialogVisible = ref(false);
const playbackStartAt = ref("2026-06-23T14:20");
const playbackEndAt = ref("2026-06-23T14:50");
const playbackProgress = ref(0);
const playbackPaused = ref(true);
const playbackPlayerRef = ref<HTMLVideoElement | null>(null);

const currentProject = computed(() => projectData);

const projectCameras = computed<ProjectCameraItem[]>(() =>
  currentProject.value.devices.flatMap((device) =>
    device.cameras.map((camera) => ({
      ...camera,
      deviceId: device.id,
      deviceName: device.name,
    })),
  ),
);

const activeCamera = computed(
  () =>
    projectCameras.value.find((camera) => camera.id === activeCameraId.value) ??
    projectCameras.value[0],
);

const orderedCameras = computed(() => {
  const selected = activeCamera.value;

  return projectCameras.value
    .filter((camera) => camera.id !== selected.id)
    .reduce<ProjectCameraItem[]>((list, camera) => {
      list.push(camera);
      return list;
    }, [selected]);
});

const visibleCameras = computed(() => {
  const countMap: Record<GridMode, number> = {
    1: 1,
    4: 4,
    9: 9,
  };
  const targetCount = countMap[gridMode.value];
  const cameras = orderedCameras.value;

  return Array.from({ length: targetCount }, (_, index) => cameras[index] ?? null);
});

const playbackRangeLabel = computed(() => {
  const startLabel = playbackStartAt.value.replace("T", " ");
  const endLabel = playbackEndAt.value.replace("T", " ");
  return `${startLabel} - ${endLabel}`;
});

function selectCamera(cameraId: string) {
  activeCameraId.value = cameraId;
}

function setGridMode(mode: GridMode) {
  gridMode.value = mode;
}

function syncPlaybackProgress() {
  const video = playbackPlayerRef.value;

  if (!video) {
    playbackProgress.value = 0;
    playbackPaused.value = true;
    return;
  }

  const duration = Number.isFinite(video.duration) ? video.duration : 0;
  playbackProgress.value = duration > 0 ? (video.currentTime / duration) * 100 : 0;
  playbackPaused.value = video.paused;
}

function startPlayback() {
  const video = playbackPlayerRef.value;

  if (!video) {
    return;
  }

  video.currentTime = 0;
  void video.play();
  playbackPaused.value = false;
  syncPlaybackProgress();
}

async function openPlaybackDialog() {
  playbackDialogVisible.value = true;
  playbackProgress.value = 0;
  playbackPaused.value = true;

  await nextTick();
  startPlayback();
}

function closePlaybackDialog() {
  playbackPlayerRef.value?.pause();
  playbackDialogVisible.value = false;
  playbackPaused.value = true;
}

function togglePlaybackPause() {
  const video = playbackPlayerRef.value;

  if (!video) {
    return;
  }

  if (video.paused) {
    void video.play();
  } else {
    video.pause();
  }

  syncPlaybackProgress();
}

function seekPlayback(offsetSeconds: number) {
  const video = playbackPlayerRef.value;

  if (!video) {
    return;
  }

  const duration = Number.isFinite(video.duration) ? video.duration : 0;
  const targetTime = Math.max(0, Math.min(duration, video.currentTime + offsetSeconds));
  video.currentTime = targetTime;
  syncPlaybackProgress();
}

function updatePlaybackProgress() {
  const video = playbackPlayerRef.value;

  if (!video) {
    return;
  }

  const duration = Number.isFinite(video.duration) ? video.duration : 0;
  if (duration <= 0) {
    return;
  }

  video.currentTime = (playbackProgress.value / 100) * duration;
}
</script>

<template>
  <div class="page-shell video-center-page video-center-shell">
    <div class="video-center-layout">
      <aside class="page-card video-tree-card">
        <div class="page-card-title">摄像头列表</div>
        <div class="tree-panel">
          <div class="tree-panel-project">
            <div class="tree-panel-project-name">{{ currentProject.name }}</div>
            <div class="tree-panel-project-meta">共 {{ projectCameras.length }} 路摄像头</div>
          </div>
          <div class="tree-device-list">
            <button
              v-for="camera in projectCameras"
              :key="camera.id"
              :class="['tree-device-btn', { active: activeCameraId === camera.id }]"
              type="button"
              @click="selectCamera(camera.id)"
            >
              <span class="tree-device-name">{{ camera.name }}</span>
              <span class="tree-device-id">{{ camera.deviceName }} / {{ camera.id }}</span>
            </button>
          </div>
          <div class="tree-panel-footer">
            <button class="tree-playback-btn" type="button" @click="openPlaybackDialog">
              录像回放
            </button>
          </div>
        </div>
      </aside>

      <section class="page-card video-wall-card">
        <div class="video-wall-header">
          <div>
            <div class="page-card-title">视频播放</div>
            <div class="video-wall-meta">
              {{ currentProject.name }} / {{ activeCamera.name }}
            </div>
          </div>
          <div class="grid-switch">
            <button
              v-for="mode in [1, 4, 9]"
              :key="mode"
              :class="['grid-switch-btn', { active: gridMode === mode }]"
              type="button"
              @click="setGridMode(mode as GridMode)"
            >
              {{ mode }} 宫格
            </button>
          </div>
        </div>

        <div :class="['video-grid-board', `grid-${gridMode}`]">
          <div
            v-for="(camera, index) in visibleCameras"
            :key="camera?.id ?? `empty-${index}`"
            class="video-grid-cell"
          >
            <template v-if="camera">
              <video autoplay loop muted playsinline :src="monitorVideo"></video>
              <div class="video-cell-top">
                <span class="cell-badge">LIVE</span>
                <span class="cell-type">{{ camera.type }}</span>
              </div>
              <div class="video-cell-bottom">
                <div class="cell-name">{{ camera.name }}</div>
                <div class="cell-meta">{{ camera.deviceName }} / {{ camera.status }}</div>
              </div>
            </template>
            <template v-else>
              <div class="video-empty">
                <span>未分配画面</span>
              </div>
            </template>
          </div>
        </div>
      </section>
    </div>

    <div
      v-if="playbackDialogVisible && activeCamera"
      class="playback-dialog-mask"
      @click.self="closePlaybackDialog"
    >
      <div class="playback-dialog">
        <div class="playback-dialog-header">
          <div>
            <div class="playback-dialog-title">录像回放</div>
            <div class="playback-dialog-meta">
              {{ activeCamera.deviceName }} / {{ activeCamera.name }} / {{ activeCamera.id }}
            </div>
          </div>
          <button class="dialog-close" type="button" @click="closePlaybackDialog">×</button>
        </div>

        <div class="playback-dialog-filter">
          <label class="playback-field">
            <span>开始时间</span>
            <input v-model="playbackStartAt" type="datetime-local" />
          </label>
          <label class="playback-field">
            <span>结束时间</span>
            <input v-model="playbackEndAt" type="datetime-local" />
          </label>
          <button class="playback-btn playback-launch-btn" type="button" @click="startPlayback">
            开始回放
          </button>
        </div>

        <div class="playback-preview">
          <video
            ref="playbackPlayerRef"
            :src="monitorVideo"
            playsinline
            @ended="syncPlaybackProgress"
            @loadedmetadata="syncPlaybackProgress"
            @pause="syncPlaybackProgress"
            @play="syncPlaybackProgress"
            @timeupdate="syncPlaybackProgress"
          ></video>
        </div>

        <div class="playback-dialog-controls">
          <button class="playback-btn" type="button" @click="togglePlaybackPause">
            {{ playbackPaused ? "播放" : "暂停" }}
          </button>
          <button class="playback-btn" type="button" @click="seekPlayback(-10)">快退 10s</button>
          <button class="playback-btn" type="button" @click="seekPlayback(10)">快进 10s</button>
          <div class="playback-track">
            <div class="playback-track-line">
              <span :style="{ width: `${playbackProgress}%` }"></span>
            </div>
            <input
              v-model="playbackProgress"
              class="playback-range"
              max="100"
              min="0"
              type="range"
              @input="updatePlaybackProgress"
            />
          </div>
          <div class="playback-time">{{ playbackRangeLabel }}</div>
        </div>
      </div>
    </div>
  </div>
</template>
