'use client';

import { useEffect, useState } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import { ChevronDown, ChevronUp } from 'lucide-react';

/**
 * A floating control that pages through long content. It scrolls down by one
 * viewport, and once there is nothing left below it flips to "back to top" —
 * so the same button gets a reader down a long page and back again, instead of
 * stranding them at the bottom.
 *
 * Deliberately not a static arrow in the hero: that only ever helped on one
 * page, could not be clicked, and offered nothing on the second screenful.
 */
export function ScrollButton() {
  const [atEnd, setAtEnd] = useState(false);
  // Pages shorter than about a screen and a half do not need this at all.
  const [worthShowing, setWorthShowing] = useState(false);

  useEffect(() => {
    const check = () => {
      const { scrollY, innerHeight } = window;
      const full = document.documentElement.scrollHeight;
      setWorthShowing(full > innerHeight * 1.5);
      // 120px of slack: the very bottom is often unreachable by a pixel or two
      // because of rounding and browser chrome.
      setAtEnd(scrollY + innerHeight >= full - 120);
    };

    check();
    window.addEventListener('scroll', check, { passive: true });
    window.addEventListener('resize', check);
    return () => {
      window.removeEventListener('scroll', check);
      window.removeEventListener('resize', check);
    };
  }, []);

  // `smooth` here is honoured or ignored by the browser according to the
  // visitor's reduced-motion setting, so it needs no guard of its own.
  const go = () => {
    if (atEnd) {
      window.scrollTo({ top: 0, behavior: 'smooth' });
      return;
    }
    // 0.85 rather than a full viewport keeps a sliver of the previous screen
    // visible, so the reader does not lose their place.
    window.scrollBy({ top: window.innerHeight * 0.85, behavior: 'smooth' });
  };

  const Icon = atEnd ? ChevronUp : ChevronDown;

  return (
    <AnimatePresence>
      {worthShowing && (
        <motion.button
          type="button"
          onClick={go}
          aria-label={atEnd ? 'Back to top' : 'Scroll down'}
          title={atEnd ? 'Back to top' : 'Scroll down'}
          initial={{ opacity: 0, scale: 0.8 }}
          animate={{ opacity: 1, scale: 1 }}
          exit={{ opacity: 0, scale: 0.8 }}
          whileHover={{ y: atEnd ? -4 : 4 }}
          whileTap={{ scale: 0.92 }}
          transition={{ duration: 0.2, ease: 'easeOut' }}
          className="fixed bottom-6 right-6 z-50 flex h-12 w-12 items-center justify-center rounded-full
                     bg-primary text-primary-foreground shadow-lg shadow-primary/30
                     ring-1 ring-white/20 transition-colors hover:bg-primary/90
                     focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2
                     focus-visible:outline-primary"
        >
          <Icon className="h-5 w-5" aria-hidden />
        </motion.button>
      )}
    </AnimatePresence>
  );
}
