<template>
  <LiveSessionPanel
    v-if="isLiveSession"
    :session="camera"
    :inline="inline"
    @close="$emit('close')"
  />
  <aside
    v-else
    class="flex flex-col border border-kestrel-border bg-kestrel-surface"
    :class="asideClass"
    role="dialog"
    aria-label="Camera feed"
  >
    <div class="flex items-center justify-between border-b border-kestrel-border px-4 py-3 [box-shadow:0_1px_0_0_rgba(34,201,201,0.08)]">
      <h2 class="font-medium tracking-wide text-kestrel-text [text-shadow:0_0_8px_rgba(34,201,201,0.25)]">
        {{ camera?.name ?? 'Camera' }}
      </h2>
      <button
        type="button"
        class="rounded p-1 text-kestrel-muted transition-colors hover:bg-kestrel-border hover:text-kestrel-accent"
        aria-label="Close panel"
        @click="$emit('close')"
      >
        <span class="text-xl leading-none">&times;</span>
      </button>
    </div>
    <div class="flex-1 overflow-auto p-4">
      <div class="relative aspect-video w-full overflow-hidden rounded border border-kestrel-border bg-black [box-shadow:inset_0_0_20px_-8px_rgba(34,201,201,0.1)]">
        <template v-if="sourceType === 'hls'">
          <video
            ref="videoRef"
            class="h-full w-full object-contain"
            muted
            autoplay
            playsinline
          />
        </template>
        <template v-else>
          <img
            v-if="safeStreamUrl && !streamError"
            :src="safeStreamUrl"
            alt="Live feed"
            class="h-full w-full object-contain"
            @error="streamError = true"
          >
          <div
            v-else-if="streamError || (!safeStreamUrl && streamUrl)"
            class="flex h-full w-full items-center justify-center text-xs uppercase tracking-wider text-kestrel-muted"
          >
            [ Stream unavailable ]
          </div>
        </template>
      </div>
    </div>
  </aside>
</template>

<script setup>
const props = defineProps({
  /** Device (streamUrl, sourceType, name) or live session (id, label, hasStream) */
  camera: {
    type: Object,
    default: null,
  },
  /** When true, render inline (e.g. on Cameras page) instead of overlay */
  inline: {
    type: Boolean,
    default: false,
  },
})

defineEmits(['close'])

const videoRef = ref(null)
const streamError = ref(false)

const isLiveSession = computed(() =>
  props.camera && typeof props.camera.hasStream !== 'undefined')

const asideClass = computed(() =>
  props.inline ? 'rounded-lg shadow-glow' : 'absolute right-0 top-0 z-[1000] h-full w-full border-l shadow-glow md:w-[420px] [box-shadow:-8px_0_24px_-4px_rgba(34,201,201,0.12)]')

const streamUrl = computed(() => props.camera?.streamUrl ?? '')
const sourceType = computed(() => (props.camera?.sourceType === 'hls' ? 'hls' : 'mjpeg'))

const safeStreamUrl = computed(() => {
  const u = streamUrl.value
  return typeof u === 'string' && u.trim() && (u.startsWith('http://') || u.startsWith('https://')) ? u.trim() : ''
})

function initHls() {
  const url = streamUrl.value
  if (!url || sourceType.value !== 'hls' || typeof window === 'undefined') return
  const Hls = window.Hls
  if (Hls?.isSupported() && videoRef.value) {
    const hls = new Hls()
    hls.loadSource(url)
    hls.attachMedia(videoRef.value)
  }
  else if (videoRef.value?.canPlayType?.('application/vnd.apple.mpegurl')) {
    videoRef.value.src = url
  }
}

onMounted(() => {
  if (sourceType.value === 'hls') {
    import('hls.js').then((mod) => {
      if (typeof window === 'undefined') return
      window.Hls = mod.default
      nextTick(initHls)
    })
  }
})

onBeforeUnmount(() => {
  if (videoRef.value) videoRef.value.src = ''
})
</script>
