import styled, { css, keyframes } from 'styled-components';
import { SliderNextArrow, SliderPrevArrow } from '../../components/Icons';
import { useState, useRef } from 'react';
import { CHAPTER_1_MUST_DO, CHAPTER_2_MUST_DO, CHAPTER_3_MUST_DO, CHAPTER_4_MUST_DO } from '../ResultPage/getCompleteTasks';
import { RatingStar } from '../../components/Icons';
import { getTaskCategoryColor } from '../ResultPage/TaskCard';
import { ImageWrapper } from '../../components/MediaWrapper';
import { breakpoints, respondTo, useMediaSelectTo } from '../../utils/responsive';
import { useEffect, useMemo } from 'react';

const MOCK_CARDS = [...CHAPTER_1_MUST_DO, ...CHAPTER_2_MUST_DO, ...CHAPTER_3_MUST_DO, ...CHAPTER_4_MUST_DO].map((card, index) => ({
    ...card,
    number: index + 1,
}));

function CardStack() {
    const [cards, setCards] = useState(MOCK_CARDS);
    const [isLoaded, setIsLoaded] = useState(false);
    const cardStackRef = useRef(null);
    const isAnimating = useRef(false);
    const touchStartX = useRef(null);
    const touchEndX = useRef(null);
    const isMobile = useMediaSelectTo(breakpoints.sm);

    const dots = useMemo(() => {
        if (typeof isMobile !== 'boolean') return null;

        if (!isMobile) return (
            <div className="dots-group">
                {Array.from({ length: cards.length }, (_, index) => (
                    <button
                        key={index}
                        className={
                            MOCK_CARDS[index].number === cards[0].number
                                ? "active"
                                : ""
                        }
                        onClick={() => pullCard(MOCK_CARDS[index].number)}
                    />
                ))}
            </div>
        );

        let currentCardNumber = cards[0].number;

        return (
            <div className="dots-group">
                {currentCardNumber} / {cards.length}
            </div>
        );
    }, [isMobile, cards])

    // Add touch event handlers
    const handleTouchStart = (e) => {
        touchStartX.current = e.touches[0].clientX;
    };

    const handleTouchMove = (e) => {
        touchEndX.current = e.touches[0].clientX;
    };

    const handleTouchEnd = () => {
        if (!touchStartX.current || !touchEndX.current) return;

        const diffX = touchEndX.current - touchStartX.current;
        const minSwipeDistance = 50; // minimum distance for swipe

        if (Math.abs(diffX) > minSwipeDistance) {
            if (diffX > 0) {
                // Swipe right - go to previous card
                toPrevCard();
            } else {
                // Swipe left - go to next card
                toNextCard();
            }
        }

        // Reset touch coordinates
        touchStartX.current = null;
        touchEndX.current = null;
    };

    const toPrevCard = () => {
        if (isAnimating.current) return;
        if (cards[0].number === 1) return;
        isAnimating.current = true;


        const currentFrontCardNumber = cards[0].number;
        const prevCard = MOCK_CARDS.find((card) => card.number === currentFrontCardNumber - 1);
        const prevCardIndex = cards.findIndex((card) => card.number === prevCard.number);
        const prevCardElement = cardStackRef.current.querySelector(`.number-${prevCard.number}`);

        // 從最後面抽出來，疊到前面
        prevCardElement.classList.add('animate-prev-out');

        setTimeout(() => {
            prevCardElement.classList.remove('animate-prev-out');
            prevCardElement.classList.add('animate-prev-in');

            setTimeout(() => {
                prevCardElement.classList.remove("animate-prev-in");
                setCards(prevCards => [prevCard, ...prevCards.slice(0, prevCardIndex), ...prevCards.slice(prevCardIndex + 1)]);

                isAnimating.current = false;
            }, 300);
        }, 300);
    }

    const toNextCard = () => {
        if (isAnimating.current) return;
        if (cards[0].number === MOCK_CARDS[MOCK_CARDS.length - 1].number) return;
        isAnimating.current = true;

        const currentFrontCardNumber = cards[0].number;
        const nextCard = MOCK_CARDS.find((card) => card.number === currentFrontCardNumber + 1);
        const nextCardIndex = cards.findIndex((card) => card.number === nextCard.number);
        const nextCardElement = cardStackRef.current.querySelector(`.number-${nextCard.number}`);

        if (!nextCardElement) {

            return;
        }

        nextCardElement.classList.add('animate-next-out');

        setTimeout(() => {
            nextCardElement.classList.remove('animate-next-out');
            nextCardElement.classList.add('animate-next-in');

            setTimeout(() => {
                nextCardElement.classList.remove('animate-next-in');
                
                // put nextCard to the first
                setCards(prevCards => [nextCard, ...prevCards.slice(0, nextCardIndex), ...prevCards.slice(nextCardIndex + 1)]);

                isAnimating.current = false;
            }, 300);
        }, 300);
    }

    const pullCard = (cardNumber) => {
        if (isAnimating.current) return;
        const currentFrontCard = cards[0];
        if (currentFrontCard.number === cardNumber) return;
        isAnimating.current = true;


        const card = cardStackRef.current.querySelector(`.number-${cardNumber}`);

        const cardObject = MOCK_CARDS.find((card) => card.number === cardNumber);
        const cardIndex = cards.findIndex((card) => card.number === cardNumber);
    
        card.classList.add("animate-prev-out");

        setTimeout(() => {
            card.classList.remove("animate-prev-out");
            card.classList.add("animate-prev-in");

            setTimeout(() => {
                card.classList.remove("animate-prev-in");
                
                // set cardObject to the first
                setCards(prevCards => [cardObject, ...prevCards.slice(0, cardIndex), ...prevCards.slice(cardIndex + 1)]);

                isAnimating.current = false;
            }, 300);
        }, 300);
    }

    useEffect(() => {
        if (isLoaded) return;
        // preload all images
        const allImages = cards.map((card) => card.image);
        allImages.forEach((image) => {
            const img = new Image();
            img.src = image;
        });

        setIsLoaded(true);

        return () => {
            // clean up
            allImages.forEach((image) => {
                URL.revokeObjectURL(image);
            });
        }
    }, []);


    return (
        <StyledContainer>
            <ControlBtn
                $position="left"
                onClick={toPrevCard}
                disabled={cards[0].number === 1}
            >
                <SliderPrevArrow />
            </ControlBtn>
            <Stack 
                ref={cardStackRef}
                onTouchStart={handleTouchStart}
                onTouchMove={handleTouchMove}
                onTouchEnd={handleTouchEnd}
            >
                {cards.map((card, index) => (
                    <Card
                        key={card.number}
                        className={`card card-${index} number-${card.number}`}
                        style={{
                            zIndex:
                                index === 0
                                    ? 100
                                    : index === cards.length - 1
                                    ? -100
                                    : cards.length - index,
                            transform: `rotate(${
                                index < 3 && index > 0 ? index * -4 : 0
                            }deg)`,
                        }}
                    >
                        <div
                            className="category"
                            style={{
                                background: getTaskCategoryColor(card.category),
                            }}
                        >
                            {card.category}
                        </div>
                        <div className="stars">
                            <span>重要程度</span>
                            <div>
                                {Array.from({ length: card.stars }).map((_, index) => (
                                    <RatingStar key={index} />
                                ))}
                            </div>
                        </div>
                        <div className="content">
                            <ImageWrapper src={card.image} alt={card.title} />
                            <div>
                                <h3>{card.title}</h3>
                                <p>{card.importance}</p>
                            </div>
                        </div>
                    </Card>
                ))}
            </Stack>
            <ControlBtn
                $position="right"
                onClick={toNextCard}
                disabled={
                    cards[0].number === MOCK_CARDS[MOCK_CARDS.length - 1].number
                }
            >
                <SliderNextArrow />
            </ControlBtn>
            <Dots>
                <ControlBtn
                    className="mobile-control-btn"
                    $position="left"
                    onClick={toPrevCard}
                    disabled={cards[0].number === 1}
                >
                    <SliderPrevArrow />
                </ControlBtn>
                {dots}
                <ControlBtn
                    className="mobile-control-btn"
                    $position="right"
                    onClick={toNextCard}
                    disabled={
                        cards[0].number ===
                        MOCK_CARDS[MOCK_CARDS.length - 1].number
                    }
                >
                    <SliderNextArrow />
                </ControlBtn>
            </Dots>
        </StyledContainer>
    );
}


const StyledContainer = styled.div`
    padding: 80px 90px;
    position: relative;

    ${respondTo.sm} {
        width: 100vw;

        padding: 0;
        padding-top: 40px;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }
`;

const Stack = styled.div`
    width: 480px;
    height: 300px;

    ${respondTo.sm} {
        width: 311px;
        height: 378px;
        margin-bottom: 40px;
    }

    position: relative;

    .card:first-of-type {
        z-index: 98 !important;
    }
`;

const fadeIn = keyframes`
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
`;

const fadeOut = keyframes`
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
`;

const Card = styled.div`
    background: white;
    border: 2px solid var(--neutrals-700);
    border-radius: 12px;

    width: 480px;
    height: 300px;
    border-radius: 16px;
    border: 4px solid var(--neutrals-700);
    overflow: hidden;

    position: absolute;
    padding: 82px 24px 40px;

    ${respondTo.sm} {
        width: 311px;
        height: 378px;
        border-radius: 20px;
    }

    .category {
        position: absolute;
        top: 0;
        left: 0;

        width: 220px;
        height: 64px;

        font: var(--headline-6);
        // 文字置中
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 0px 0px 16px 0px;

        ${respondTo.sm} {
            width: 132px;
            height: 54px;
            font-size: 16px;
            font-weight: 900;

            border-radius: 16px 0px 16px 0px;
        }
    }

    .stars {
        position: absolute;
        top: 0;
        right: 0;

        width: 198px;
        height: 40px;

        background: var(--neutrals-700);
        border-radius: 0px 0px 0px 16px;

        color: white;
        font: var(--small-text-2);
        font-weight: 700;

        display: flex;
        justify-content: center;
        align-items: center;

        span {
            margin-right: 4px;
            flex-shrink: 0;
        }

        > div {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 4px;
        }

        ${respondTo.sm} {
            width: 142px;
            height: 54px;
            flex-direction: column;
            align-items: flex-start;
            padding: 0 16px;
            gap: 4px;

            font: var(--mobile-small-text-1);
            font-weight: 700;
        }
    }

    .content {
        display: flex;
        align-items: center;

        ${respondTo.sm} {
            flex-direction: column;
        }

        img {
            --size: 178px;
            width: var(--size);
            height: var(--size);
            object-fit: contain;
        }

        h3 {
            font: var(--paragraph-1);
            font-weight: 700;
            margin-bottom: 6px;

            ${respondTo.sm} {
                font: var(--mobile-paragraph-1);
                text-align: center;
                font-weight: 700;
            }
        }

        p {
            font: var(--small-text-1);
            white-space: pre-wrap;
            font-size: 14px;

            ${respondTo.sm} {
                font: var(--mobile-small-text-1);
                text-align: center;
                font-size: 14px;
            }
        }
    }

    &.animate-prev-out {
        transform: translateY(-100px) !important;
        transition: transform 0.3s ease-out;
        animation: ${fadeOut} 0.3s ease-out 1;
    }

    &.animate-prev-in {
        z-index: 100 !important;
        transform: translateY(0) !important;
        transition: transform 0.3s ease-out;
        animation: ${fadeIn} 0.3s ease-out 1;
    }

    &.animate-next-out {
        transform: translateY(100px) !important;
        transition: transform 0.3s ease-out;
        animation: ${fadeOut} 0.3s ease-out 1;
    }

    &.animate-next-in {
        z-index: 100 !important;
        transform: translateY(0) !important;
        transition: transform 0.3s ease-out;
        animation: ${fadeIn} 0.3s ease-out 1;
    }
`;


const ControlBtn = styled.button`
    position: absolute;
    top: 50%;
    transform: translateY(-50%);

    color: var(--neutrals-700);

    ${respondTo.sm} {
        display: none;

        width: 32px;
        height: 32px;

        svg {
            width: 24px;
            height: 24px;
        }
    }

    ${({ $position }) => $position === 'left' && css`
        left: 0;

        ${respondTo.sm} {
            transform: translate(-100%, -50%);
        }
    `}

    ${({ $position }) => $position === 'right' && css`
        right: 0;

        ${respondTo.sm} {
            transform: translate(100%, -50%);
        }
    `}

    &:disabled {
        color: white;
        pointer-events: none;
        opacity: 0.5;
    }
`;

const Dots = styled.div`
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);

    display: flex;
    gap: 12px;

    .mobile-control-btn {
        display: none;
    }

    ${respondTo.sm} {
        flex-wrap: wrap;
        justify-content: center;

        position: relative;
        bottom: unset;
        left: unset;
        transform: unset;

        width: 60%;
        font: var(--mobile-paragraph-1);
        font-weight: 700;

        .mobile-control-btn {
            display: block;
        }
    }

    .dots-group {
        display: flex;
        gap: 12px;
        justify-content: center;

        ${respondTo.sm} {
            flex-wrap: wrap;
            justify-content: center;

            padding: 0 16px;

        }

        button {
            --size: 14px;
            width: var(--size);
            height: var(--size);
            border-radius: 50%;

            border: 2px solid var(--neutrals-700);

            ${respondTo.sm} {
                --size: 10px;
            }

            &.active {
                background: var(--neutrals-700);
            }
        }
    }
`;

export default CardStack;
