<script setup lang="ts">
import { ChevronLeft, ChevronRight } from '@lucide/vue';
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';

const open = defineModel<boolean>('open', { default: false });

const emit = defineEmits<{
    close: [];
    'update:url': [url: string];
}>();

const props = withDefaults(
    defineProps<{
        url: string | null;
        urls?: string[];
        title?: string;
    }>(),
    {
        urls: () => [],
        title: 'Pratinjau Foto',
    }
);

const activeUrl = ref<string | null>(props.url);

watch(
    () => props.url,
    (newUrl) => {
        activeUrl.value = newUrl;
    }
);

watch(open, (val) => {
    if (!val) {
        emit('close');
    } else {
        activeUrl.value = props.url;
    }
});

const allUrls = computed(() => {
    if (props.urls && props.urls.length > 0) {
        return props.urls;
    }

    return props.url ? [props.url] : [];
});

const currentIndex = computed(() => {
    if (!activeUrl.value) {
        return -1;
    }

    return allUrls.value.indexOf(activeUrl.value);
});

const hasMultiple = computed(() => allUrls.value.length > 1);

function nextImage() {
    if (!hasMultiple.value) {
        return;
    }

    const nextIdx = (currentIndex.value + 1) % allUrls.value.length;
    const newUrl = allUrls.value[nextIdx];
    activeUrl.value = newUrl;
    emit('update:url', newUrl);
}

function prevImage() {
    if (!hasMultiple.value) {
        return;
    }

    const prevIdx = (currentIndex.value - 1 + allUrls.value.length) % allUrls.value.length;
    const newUrl = allUrls.value[prevIdx];
    activeUrl.value = newUrl;
    emit('update:url', newUrl);
}

function handleKeyDown(e: KeyboardEvent) {
    if (!open.value || !hasMultiple.value) {
        return;
    }

    if (e.key === 'ArrowRight') {
        nextImage();
    } else if (e.key === 'ArrowLeft') {
        prevImage();
    }
}

onMounted(() => {
    window.addEventListener('keydown', handleKeyDown);
});

onUnmounted(() => {
    window.removeEventListener('keydown', handleKeyDown);
});

let touchStartX = 0;
let touchEndX = 0;

function handleTouchStart(e: TouchEvent) {
    touchStartX = e.changedTouches[0].screenX;
}

function handleTouchEnd(e: TouchEvent) {
    touchEndX = e.changedTouches[0].screenX;
    const diff = touchStartX - touchEndX;

    if (Math.abs(diff) > 50) {
        if (diff > 0) {
            nextImage();
        } else {
            prevImage();
        }
    }
}
</script>

<template>
    <Dialog v-model:open="open">
        <DialogContent class="sm:max-w-2xl p-4 overflow-hidden gap-4">
            <DialogHeader class="pb-2 border-b">
                <DialogTitle class="text-base font-semibold">{{ title ?? 'Pratinjau Gambar' }}</DialogTitle>
            </DialogHeader>

            <div class="relative flex items-center justify-center min-h-[300px] select-none"
                @touchstart="handleTouchStart" @touchend="handleTouchEnd">
                <img v-if="activeUrl" :key="activeUrl" :src="activeUrl" :alt="title ?? 'Pratinjau gambar'"
                    class="max-h-[70vh] w-full rounded-md object-contain transition-all duration-300">
            </div>

            <!-- Bottom Navigation Bar -->
            <div v-if="hasMultiple" class="mt-4 flex items-center justify-between gap-4 border-t pt-3">
                <Button type="button" variant="outline" size="sm" class="flex items-center gap-1 shrink-0"
                    @click.stop="prevImage">
                    <ChevronLeft class="size-4" />
                    Sebelumnya
                </Button>

                <div class="flex flex-wrap justify-center gap-1.5">
                    <button v-for="(_, idx) in allUrls" :key="idx" type="button"
                        class="size-2 rounded-full transition-all duration-200"
                        :class="idx === currentIndex ? 'bg-primary w-4' : 'bg-muted-foreground/30'"
                        @click="activeUrl = allUrls[idx]; emit('update:url', allUrls[idx]);" />
                </div>

                <Button type="button" variant="outline" size="sm" class="flex items-center gap-1 shrink-0"
                    @click.stop="nextImage">
                    Berikutnya
                    <ChevronRight class="size-4" />
                </Button>
            </div>
        </DialogContent>
    </Dialog>
</template>
