"use client";

import React, { useMemo, useState, useEffect, useRef } from "react";
import { useBanners } from "@/hooks/banner/useBanners";

export default function AdvertisementBanner() {
    const { data: response, isLoading } = useBanners();

    // Filter and sort active advertisement banners
    const adBanners = useMemo(() => {
        if (!response?.data) return [];
        const activeBanners = response.data.filter((b) => b.status && b.image);

        const hasBannerTypes = activeBanners.some((b) => Boolean(b.banner_type));

        if (hasBannerTypes) {
            return activeBanners
                .filter((b) => b.banner_type === "advertisement_banner")
                .sort((a, b) => a.sort_order - b.sort_order);
        }

        return (activeBanners.length > 1 ? activeBanners.slice(1) : activeBanners)
            .sort((a, b) => a.sort_order - b.sort_order);
    }, [response]);

    const count = adBanners.length;

    // Window size detection
    const [isMobile, setIsMobile] = useState<boolean>(false);
    useEffect(() => {
        const checkMobile = () => {
            setIsMobile(window.innerWidth < 640);
        };
        checkMobile();
        window.addEventListener("resize", checkMobile);
        return () => window.removeEventListener("resize", checkMobile);
    }, []);

    // Create cloned items for infinite loop
    const displayBanners = useMemo(() => {
        if (count < 2) return adBanners;
        const lastTwo = adBanners.slice(-2);
        const firstTwo = adBanners.slice(0, 2);
        return [...lastTwo, ...adBanners, ...firstTwo];
    }, [adBanners, count]);

    const [currentIndex, setCurrentIndex] = useState<number>(2);
    const [isTransitioning, setIsTransitioning] = useState<boolean>(false);
    const [isHovered, setIsHovered] = useState<boolean>(false);

    // Refs for 120fps direct DOM drag performance
    const trackRef = useRef<HTMLDivElement>(null);
    const isDraggingRef = useRef<boolean>(false);
    const startXRef = useRef<number>(0);
    const dragOffsetRef = useRef<number>(0);
    const isClickPreventedRef = useRef<boolean>(false);
    const rafIdRef = useRef<number | null>(null);

    // Calculate current transform string
    const getTransformString = (index: number, offsetPx: number) => {
        const slidePercent = isMobile ? 84 : 50;
        const baseOffsetPercent = isMobile ? 8 : 0;
        return `translate3d(calc(${baseOffsetPercent}% - ${index * slidePercent}% + ${offsetPx}px), 0, 0)`;
    };

    // Seamless loop reset without flicker
    useEffect(() => {
        if (count < 2) return;

        if (currentIndex >= count + 2) {
            const timer = setTimeout(() => {
                if (trackRef.current) {
                    trackRef.current.style.transition = "none";
                    const newIdx = currentIndex - count;
                    trackRef.current.style.transform = getTransformString(newIdx, 0);
                    void trackRef.current.offsetHeight; // Force DOM reflow
                    setIsTransitioning(false);
                    setCurrentIndex(newIdx);
                }
            }, 350);
            return () => clearTimeout(timer);
        } else if (currentIndex < 2) {
            const timer = setTimeout(() => {
                if (trackRef.current) {
                    trackRef.current.style.transition = "none";
                    const newIdx = currentIndex + count;
                    trackRef.current.style.transform = getTransformString(newIdx, 0);
                    void trackRef.current.offsetHeight; // Force DOM reflow
                    setIsTransitioning(false);
                    setCurrentIndex(newIdx);
                }
            }, 350);
            return () => clearTimeout(timer);
        }
    }, [currentIndex, count, isMobile]);

    // Update track position when currentIndex or transition state changes
    useEffect(() => {
        if (!trackRef.current) return;
        if (isTransitioning) {
            trackRef.current.style.transition = "transform 0.35s cubic-bezier(0.25, 1, 0.5, 1)";
        } else {
            trackRef.current.style.transition = "none";
        }
        trackRef.current.style.transform = getTransformString(currentIndex, 0);
    }, [currentIndex, isTransitioning, isMobile]);

    // Autoplay Timer
    useEffect(() => {
        if (count <= 1 || isHovered) return;
        const timer = setInterval(() => {
            if (isDraggingRef.current) return;
            setIsTransitioning(true);
            setCurrentIndex((prev) => prev + 1);
        }, 4000);
        return () => clearInterval(timer);
    }, [count, isHovered]);

    // Drag / Swipe handlers with RequestAnimationFrame (60-120 FPS)
    const handleStart = (clientX: number) => {
        if (count < 2 || !trackRef.current) return;
        isDraggingRef.current = true;
        startXRef.current = clientX;
        dragOffsetRef.current = 0;
        isClickPreventedRef.current = false;
        trackRef.current.style.transition = "none";
    };

    const handleMove = (clientX: number) => {
        if (!isDraggingRef.current || !trackRef.current) return;
        const diff = clientX - startXRef.current;
        dragOffsetRef.current = diff;
        if (Math.abs(diff) > 8) {
            isClickPreventedRef.current = true;
        }

        if (rafIdRef.current) cancelAnimationFrame(rafIdRef.current);
        rafIdRef.current = requestAnimationFrame(() => {
            if (trackRef.current && isDraggingRef.current) {
                trackRef.current.style.transform = getTransformString(currentIndex, dragOffsetRef.current);
            }
        });
    };

    const handleEnd = () => {
        if (!isDraggingRef.current) return;
        isDraggingRef.current = false;
        if (rafIdRef.current) cancelAnimationFrame(rafIdRef.current);

        const diff = dragOffsetRef.current;
        const threshold = 40;

        setIsTransitioning(true);
        if (diff < -threshold) {
            setCurrentIndex((prev) => prev + 1);
        } else if (diff > threshold) {
            setCurrentIndex((prev) => prev - 1);
        } else {
            setCurrentIndex((prev) => prev);
        }
        dragOffsetRef.current = 0;
    };

    if (isLoading) {
        return (
            <div className="mt-7 px-4">
                <div className="grid grid-cols-2 gap-4">
                    <div className="w-full aspect-[900/313] animate-pulse rounded-2xl bg-zinc-200" />
                    <div className="w-full aspect-[900/313] animate-pulse rounded-2xl bg-zinc-200" />
                </div>
            </div>
        );
    }

    if (!adBanners || count === 0) {
        return null;
    }

    // 1 Banner case
    if (count === 1) {
        return (
            <section className="relative mt-7 px-4 select-none">
                <div className="flex justify-between items-center mb-3">
                    <h3 className="text-sm font-bold text-gray-800 uppercase tracking-wide">
                        Special Offers & Deals
                    </h3>
                </div>
                <div
                    className="block relative w-full aspect-[900/313] overflow-hidden rounded-xl shadow-sm group"
                >
                    <img
                        src={adBanners[0].image!}
                        alt={adBanners[0].title || "Advertisement"}
                        className="h-full w-full object-cover transition duration-500 group-hover:scale-105 select-none"
                    />
                </div>
            </section>
        );
    }

    const slidePercent = isMobile ? 84 : 50;

    return (
        <section className="relative mt-7 select-none overflow-hidden sm:px-4 md:px-6">
            <div className="flex justify-between items-center mb-3 px-4 sm:px-0">
                <h3 className="text-sm font-bold text-gray-800 uppercase tracking-wide">
                    Special Offers & Deals
                </h3>
            </div>

            <div
                className="relative w-full overflow-hidden touch-pan-y"
                onMouseEnter={() => setIsHovered(true)}
                onMouseLeave={() => {
                    setIsHovered(false);
                    if (isDraggingRef.current) handleEnd();
                }}
                onTouchStart={(e) => handleStart(e.touches[0].clientX)}
                onTouchMove={(e) => handleMove(e.touches[0].clientX)}
                onTouchEnd={handleEnd}
                onMouseDown={(e) => handleStart(e.clientX)}
                onMouseMove={(e) => handleMove(e.clientX)}
                onMouseUp={handleEnd}
            >
                <div
                    ref={trackRef}
                    className="flex w-full will-change-transform transform-gpu"
                >
                    {displayBanners.map((ad, idx) => {
                        const isCenterMobile = isMobile && idx === currentIndex;

                        return (
                            <div
                                key={`${ad.id}-${idx}`}
                                className="shrink-0 px-1 transition-all duration-300 transform-gpu"
                                style={{
                                    width: `${slidePercent}%`,
                                    opacity: isMobile ? (isCenterMobile ? 1 : 0.75) : 1,
                                    transform: isMobile ? (isCenterMobile ? "scale(1)" : "scale(0.93)") : "scale(1)",
                                }}
                            >
                                <div
                                    onClick={(e) => {
                                        if (isClickPreventedRef.current) e.preventDefault();
                                    }}
                                    draggable={false}
                                    className="group relative block w-full aspect-[900/313] overflow-hidden rounded-xl outline-none"
                                >
                                    <img
                                        src={ad.image!}
                                        alt={ad.title || "Advertisement"}
                                        draggable={false}
                                        className="h-full w-full object-cover transition duration-500 group-hover:scale-105 select-none pointer-events-none"
                                        style={{ backfaceVisibility: "hidden" }}
                                    />
                                </div>
                            </div>
                        );
                    })}
                </div>
            </div>
        </section>
    );
}
