"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { ArrowUp } from "lucide-react";

/**
 * A count of posts that have arrived since the feed loaded.
 *
 * The feed doesn't move on its own: reading something while it jumps under
 * you is unpleasant. This says how many are waiting, and pulls them in when
 * you ask.
 */
export function NewPostsBanner({
  feed,
  newestSeen,
  onShow,
}: {
  feed: string;
  /** The timestamp of the newest post already on screen. */
  newestSeen: string | null;
  onShow: () => void;
}) {
  const [count, setCount] = useState(0);
  const timer = useRef<ReturnType<typeof setInterval> | null>(null);

  const check = useCallback(async () => {
    if (!newestSeen || document.hidden) return;

    const res = await fetch(
      `/api/posts?feed=${encodeURIComponent(feed)}&since=${encodeURIComponent(newestSeen)}`
    ).catch(() => null);
    if (!res || !res.ok) return;

    const body = await res.json().catch(() => null);
    const rows = Array.isArray(body) ? body : body?.posts ?? [];
    setCount(rows.length);
  }, [feed, newestSeen]);

  useEffect(() => {
    setCount(0);
    check();

    // Every half minute is often enough to feel live without hammering.
    timer.current = setInterval(check, 30_000);
    return () => {
      if (timer.current) clearInterval(timer.current);
    };
  }, [check]);

  if (count === 0) return null;

  return (
    <button
      onClick={() => {
        setCount(0);
        onShow();
        window.scrollTo({ top: 0, behavior: "smooth" });
      }}
      className="np-banner"
    >
      <ArrowUp size={15} />
      {count === 1 ? "1 new post" : `${count} new posts`}
    </button>
  );
}
