"use client";

import { useEffect, useMemo, useState } from "react";

function clamp(value: number) {
  return Math.min(Math.max(value, 0), 1);
}

export default function CleaningOverlay() {
  const [progress, setProgress] = useState(0);

  const dust = useMemo(
    () =>
      Array.from({ length: 38 }, (_, index) => ({
        left: (index * 37) % 100,
        top: (index * 61) % 100,
        size: 1 + (index % 4),
        delay: (index % 9) * -0.43,
        duration: 5 + (index % 7) * 0.8,
      })),
    [],
  );

  const droplets = useMemo(
    () =>
      Array.from({ length: 11 }, (_, index) => ({
        top: 9 + ((index * 17) % 75),
        offset: 18 + ((index * 29) % 130),
        size: 4 + (index % 4) * 2,
        delay: (index % 5) * 0.08,
      })),
    [],
  );

  const sparkles = useMemo(
    () =>
      Array.from({ length: 8 }, (_, index) => ({
        top: 12 + ((index * 23) % 72),
        offset: 24 + ((index * 31) % 150),
        size: 5 + (index % 3) * 3,
        delay: (index % 4) * 0.11,
      })),
    [],
  );

  useEffect(() => {
    let frame = 0;

    const update = () => {
      cancelAnimationFrame(frame);

      frame = requestAnimationFrame(() => {
        const hero = document.getElementById("home");

        if (!hero) return;

        const rect = hero.getBoundingClientRect();

        /*
         * The cleaning pass happens during the first section of scrolling.
         * It starts immediately and completes before the hero leaves.
         */
        const travel = Math.max(window.innerHeight * 0.72, 1);
        const nextProgress = clamp(-rect.top / travel);

        setProgress(nextProgress);
      });
    };

    update();

    window.addEventListener("scroll", update, { passive: true });
    window.addEventListener("resize", update);

    return () => {
      cancelAnimationFrame(frame);
      window.removeEventListener("scroll", update);
      window.removeEventListener("resize", update);
    };
  }, []);

  /*
   * Sweep begins outside the right edge and moves once to the left.
   */
  const sweepX = 112 - progress * 128;
  const effectVisible = progress > 0.015 && progress < 0.985;
  const dirtOpacity = Math.max(0, 0.46 * (1 - progress));
  const trailOpacity = effectVisible
    ? Math.min(progress * 8, (1 - progress) * 8, 1)
    : 0;

  return (
    <div
      aria-hidden="true"
      className="pointer-events-none fixed inset-0 z-[80] overflow-hidden"
      style={
        {
          "--clean-progress": `${progress}`,
          "--sweep-x": `${sweepX}%`,
          "--dirt-opacity": dirtOpacity,
          "--trail-opacity": trailOpacity,
        } as React.CSSProperties
      }
    >
      {/* Initial subtle haze covering the website */}
      <div className="dirty-atmosphere">
        <div className="dirty-vignette" />

        {dust.map((particle, index) => (
          <span
            className="dust-particle"
            key={index}
            style={{
              left: `${particle.left}%`,
              top: `${particle.top}%`,
              width: particle.size,
              height: particle.size,
              animationDelay: `${particle.delay}s`,
              animationDuration: `${particle.duration}s`,
            }}
          />
        ))}
      </div>

      {/* Soft clarity behind the completed sweep */}
      <div
        className="cleaned-light"
        style={{
          clipPath: `inset(0 ${Math.max(0, 100 - progress * 100)}% 0 0)`,
        }}
      />

      {/* One clean, controlled moving boundary */}
      <div className="cleaning-boundary">
        <div className="boundary-glow" />
        <div className="boundary-reflection" />

        <div className="boundary-particles">
          {droplets.map((droplet, index) => (
            <span
              className="clean-droplet"
              key={`droplet-${index}`}
              style={{
                top: `${droplet.top}%`,
                right: `${droplet.offset}px`,
                width: droplet.size,
                height: droplet.size * 1.55,
                animationDelay: `${droplet.delay}s`,
              }}
            />
          ))}

          {sparkles.map((sparkle, index) => (
            <span
              className="clean-sparkle"
              key={`sparkle-${index}`}
              style={{
                top: `${sparkle.top}%`,
                right: `${sparkle.offset}px`,
                width: sparkle.size,
                height: sparkle.size,
                animationDelay: `${sparkle.delay}s`,
              }}
            />
          ))}
        </div>
      </div>

      <style jsx>{`
        .dirty-atmosphere {
          position: absolute;
          inset: 0;
          opacity: var(--dirt-opacity);
          background:
            linear-gradient(
              112deg,
              rgba(103, 128, 139, 0.1),
              rgba(225, 235, 238, 0.19) 45%,
              rgba(96, 120, 130, 0.08)
            );
          backdrop-filter:
            blur(calc((1 - var(--clean-progress)) * 2.8px))
            saturate(calc(0.84 + var(--clean-progress) * 0.16));
          transition: opacity 80ms linear;
          will-change: opacity, backdrop-filter;
        }

        .dirty-vignette {
          position: absolute;
          inset: 0;
          background:
            radial-gradient(
              circle at 42% 42%,
              transparent 15%,
              rgba(39, 63, 72, 0.055) 100%
            );
        }

        .dust-particle {
          position: absolute;
          display: block;
          border-radius: 50%;
          background: rgba(73, 100, 111, 0.42);
          filter: blur(0.35px);
          animation: dustDrift linear infinite;
        }

        .cleaned-light {
          position: absolute;
          inset: 0;
          opacity: calc(var(--clean-progress) * 0.52);
          background:
            radial-gradient(
              circle at 72% 24%,
              rgba(142, 224, 255, 0.2),
              transparent 32%
            ),
            linear-gradient(
              112deg,
              rgba(255, 255, 255, 0.12),
              rgba(188, 236, 252, 0.08)
            );
          mix-blend-mode: screen;
          transition:
            clip-path 70ms linear,
            opacity 70ms linear;
          will-change: clip-path;
        }

        .cleaning-boundary {
          position: absolute;
          top: -8%;
          bottom: -8%;
          left: var(--sweep-x);
          width: clamp(90px, 9vw, 150px);
          opacity: var(--trail-opacity);
          transform: translateX(-50%) rotate(1.6deg);
          transition:
            left 70ms linear,
            opacity 120ms ease;
          will-change: left, opacity;
        }

        .boundary-glow {
          position: absolute;
          top: 0;
          bottom: 0;
          left: 50%;
          width: 2px;
          transform: translateX(-50%);
          background:
            linear-gradient(
              180deg,
              transparent,
              rgba(255, 255, 255, 0.9) 12%,
              rgba(91, 209, 248, 0.95) 48%,
              rgba(255, 255, 255, 0.92) 82%,
              transparent
            );
          box-shadow:
            0 0 13px rgba(255, 255, 255, 0.86),
            0 0 34px rgba(66, 190, 235, 0.46);
        }

        .boundary-reflection {
          position: absolute;
          top: 0;
          bottom: 0;
          left: 50%;
          width: 100%;
          transform: translateX(-50%);
          background:
            linear-gradient(
              90deg,
              transparent,
              rgba(255, 255, 255, 0.18) 43%,
              rgba(255, 255, 255, 0.52) 50%,
              rgba(110, 215, 250, 0.12) 58%,
              transparent
            );
          filter: blur(9px);
        }

        .boundary-particles {
          position: absolute;
          inset: 0;
        }

        .clean-droplet {
          position: absolute;
          display: block;
          border-radius: 54% 54% 62% 62%;
          opacity: 0;
          background:
            radial-gradient(
              circle at 32% 24%,
              rgba(255, 255, 255, 0.95),
              rgba(103, 214, 248, 0.67) 42%,
              rgba(14, 127, 174, 0.78)
            );
          box-shadow:
            inset 0 1px 1px rgba(255, 255, 255, 0.82),
            0 3px 7px rgba(14, 106, 146, 0.16);
          animation: dropletRelease 1.05s ease-out infinite;
        }

        .clean-sparkle {
          position: absolute;
          display: block;
          opacity: 0;
          border-radius: 2px;
          background: white;
          transform: rotate(45deg);
          box-shadow:
            0 0 7px rgba(255, 255, 255, 0.95),
            0 0 16px rgba(80, 204, 246, 0.82);
          animation: sparkleReveal 0.9s ease-in-out infinite;
        }

        .clean-sparkle::before,
        .clean-sparkle::after {
          content: "";
          position: absolute;
          left: 50%;
          top: 50%;
          border-radius: inherit;
          background: inherit;
          transform: translate(-50%, -50%);
        }

        .clean-sparkle::before {
          width: 24%;
          height: 210%;
        }

        .clean-sparkle::after {
          width: 210%;
          height: 24%;
        }

        @keyframes dustDrift {
          0% {
            transform: translate3d(0, 12px, 0);
            opacity: 0;
          }

          18% {
            opacity: 0.55;
          }

          82% {
            opacity: 0.25;
          }

          100% {
            transform: translate3d(18px, -32px, 0);
            opacity: 0;
          }
        }

        @keyframes dropletRelease {
          0% {
            opacity: 0;
            transform: translate3d(0, -8px, 0) scale(0.55);
          }

          22% {
            opacity: 0.82;
          }

          100% {
            opacity: 0;
            transform: translate3d(-18px, 32px, 0) scale(1);
          }
        }

        @keyframes sparkleReveal {
          0%,
          100% {
            opacity: 0;
            transform: scale(0.35) rotate(45deg);
          }

          45% {
            opacity: 0.92;
            transform: scale(1) rotate(45deg);
          }
        }

        @media (prefers-reduced-motion: reduce) {
          .dust-particle,
          .clean-droplet,
          .clean-sparkle {
            animation: none;
          }
        }
      `}</style>
    </div>
  );
}
