<script setup lang="ts">
import type { LightboxItem } from './lightbox.types'

import { BglVideo, Btn, Icon, Zoomer, Image, normalizeURL, Swiper, downloadFile, useEscapeKey } from '@bagelink/vue'
import { computed, ref, watch } from 'vue'
import LightboxImage from './LightboxImage.vue'

const isOpen = ref(false)
const group = ref<LightboxItem[]>([])
const currentIndex = ref(0)
const currentItem = computed<LightboxItem>(() => group.value[currentIndex.value])
const zoom = ref(1)

const canSwipe = computed(() => zoom.value === 1)

// Advanced options that update reactively
const swiperAdvancedOptions = computed(() => ({
	allowTouchMove: zoom.value === 1,
	touchRatio: zoom.value === 1 ? 1 : 0,
	simulateTouch: zoom.value === 1,
}))

function open(item: LightboxItem, groupItems?: LightboxItem[]) {
	isOpen.value = true
	group.value = groupItems || [item]
	currentIndex.value = group.value.findIndex((groupItem) => {
		const hasSrcMatch = item.src !== undefined && item.src !== null && item.src !== ''
			&& groupItem.src === item.src
		const hasPathMatch = item.pathKey !== undefined && item.pathKey !== null && item.pathKey !== ''
			&& groupItem.pathKey === item.pathKey
		return hasSrcMatch || hasPathMatch
	})
	if (currentIndex.value === -1) currentIndex.value = 0
	zoom.value = 1
}

function close() {
	isOpen.value = false
}

useEscapeKey(close, isOpen)

function selectItem(index: number) {
	currentIndex.value = index
	zoom.value = 1
	// The v-model will handle updating the swiper
}

watch(() => isOpen.value, (val) => {
	if (val) {
		document.body.style.overflow = 'hidden'
	} else {
		document.body.style.overflow = ''
	}
})

watch(() => currentIndex.value, () => {
	// Reset zoom when changing slides
	zoom.value = 1
})

defineExpose({ open, close })
</script>

<template>
	<transition name="fade">
		<div v-if="isOpen" class="bgl-lightbox-overlay" @keydown.esc="close">
			<div class="flex start w-100 space-between p-025 z-9" @click="close">
				<Btn flat class="color-white" icon="close" @click="close" />
				<div v-if="currentItem?.enableZoom && currentItem?.type === 'image'" class="center">
					<Btn flat class="color-white" icon="remove" :disabled="zoom === 1" @click="zoom--" />
					<Btn flat class="color-white" icon="zoom_in" :disabled="zoom === 1" @click="zoom = 1" />
					<Btn flat class="color-white" icon="add" :disabled="zoom === 3" @click="zoom++" />
				</div>
				<Btn v-if="currentItem?.openFile && currentItem?.src" class="color-white" round thin flat
					iconEnd="arrow_outward" value="$t:lightbox.openFile" :href="currentItem?.src" target="_blank" />
				<Btn v-if="currentItem?.download && currentItem?.src" class="color-white" round thin flat
					icon="download" value="Download File" @click="downloadFile(currentItem?.src)" />
				<div v-if="!currentItem?.openFile && !currentItem?.download" />
			</div>

			<Swiper v-if="group && group.length > 0" v-model:index="currentIndex" :items="group"
				:initial-slide="currentIndex" class="bgl-lightbox-swiper" :class="{ zoomed: zoom > 1 }"
				:navigation="group.length > 1" :grab-cursor="canSwipe" :keyboard="true" :loop="false" :speed="400"
				:slides-per-view="1" :space-between="0" effect="slide" :advanced-options="swiperAdvancedOptions"
				@click.stop>
				<template #default="{ item }">
					<div class="bgl-lightbox-item">
						<Zoomer v-if="item.type === 'image'" v-model:zoom="zoom" :disabled="!item?.enableZoom"
							:mouse-wheel-to-zoom="false" :double-click-to-zoom="true" :max-scale="5" :min-scale="1"
							:aspect-ratio="0" :limit-translation="true" @click.stop>
							<LightboxImage :src="item?.src" />
						</Zoomer>

						<BglVideo v-else-if="item?.type === 'video' && item?.src" :src="item?.src" autoplay controls
							class="lightbox-video" />

						<div v-else-if="item?.type === 'pdf' && item?.src" class="lightbox-pdf">
							<embed :src="normalizeURL(item?.src)" type="application/pdf" :title="item?.name">
						</div>

						<div v-else class="lightbox-file">
							<div class="file-info txt-white flex m_block align-items-start gap-025">
								<Icon class="m-0 m_none" icon="draft" :size="10" weight="12" />
								<Icon class="m-0 none m_block m_-mb-1" icon="draft" :size="4" weight="2" />

								<div class="txt-start">
									<p class="mx-0 light">
										File:
										<span class="semi word-break-all">{{ item?.name }}</span>
									</p>
									<p class="mx-0">
										Type:
										<span class="semi">{{ item?.type }}</span>
									</p>
									<Btn :href="item?.src" target="_blank" round thin class="mt-1" value="Open file" />
								</div>
							</div>
						</div>
					</div>
				</template>

				<template #prev-button="{ prev }">
					<Btn icon="arrow_back" color="black" @click="prev" />
				</template>

				<template #next-button="{ next }">
					<Btn icon="arrow_forward" color="black" @click="next" />
				</template>
			</Swiper>

			<div v-if="group && group.length > 1" class="lightbox-thumbnails" @click.stop>
				<template v-for="(item, index) in group" :key="index">
					<Image v-if="item.type === 'image'" class="thumbnail" :src="item.src" alt=""
						:class="{ active: currentIndex === index }" @click.stop="selectItem(index)" />
					<Icon v-else class="thumbnail thumbnail-icon" icon="description"
						:class="{ active: currentIndex === index }" @click.stop="selectItem(index)" />
				</template>
			</div>
		</div>
	</transition>
</template>

<style>

.bgl-lightbox:has(.bgl_vid) {
width: 90vw;
}

.bgl-lightbox:has(.vid_short) {
width: auto;
aspect-ratio: 9/16;
height: 90vh;
}

.bgl-lightbox:has(.vid_short) .bgl-lightbox-item * {
max-height: unset !important;
}

.lightbox-image {
object-fit: contain;
width: fit-content;
}

.bgl-lightbox-overlay {
position: fixed;
width: 100vw;
height: 100vh;
display: grid;
grid-template-rows: 50px 1fr 100px;
z-index: 9999;
inset: 0;
background: rgba(0, 0, 0, 0.8);
overflow: hidden;
}

/* Top controls row */
.bgl-lightbox-overlay>.flex:first-child {
grid-row: 1;
align-self: start;
}

/* Main content row - Swiper */
.bgl-lightbox-swiper {
grid-row: 2;
width: 100vw;
height: 100%;
overflow: hidden;
}

/* Bottom thumbnails row */
.lightbox-thumbnails {
grid-row: 3;
align-self: end;
}

.bgl-lightbox-swiper .swiper {
width: 100%;
height: 100%;
}

.bgl-lightbox-swiper .swiper-wrapper {
align-items: center;
}

.bgl-lightbox-item {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
animation: 200ms ease bgl-lightbox-load;
}

/* Navigation button styling */
.lightbox-nav-btn {
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(8px);
border-radius: 50%;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
color: white;
cursor: pointer;
transition: all 0.2s ease;
}

.lightbox-nav-btn:hover {
background: rgba(0, 0, 0, 0.8);
transform: scale(1.05);
}

.lightbox-nav-btn:active {
transform: scale(0.95);
}

/* Adjust swiper navigation positioning */
.bgl-lightbox-swiper :deep(.swi-ctrl) {
padding: 0 1.5rem !important;
}

@media screen and (max-width: 900px) {
.bgl-lightbox-swiper :deep(.swi-ctrl) {
	padding: 0 1rem !important;
}

.lightbox-nav-btn {
	width: 40px;
	height: 40px;
}
}

@keyframes bgl-lightbox-load {
from {
	opacity: 0;
	transform: scale(0.95);
}

to {
	opacity: 1;
	transform: scale(1);
}
}

.lightbox-image,
.lightbox-video,
.lightbox-pdf,
.lightbox-file {
max-width: 90vw;
max-height: calc(100vh - 140px);
object-fit: contain;
border-radius: 3px;
margin: auto;
}

.lightbox-pdf {
width: 90vw;
height: calc(100vh - 140px);
}

.lightbox-pdf embed {
width: 100%;
height: 100%;
border: none;
border-radius: 3px;
}

.lightbox-video iframe {
width: 90vw;
}

.lightbox-video video {
width: 100%;
height: 100%;
}

.lightbox-image {
width: auto;
height: auto;
}

/* When zoomed, make image full width */
.bgl-lightbox-swiper.zoomed .lightbox-image {
max-width: 100vw;
width: 100vw;
max-height: 100vh;
height: 100vh;
object-fit: contain;
}

.bgl-lightbox-swiper.zoomed .vue-zoomer {
width: 100vw;
height: 100vh;
}

.bgl-lightbox-swiper.zoomed .bgl-lightbox-item * {
max-height: calc(100vh - 90px);
height: calc(100vh - 90px);
}

.bgl-lightbox-swiper.zoomed {
pointer-events: none;
}

.bgl-lightbox-swiper.zoomed .vue-zoomer {
pointer-events: auto;
}

.lightbox-thumbnails {
display: flex;
justify-content: center;
align-items: center;
gap: 0.75rem;
padding: 1rem;
overflow-x: auto;
overflow-y: hidden;
background: linear-gradient(to top, rgba(0, 0, 0, 0.4) 0%, transparent 100%);
width: 100%;
}

.lightbox-thumbnails::-webkit-scrollbar {
height: 4px;
}

.lightbox-thumbnails::-webkit-scrollbar-track {
background: transparent;
}

.lightbox-thumbnails::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.3);
border-radius: 2px;
}

.thumbnail {
height: 60px;
width: 60px;
min-width: 60px;
object-fit: cover;
border-radius: 6px;
cursor: pointer;
opacity: 0.6;
transition: all 0.2s ease;
flex-shrink: 0;
}

.thumbnail-icon {
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.1);
}

.thumbnail:hover {
opacity: 1;
transform: scale(1.05);
}

.thumbnail:active {
transform: scale(0.95);
}

.thumbnail.active {
opacity: 1;
outline: 3px solid white;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

@media screen and (max-width: 910px) {
.bgl-lightbox-overlay {
	grid-template-rows: 50px 1fr 70px;
}

.lightbox-thumbnails {
	justify-content: flex-start;
	gap: 0.5rem;
	padding: 0.75rem 1rem;
}

.thumbnail {
	height: 50px;
	width: 50px;
	min-width: 50px;
}
}

.file-info {
max-width: 420px
}

@media screen and (max-width: 910px) {
.file-info {
	max-width: 220px;
	text-align: center !important;
}

.file-info * {
	text-align: center !important;
	margin-inline: 0 !important;
	max-width: 100% !important;
}
}

</style>
