<script setup lang="ts">
import type { TimelineClipData, TimelineTrackData } from '@/lib/Timeline'
import { useCssVar, useElementBounding } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { computed, shallowRef, useTemplateRef } from 'vue'
import { timelineClipColor, toAbsoluteDuration, toAbsoluteTime } from '@/lib/Timeline'
import { toPx, usePx } from '@/lib/usePx'
import { useTimelineStore } from '@/store/TimelineStore'
import { getComponentFor } from '.'

const {
  timelineTrack,
  timelineClip,
} = defineProps<{
  timelineTrack: TimelineTrackData
  timelineClip: TimelineClipData
}>()

const timeline = useTimelineStore()
const { audioTrack } = storeToRefs(timeline)

const contentView = computed(() => getComponentFor(timelineTrack))

const left = computed(() => {
  const t = toAbsoluteTime(audioTrack.value, timelineTrack.reference, timelineClip.clipIn)
  const px = timeline.secondsToPixels(t)
  return toPx(px)
})

const width = usePx(() => {
  const t = toAbsoluteDuration(audioTrack.value, timelineTrack.reference, timelineClip.duration)
  const px = timeline.secondsToPixels(t)
  return px
})

const autorepeat = computed(() => timelineClip.autorepeat)
const color = computed(() => timelineClipColor(timelineTrack, timelineClip))

const isSelected = shallowRef(false)
function selectClip() {
  // TODO: make selection manager
  isSelected.value = !isSelected.value
}

// style:
// - always thin outer border style
// - regular (non-autorepeat):
//   - outer border is 50% black
//   - if not selected, do nothing
//   - if selected, red (inner) outline
// - autorepeat:
//   - outer border is transparent (but still occupies 1px of space)
//   - always dashed thick outer border style
//   - if not selected, custom colored border
//   - if selected, red outline
/* NOTE: the following is "would do anything to avoid hardcoding 4px width limit" */
const selectionRef = useTemplateRef('selection')
const { width: selectionWidth } = useElementBounding(selectionRef)
const outlineSelectedWidth = useCssVar('--timeline-clip-outline-selected-width', selectionRef)
const innerBorderVisible = computed(() => outlineSelectedWidth.value ? selectionWidth.value > 2 * Number.parseInt(outlineSelectedWidth.value, 10) : false)
</script>

<template>
  <div
    class="tw:absolute tw:h-full tw:border tw:rounded-(--timeline-clip-border-radius) tw:overflow-hidden"
    :style="{
      left,
      width: width.string,
      maxWidth: width.string,
      borderColor: autorepeat ? 'transparent' : 'var(--timeline-clip-border-color)',
    }"
    @click="selectClip"
  >
    <!-- background color within outline borders -->
    <div
      v-if="!autorepeat"
      class="tw:absolute tw:size-full"
      :style="{ backgroundColor: color }"
    />

    <component :is="contentView" :track="timelineTrack" :clip="timelineClip" :width="width.number" />

    <!-- selection outline, above content -->
    <div
      v-if="isSelected || autorepeat" ref="selection"
      class="tw:absolute tw:size-full tw:max-w-full tw:pointer-events-none tw:select-none"
      :class="{ selection: isSelected, autorepeat }"
      :style="!isSelected ? { borderColor: color } : null"
    >
      <div
        v-if="!autorepeat && innerBorderVisible"
        class="tw:absolute tw:size-full tw:max-w-full selection-inner"
      />
    </div>
  </div>
</template>

<style scoped>
.selection {
  border: var(--timeline-clip-outline-selected);
}

.autorepeat {
  border-width: var(--timeline-clip-outline-selected-width);
  border-style: dashed;
}

.selection-inner {
  border: 1px solid var(--timeline-clip-border-color-inner);
}
</style>
