"use client";

import { useEffect, useState } from "react";
import type { Post } from "@/lib/types";

export type Trend = { tag: string; count: number };

/**
 * What this site is actually talking about.
 *
 * Counted from the posts that exist, not from a list written into the
 * code. The rail and the search box both used to ship the same five
 * invented tags with invented totals — #shaderart, 128.4K posts — which
 * on a site that had just been installed was the first thing a new owner
 * saw, and it was fiction.
 *
 * An empty array means say nothing. Both callers hide their section
 * rather than drawing an empty box.
 */
export function useTrending(limit = 5): Trend[] {
  const [tags, setTags] = useState<Trend[]>([]);

  useEffect(() => {
    let alive = true;

    fetch("/api/posts?feed=")
      .then((r) => (r.ok ? r.json() : []))
      .then((d) => {
        if (!alive) return;
        const posts: Post[] = Array.isArray(d) ? d : d?.posts ?? [];
        const counts = new Map<string, number>();

        for (const p of posts) {
          // One post repeating a tag counts once for it.
          const seen = new Set<string>();
          for (const raw of (p.text ?? "").match(/#[\w-]{2,30}/g) ?? []) {
            const tag = raw.slice(1).toLowerCase();
            if (seen.has(tag)) continue;
            seen.add(tag);
            counts.set(tag, (counts.get(tag) ?? 0) + 1);
          }
        }

        setTags(
          [...counts.entries()]
            .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
            .slice(0, limit)
            .map(([tag, count]) => ({ tag, count }))
        );
      })
      .catch(() => {});

    return () => {
      alive = false;
    };
  }, [limit]);

  return tags;
}
