"use client";

import {
  createContext,
  useContext,
  useState,
  useEffect,
  type ReactNode,
} from "react";
import { motion, AnimatePresence } from "framer-motion";
import Image from "next/image";

type LoaderContextType = {
  isLoading: boolean;
  isReady: boolean;
  setContentReady: () => void;
};

const LoaderContext = createContext<LoaderContextType>({
  isLoading: true,
  isReady: false,
  setContentReady: () => {},
});

export const useLoader = () => useContext(LoaderContext);

const EASE_OUT_EXPO = [0.16, 1, 0.3, 1] as const;

type PageLoaderProps = {
  children: ReactNode;
  minLoadTime?: number;
};

export const PageLoader = ({
  children,
  minLoadTime = 800,
}: PageLoaderProps) => {
  const [isLoading, setIsLoading] = useState(true);
  const [isReady, setIsReady] = useState(false);
  const [contentReady, setContentReady] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => {
      setContentReady(true);
    }, minLoadTime);

    return () => clearTimeout(timer);
  }, [minLoadTime]);

  useEffect(() => {
    if (contentReady) {
      setIsLoading(false);
      // Small delay before triggering content animations
      const readyTimer = setTimeout(() => {
        setIsReady(true);
      }, 100);
      return () => clearTimeout(readyTimer);
    }
  }, [contentReady]);

  return (
    <LoaderContext.Provider
      value={{
        isLoading,
        isReady,
        setContentReady: () => setContentReady(true),
      }}
    >
      <AnimatePresence mode="wait">
        {isLoading && (
          <motion.div
            key="loader"
            className="fixed inset-0 z-100 bg-primary flex items-center justify-center"
            initial={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.6, ease: EASE_OUT_EXPO }}
          >
            {/* Animated logo/loader */}
            <div className="flex flex-col items-center gap-6">
              <motion.div
                className="relative"
                initial={{ scale: 0.8, opacity: 0 }}
                animate={{ scale: 1, opacity: 1 }}
                transition={{ duration: 0.5, ease: EASE_OUT_EXPO }}
              >
                {/* Pulsing ring */}
                <motion.div
                  className="absolute inset-0 rounded-full border-2 border-secondary"
                  animate={{
                    scale: [1, 1.5, 1],
                    opacity: [0.5, 0, 0.5],
                  }}
                  transition={{
                    duration: 1.5,
                    repeat: Number.POSITIVE_INFINITY,
                    ease: "easeInOut",
                  }}
                />
                {/* Logo circle */}
                <motion.div
                  className="size-16 rounded-full bg-secondary flex items-center justify-center"
                  animate={{
                    scale: [1, 1.05, 1],
                  }}
                  transition={{
                    duration: 1.2,
                    repeat: Number.POSITIVE_INFINITY,
                    ease: "easeInOut",
                  }}
                >
                  <Image
                    src={"/images/logo-white.png"}
                    alt="logo"
                    fill
                    quality={100}
                  />
                </motion.div>
              </motion.div>

              {/* Loading bar */}
              <div className="w-32 h-1 bg-white/20 rounded-full overflow-hidden">
                <motion.div
                  className="h-full bg-secondary rounded-full"
                  initial={{ width: "0%" }}
                  animate={{ width: "100%" }}
                  transition={{
                    duration: minLoadTime / 1000,
                    ease: "easeInOut",
                  }}
                />
              </div>
            </div>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Page content - renders but hidden until ready */}
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: isLoading ? 0 : 1 }}
        transition={{ duration: 0.4, ease: EASE_OUT_EXPO }}
      >
        {children}
      </motion.div>
    </LoaderContext.Provider>
  );
};
