'use client';

import { useEffect, useRef, useState } from 'react';
import type { Brand } from '@/types';

export type LogoScrollSpeed = 'slow' | 'normal' | 'fast';

/** Pixels per frame when idle; hovering a side steers at 5/3 of that (0.6 → 1 as on index.php). */
const IDLE_SPEED: Record<LogoScrollSpeed, number> = { slow: 0.3, normal: 0.6, fast: 1.2 };

/**
 * Infinite logo strip; hovering the left/right third steers direction, the middle pauses (ported from index.php).
 * The strip only scrolls (and repeats) when the logos are wider than the screen; a short list sits still, once.
 */
export default function LogoScroll({ brands, speed: speedSetting = 'normal' }: { brands: Brand[]; speed?: LogoScrollSpeed }) {
  const areaRef = useRef<HTMLDivElement>(null);
  const trackRef = useRef<HTMLDivElement>(null);
  const setRef = useRef<HTMLDivElement>(null);
  const [scrolls, setScrolls] = useState(true);

  useEffect(() => {
    const area = areaRef.current;
    const set = setRef.current;
    if (!area || !set) return;
    // Fires once on observe, then whenever the screen or the logo row (images loading) changes size.
    const observer = new ResizeObserver(() =>
      setScrolls(set.getBoundingClientRect().width > area.getBoundingClientRect().width),
    );
    observer.observe(area);
    observer.observe(set);
    return () => observer.disconnect();
  }, [brands]);

  useEffect(() => {
    const area = areaRef.current;
    const track = trackRef.current;
    const set = setRef.current;
    if (!area || !track || !set) return;
    if (!scrolls) {
      track.style.transform = '';
      return;
    }

    const idle = IDLE_SPEED[speedSetting] ?? IDLE_SPEED.normal;
    const steer = (idle * 5) / 3;
    let x = 0;
    let direction = -1;
    let speed = idle;
    let isHover = false;
    let setWidth = set.getBoundingClientRect().width;
    let frame = 0;

    const onResize = () => {
      setWidth = set.getBoundingClientRect().width;
      if (setWidth > 0) {
        while (x <= -setWidth) x += setWidth;
        while (x >= 0) x -= setWidth;
      }
    };
    const onEnter = () => {
      isHover = true;
    };
    const onLeave = () => {
      isHover = false;
      direction = -1;
      speed = idle;
    };
    const onMove = (e: MouseEvent) => {
      const rect = area.getBoundingClientRect();
      const percent = (e.clientX - rect.left) / rect.width;
      if (percent < 0.35) {
        direction = -1;
        speed = steer;
      } else if (percent > 0.65) {
        direction = 1;
        speed = steer;
      } else {
        speed = 0;
      }
    };
    const tick = () => {
      if (!isHover) {
        direction = -1;
        speed = idle;
      }
      x += direction * speed;
      if (x <= -setWidth) x += setWidth;
      if (x >= 0) x -= setWidth;
      track.style.transform = `translate3d(${x}px, 0, 0)`;
      frame = requestAnimationFrame(tick);
    };

    window.addEventListener('resize', onResize);
    area.addEventListener('mouseenter', onEnter);
    area.addEventListener('mouseleave', onLeave);
    area.addEventListener('mousemove', onMove);
    tick();

    return () => {
      cancelAnimationFrame(frame);
      window.removeEventListener('resize', onResize);
      area.removeEventListener('mouseenter', onEnter);
      area.removeEventListener('mouseleave', onLeave);
      area.removeEventListener('mousemove', onMove);
    };
  }, [brands, scrolls, speedSetting]);

  const logos = (hidden: boolean) =>
    brands.map((brand, i) => (
      <div className="logo-item" key={`${brand.logo}-${i}`}>
        <img src={brand.logo} alt={hidden ? '' : brand.name} className="img-fluid" />
      </div>
    ));

  return (
    <section className="logo-section bg-black pb-4 pb-md-5">
      <div className="logo-scroll-area" ref={areaRef} style={scrolls ? undefined : { display: 'flex', justifyContent: 'center' }}>
        <div className="logo-track" ref={trackRef}>
          <div className="logo-set" ref={setRef}>
            {logos(false)}
          </div>
          {scrolls && (
            <div className="logo-set" aria-hidden="true">
              {logos(true)}
            </div>
          )}
        </div>
      </div>
    </section>
  );
}
