import Track from "./Track";
import "./Album.css";
import type { Album, Track as TrackType } from "../../album";

import { useLayoutEffect, useMemo, useRef, useState } from "react";

export default function Album({ album, dismissAlbum, play, nowPlaying }: { album: Album; dismissAlbum: () => void, play: (i: number) => void, nowPlaying: TrackType }) {
  const titleViewportRef = useRef<HTMLSpanElement | null>(null);
  const titleTextRef = useRef<HTMLSpanElement | null>(null);

  const [isMarquee, setIsMarquee] = useState(false);
  const [marqueeDistancePx, setMarqueeDistancePx] = useState(0);

  // Tunables (constant px/sec + visible gap between repeats)
  const marqueeGapPx = 96;
  const marqueeSpeedPxPerSec = 60;

  useLayoutEffect(() => {
    const viewportEl = titleViewportRef.current;
    const textEl = titleTextRef.current;
    if (!viewportEl || !textEl) return;

    let raf = 0;
    const measure = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        const viewportWidth = viewportEl.clientWidth;
        const textWidth = textEl.scrollWidth;
        const shouldMarquee = textWidth > viewportWidth + 1;

        setIsMarquee(shouldMarquee);
        setMarqueeDistancePx(shouldMarquee ? textWidth + marqueeGapPx : 0);
      });
    };

    measure();

    const ro = new ResizeObserver(measure);
    ro.observe(viewportEl);

    // Fonts can load after first paint and change measurements.
    void (document as unknown as { fonts?: { ready: Promise<void> } }).fonts?.ready.then(measure);

    return () => {
      cancelAnimationFrame(raf);
      ro.disconnect();
    };
  }, [album.title]);

  const marqueeStyle = useMemo(() => {
    if (!isMarquee) return undefined;

    const durationSec = marqueeSpeedPxPerSec > 0 ? marqueeDistancePx / marqueeSpeedPxPerSec : 0;

    return {
      ["--marquee-gap" as never]: `${marqueeGapPx}px`,
      ["--marquee-distance" as never]: `${marqueeDistancePx}px`,
      ["--marquee-duration" as never]: `${durationSec}s`,
    };
  }, [isMarquee, marqueeDistancePx]);

  return (
    <section className="panel">
      <div className="meta">
        <div className="title-row">
          <h1 className="title" id="release-title">
            <span
              ref={titleViewportRef}
              className={`title-viewport${isMarquee ? " is-marquee" : ""}`}
              style={marqueeStyle}
              title={album.title}
            >
              <span className="title-track">
                <span ref={titleTextRef} className="title-text">{album.title}</span>
                {isMarquee ? (
                  <span className="title-text title-text--clone">{album.title}</span>
                ) : null}
              </span>
            </span>
          </h1>
          <button type="button" className="dismiss" onClick={dismissAlbum}>✕</button>
        </div>
        <p className="subtitle" id="release-artist">
          {album.artistName} {album.releaseDate.year ? ' • ' + album.releaseDate.year : ''} {/* TODO: .toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" }) */}
        </p>
        <div className="queue" id="queue">
          {album.tracks.map((t, i) => (
            <Track key={t.id} idx={i} track={t} play={play} nowPlaying={nowPlaying} />
          ))}
        </div>
      </div>
    </section>
  );
}
