'use client'
import './EmblaCarousel.css'
import React, { HTMLAttributes, useCallback, useEffect, useRef, useState } from 'react'
import useEmblaCarousel from 'embla-carousel-react'
import Autoplay from 'embla-carousel-autoplay'
import AutoScroll from 'embla-carousel-auto-scroll'
import { CarouselSlide } from '@/types/entities'
import { IconChevronLeft, IconChevronRight } from '@tabler/icons-react'
import { montserratFont } from '@/app/layout'

export interface EmblaCarouselProps {
    slides: CarouselSlide[]
    slides_per_view?: number
    show_dots?: boolean
    dots_position?: 'bottom_inside' | 'bottom'
    buttons_position?: 'middle_inside' | 'bottom'
    show_title?: boolean
    title_align?: 'center' | 'left' | 'right'
    title_position?: 'middle' | 'top' | 'bottom'
    autoplay?: boolean
    autoscroll?: boolean
    autoscroll_speed?: number
    autoscroll_direction?: 'forward' | 'backward'
    shape?: 'fit' | 'square'
    rounded?: boolean
}

const EmblaCarousel = ({
    slides,
    slides_per_view,
    show_dots = false,
    dots_position = 'bottom_inside',
    buttons_position = 'middle_inside',
    show_title = false,
    title_align = 'center',
    title_position = 'middle',
    autoplay = false,
    autoscroll = false,
    autoscroll_speed = 1.5,
    autoscroll_direction = 'forward',
    shape = 'fit',
    rounded = false
}: EmblaCarouselProps) => {
    const autoScrollPlugin = useRef(
        AutoScroll({
            active: autoscroll,
            speed: autoscroll_speed,
            direction: autoscroll_direction,
            stopOnInteraction: false, // Stop when user interacts
            stopOnMouseEnter: false, // Stop on hover
            //startDelay: 500, // Delay before starting
            playOnInit: autoscroll, // Start playing on init
        })
    )

    const autoplayPlugin = useRef(
        Autoplay({
            active: autoplay,
            stopOnInteraction: false, // Stop when user interacts
            stopOnMouseEnter: false, // Stop on hover
            jump: false, // false = smooth scroll, true = instant jump
            playOnInit: autoplay, // Start playing on init
        })
    )

    const [emblaRef, emblaApi] = useEmblaCarousel({
        align: 'start',
        loop: true
    }, [autoplayPlugin.current, autoScrollPlugin.current])

    const [selectedIndex, setSelectedIndex] = useState(0)
    const [scrollSnaps, setScrollSnaps] = useState<number[]>([])

    const scrollTo = useCallback((index: number) => {
        emblaApi?.scrollTo(index)

        autoScrollPlugin.current.stop()
        setTimeout(() => {
            if (autoscroll) autoScrollPlugin.current.play()
        }, 1000)
    }, [emblaApi])

    const scrollPrev = useCallback(() => {
        emblaApi?.scrollPrev()

        autoScrollPlugin.current.stop()
        setTimeout(() => {
            if (autoscroll) autoScrollPlugin.current.play()
        }, 1000)
    }, [emblaApi])

    const scrollNext = useCallback(() => {
        emblaApi?.scrollNext()

        autoScrollPlugin.current.stop()
        setTimeout(() => {
            if (autoscroll) autoScrollPlugin.current.play()
        }, 1000)
    }, [emblaApi])

    const onSelect = useCallback(() => {
        if (!emblaApi) return
        setSelectedIndex(emblaApi.selectedScrollSnap())
    }, [emblaApi])

    useEffect(() => {
        if (!emblaApi) return

        onSelect()
        setScrollSnaps(emblaApi.scrollSnapList())
        emblaApi.on('select', onSelect)
        emblaApi.on('reInit', onSelect)

        if (autoplay) {
            autoplayPlugin.current.play()
        } else {
            autoplayPlugin.current.stop()
        }

        if (autoscroll) {
            autoScrollPlugin.current.play()
        } else {
            autoplayPlugin.current.stop()
        }

        return () => {
            emblaApi.off('select', onSelect)
            emblaApi.off('reInit', onSelect)
            emblaApi.off('autoScroll:play', () => { })
            emblaApi.off('autoScroll:stop', () => { })
        }
    }, [emblaApi, autoplay, autoscroll, onSelect])

    const slideTitleAlign = (title_align?: EmblaCarouselProps['title_align']) => {
        switch (title_align) {
            case 'center':
                return 'justify-center'
            case 'left':
                return 'justify-start'
            case 'right':
                return 'justify-end'
            default:
                return ''
        }
    }

    const slideTitlePosition = (title_position?: EmblaCarouselProps['title_position']) => {
        switch (title_position) {
            case 'bottom':
                return 'items-end'
            case 'middle':
                return 'items-center'
            case 'top':
                return 'items-start'
            default:
                return ''
        }
    }

    const slideClass = (slides_per_view?: number) => {
        switch (slides_per_view) {
            case 1:
                return ''
            case 2:
                return 'sm:basis-1/2!'
            case 3:
                return 'sm:basis-1/3!'
            case 4:
                return 'basis-1/2! sm:basis-1/4!'
            default:
                return ''
        }
    }

    return (
        <div className={`embla ${montserratFont.className} ${rounded ? 'rounded-lg overflow-hidden' : ''}`}>
            <div className="embla__viewport" ref={emblaRef}>
                <div className="embla__container">
                    {slides.map((slide, index) => (
                        <a href={slide.href} target='_blank' key={`slide-${index}`} className={`embla__slide ${slideClass(slides_per_view)}`}>
                            <img className={`h-full min-h-48 object-cover  ${shape === 'fit' ? '' : 'aspect-square'}`} src={slide.src} />
                            {show_title && slide.title &&
                                <div className={`${title_position === 'top' ? 'bg-linear-to-b' : 'bg-linear-to-t'} from-black/75 via-40% via-black/50 to-transparent font-semibold text-white text-lg sm:text-3xl absolute top-0 w-full h-full flex justify-center pointer-events-none z-10`}>
                                    <span className={`flex px-8 py-16 max-w-5xl! w-full h-full justify-self-center ${slideTitleAlign(title_align)} ${slideTitlePosition(title_position)}`}>
                                        <span>{slide.title}</span>
                                    </span>
                                </div>}
                        </a>
                    ))}
                </div>
            </div>

            <div className={`embla__buttons ${buttons_position === 'middle_inside' ? 'absolute z-1 inset-0 flex justify-between items-center p-4 pointer-events-none' : ''}`}>
                <button
                    className="embla__button h-full text-gray-300/75 hover:text-gray-100 embla__button--prev pointer-events-auto"
                    onClick={scrollPrev}
                    aria-label="Previous slide"
                >
                    <IconChevronLeft size={32} />
                </button>
                <button
                    className="embla__button h-full text-gray-300/75 hover:text-gray-100 embla__button--next pointer-events-auto"
                    onClick={scrollNext}
                    aria-label="Next slide"
                >
                    <IconChevronRight size={32} />
                </button>
            </div>

            {show_dots && <div className={`embla__dots ${dots_position === 'bottom_inside' ? 'absolute bottom-4 w-full justify-center z-1' : dots_position === 'bottom' ? 'relative my-4 justify-center' : ''}`}>
                <div className='flex gap-2 bg-gray-300/75 bg-blend-difference p-1 rounded-2xl'>
                    {scrollSnaps.map((_, index) => (
                        <button
                            key={index}
                            className={`embla__dot ${index === selectedIndex ? 'embla__dot--selected' : ''}`}
                            onClick={() => scrollTo(index)}
                            aria-label={`Go to slide ${index + 1}`}
                        />
                    ))}
                </div>

            </div>}
        </div>
    )
}

export default EmblaCarousel