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

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

const { $t } = useI18n()

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
	document.addEventListener('keydown', handleKeydown)
}

function close() {
	isOpen.value = false
	document.removeEventListener('keydown', handleKeydown)
}

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
})

function handleKeydown(event: KeyboardEvent) {
	if (event.key === 'Escape') {
		close()
	}
}

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
						>
							<Image :draggable="false" :src="item?.src" alt="Preview" class="lightbox-image" />
						</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" width="100%" height="1080"
								: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-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>
