<template>
  <LiveSessionPanel
    v-if="isLiveSession"
    :session="camera"
    :inline="inline"
    @close="$emit('close')"
  />
  <aside
    v-else
    class="kestrel-panel-base"
    :class="inline ? 'kestrel-panel-inline' : 'kestrel-panel-overlay'"
    role="dialog"
    aria-label="Camera feed"
  >
    <div class="kestrel-panel-header">
      <h2 class="font-medium tracking-wide text-kestrel-text text-shadow-glow-sm">
        {{ camera?.name ?? 'Camera' }}
      </h2>
      <button
        type="button"
        class="kestrel-close-btn"
        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="kestrel-video-frame">
        <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?.hasStream !== undefined)

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

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

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>
