<script setup lang="ts">
import { CaretRightOutlined, PauseOutlined } from '@ant-design/icons-vue';
import { computed, ref, watch } from 'vue';

import { useTimelineTicks } from '../hooks/useTimelineTicks';

const props = defineProps<{
  isPlaying: boolean;
  currentTime: number; // in milliseconds
  totalDuration: number; // in milliseconds
}>();

const emit = defineEmits<{
  (e: 'play'): void;
  (e: 'pause'): void;
  (e: 'seek', time: number): void;
}>();

// --- Constants ---
const SLIDER_PADDING = 8; // Ant Design Slider has 8px padding on each side
const HOUR_IN_MS = 3600 * 1000;

// --- Internal State ---
const internalCurrentTime = ref(props.currentTime);
const selectedHour = ref(Math.floor(props.currentTime / HOUR_IN_MS));

// --- Computed View Range ---
const viewStartTime = computed(() => selectedHour.value * HOUR_IN_MS);
const viewEndTime = computed(() => viewStartTime.value + HOUR_IN_MS);

// --- Ticks Logic ---
const { ticks } = useTimelineTicks(viewStartTime, viewEndTime);

// --- Sync internal time with external prop ---
watch(
  () => props.currentTime,
  (newValue) => {
    internalCurrentTime.value = newValue;
    const newHour = Math.floor(newValue / HOUR_IN_MS);
    if (newHour !== selectedHour.value) {
      selectedHour.value = newHour;
    }
  },
);

// --- Computed properties for display and binding ---
const formatTime = (ms: number): string => {
  if (isNaN(ms) || ms < 0) return '00:00:00';
  const totalSeconds = Math.floor(ms / 1000);
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const seconds = totalSeconds % 60;
  return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
};

const currentTimeFormatted = computed(() => formatTime(internalCurrentTime.value));
const totalDurationFormatted = computed(() => formatTime(props.totalDuration));

const sliderValue = computed({
  get: () => internalCurrentTime.value,
  set: (val: number) => {
    internalCurrentTime.value = val;
    emit('seek', val);
  },
});

const playheadPosition = computed(() => {
  if (!props.totalDuration) return '0%';
  const relativeTime = internalCurrentTime.value - viewStartTime.value;
  const viewDuration = viewEndTime.value - viewStartTime.value;
  return `${(relativeTime / viewDuration) * 100}%`;
});

const hourOptions = computed(() => {
  const numHours = Math.ceil(props.totalDuration / HOUR_IN_MS);
  return Array.from({ length: numHours }, (_, i) => {
    const start = formatTime(i * HOUR_IN_MS).substring(0, 5);
    const end = formatTime((i + 1) * HOUR_IN_MS).substring(0, 5);
    return {
      value: i,
      label: `${start} - ${end}`,
    };
  });
});

// --- Event Handlers ---
const timelineContainerRef = ref<HTMLElement | null>(null);

const handleTimelineClick = (event: MouseEvent) => {
  if (!timelineContainerRef.value || !props.totalDuration) return;

  const rect = timelineContainerRef.value.getBoundingClientRect();
  const effectiveWidth = rect.width - SLIDER_PADDING * 2;
  const clickX = event.clientX - rect.left - SLIDER_PADDING;

  const percentage = Math.max(0, Math.min(1, clickX / effectiveWidth));
  const newTimeInView = percentage * HOUR_IN_MS;
  const newAbsoluteTime = viewStartTime.value + newTimeInView;

  internalCurrentTime.value = newAbsoluteTime;
  emit('seek', newAbsoluteTime);
};

const handlePlayPause = () => {
  if (props.isPlaying) {
    emit('pause');
  } else {
    emit('play');
  }
};
</script>

<template>
  <div class="playback-controller">
    <a-row align="middle" :gutter="16">
      <!-- Play/Pause Button -->
      <a-col>
        <a-button shape="circle" @click="handlePlayPause">
          <template #icon>
            <PauseOutlined v-if="isPlaying" />
            <CaretRightOutlined v-else />
          </template>
        </a-button>
      </a-col>

      <!-- Timestamp -->
      <a-col>
        <a-typography-text class="time-display">
          {{ currentTimeFormatted }} / {{ totalDurationFormatted }}
        </a-typography-text>
      </a-col>

      <!-- Hour Selector -->
      <a-col>
        <a-select v-model:value="selectedHour" style="width: 150px" :options="hourOptions" />
      </a-col>

      <!-- Timeline Slider -->
      <a-col flex="1">
        <div class="timeline-container" ref="timelineContainerRef" @click="handleTimelineClick">
          <div class="timeline-ticks">
            <div class="playhead-marker" :style="{ left: playheadPosition }"></div>
            <span
              v-for="(tick, index) in ticks"
              :key="index"
              class="tick"
              :class="{ 'tick-major': tick.isMajor }"
              :style="{ left: tick.position }"
            >
              <span v-if="tick.label" class="tick-label">{{ tick.label }}</span>
            </span>
          </div>
          <a-slider
            v-model:value="sliderValue"
            :min="viewStartTime"
            :max="viewEndTime"
            :tip-formatter="formatTime as any"
            :tooltip-open="false"
          />
        </div>
      </a-col>
    </a-row>
  </div>
</template>

<style scoped lang="scss">
.playback-controller {
  position: fixed;
  bottom: 0;
  left: 0;
  width: calc(100% - 48px);
  padding: 16px 24px;
  background-color: rgba(255, 255, 255, 0.9);
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  backdrop-filter: blur(5px);
  border-top: 1px solid #f0f0f0;

  body[data-theme='dark'] & {
    background-color: rgba(20, 20, 20, 0.9);
    border-top: 1px solid #303030;
  }
}

.time-display {
  font-family: 'Courier New', Courier, monospace;
  font-size: 14px;
  min-width: 180px; // Prevents layout shift
}

.timeline-container {
  position: relative;
  padding-top: 20px; // Space for tick labels
  margin-bottom: 5px;
  cursor: pointer;
}

.playhead-marker {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background-color: red;
  pointer-events: none;
  z-index: 5;
  transition: left 0.1s linear;
}

.timeline-ticks {
  position: absolute;
  top: 0;
  left: 8px;
  right: 8px;
  height: 20px;
  pointer-events: none;
}

.tick {
  position: absolute;
  bottom: 0;
  width: 1px;
  height: 6px;
  background-color: #a0a0a0;

  &.tick-major {
    height: 10px;
    background-color: #333;
  }
}

.tick-label {
  position: absolute;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 12px;
  color: #555;
  white-space: nowrap;
}

body[data-theme='dark'] {
  .tick {
    background-color: #777;
    &.tick-major {
      background-color: #ddd;
    }
  }
  .tick-label {
    color: #aaa;
  }
}
</style>
