import * as React from "react"
import {
    animate,
    useMotionValue,
} from "framer-motion"

import Arrow from "./arrow"
import Slider from "./slider"
import Dots from "./dots"
import styled from "styled-components"
import useScreenDimensions from "../../../../hooks/useScreenDimensions"

const transition = {
    type: "spring",
    bounce: 0,
}


const Container = styled.div`
    position: relative;
    width: 100%;
    height: 100%;
    overflow-x: hidden;
    display: flex;
`;

export const Carousel = ({
    children,
    renderArrowLeft,
    renderArrowRight,
    renderDots,
    autoPlay = true,
    interval = 5000,
    loop = true,
}) => {
    const x = useMotionValue(0)
    const containerRef = React.useRef(null)
    const [index, setIndex] = React.useState(0)
    const screen = useScreenDimensions();

    const calculateNewX = () =>
        -index * (containerRef.current?.clientWidth || 0)

    const handleEndDrag = (e, dragProps) => {
        const clientWidth = containerRef.current?.clientWidth || 0

        const { offset } = dragProps

        if (offset.x > clientWidth / 8) {
            handlePrev()
        } else if (offset.x < -clientWidth / 8) {
            handleNext()
        } else {
            animate(x, calculateNewX(), transition)
        }
    }

    const childrens = React.Children.toArray(children)

    const resetSlider = () => {
        setIndex(0)
    }

    const handleNext = () => {
        const idx = loop ? 0 : index;
        setIndex(index + 1 === childrens.length ? idx : index + 1)
    }

    const handlePrev = () => {
        const idx = loop ? childrens.length - 1: 0;
        setIndex(index - 1 < 0 ? idx : index - 1)
    }

    React.useEffect (() => {

           resetSlider(); 
        
    },[screen.width])

    React.useEffect(() => {
        const controls = animate(x, calculateNewX(), transition)
        return controls.stop
    }, [index])

    React.useEffect(() => {
        if (!autoPlay) {
            return
        }
        const timer = setInterval(() => handleNext(), interval)
        return () => clearInterval(timer)
    }, [handleNext, interval])

    return (
        <Container ref={containerRef}>
            {childrens.map((child, i) => (
                <Slider onDragEnd={handleEndDrag} x={x} i={i} key={i}>
                    {child}
                </Slider>
            ))}
            {/* left arrow */}
            {renderArrowLeft ? (
                renderArrowLeft({ handlePrev, activeIndex: index })
            ) : (
                <Arrow left onClick={handlePrev}>
                    &larr;
                </Arrow>
            )}

            {/* right arrow */}
            {renderArrowRight ? (
                renderArrowRight({ handleNext, activeIndex: index })
            ) : (
                <Arrow onClick={handleNext}>&rarr;</Arrow>
            )}

            {/* dots */}
            {renderDots ? (
                renderDots({ setActiveIndex: setIndex, activeIndex: index })
            ) : (
                <Dots
                    length={childrens.length}
                    setActiveIndex={setIndex}
                    activeIndex={index}
                />
            )}
        </Container>
    )
}
