"use client";

import * as React from "react";
import Link from "next/link";
import { AnimatePresence, motion } from "motion/react";
import { Radio } from "lucide-react";
import { cn } from "@/lib/utils";
import { describeActivity, hrefFor, type ActivityDto } from "@/components/dashboard/activity-feed";
import { relativeTime } from "@/lib/dates";
import { useTick } from "./use-changed";

type Item = Omit<ActivityDto, "createdAt"> & { createdAt: string };

/**
 * Live event ticker: the newest action slides in on the left and is held for
 * a few seconds while the rest scroll by. Ticks its own "updated" clock.
 */
export function LiveTicker({ items, updatedAt, className, dark }: { items: Item[]; updatedAt: Date; className?: string; dark?: boolean }) {
  useTick(4000);
  const [mounted, setMounted] = React.useState(false);
  React.useEffect(() => setMounted(true), []);
  const [latest, setLatest] = React.useState<Item | null>(null);
  const seen = React.useRef<Set<string> | null>(null);
  React.useEffect(() => {
    if (!seen.current) {
      seen.current = new Set(items.map((i) => i.id));
      return;
    }
    const fresh = items.find((i) => !seen.current!.has(i.id));
    for (const i of items) seen.current.add(i.id);
    if (fresh) {
      setLatest(fresh);
      const t = setTimeout(() => setLatest(null), 6000);
      return () => clearTimeout(t);
    }
  }, [items]);
  const row = items.slice(0, 10);
  const ago = Math.max(0, Math.round((Date.now() - updatedAt.getTime()) / 1000));
  return (
    <div className={cn("flex h-9 items-center gap-2 overflow-hidden rounded-full border pl-2 pr-3 text-xs", dark ? "border-white/15 bg-white/10 text-white/85" : "border-border bg-surface/80 text-fg-muted", className)}>
      <span className={cn("flex shrink-0 items-center gap-1.5 rounded-full px-2 py-0.5 text-2xs font-bold uppercase tracking-wider", dark ? "bg-white/15 text-white" : "bg-positive-500/12 text-positive-700 dark:text-positive-500")}>
        <span className="live-dot" /> Live
      </span>
      <div className="relative min-w-0 flex-1 overflow-hidden">
        <AnimatePresence mode="wait">
          {latest ? (
            <motion.p key={latest.id} initial={{ opacity: 0, y: 12 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -12 }} transition={{ type: "spring", stiffness: 420, damping: 32 }} className={cn("flex items-center gap-1.5 truncate font-medium", dark ? "text-white" : "text-fg")}>
              <Radio className="size-3.5 shrink-0 animate-pulse-soft text-positive-500" /> <span className="truncate">{latest.userName.split(" ")[0]} {describeActivity({ ...latest, createdAt: new Date(latest.createdAt) })}</span>
            </motion.p>
          ) : (
            <motion.div key="marquee" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="marquee mask-fade-r">
              <div className="flex w-max animate-marquee gap-8 whitespace-nowrap">
                {[...row, ...row].map((a, i) => {
                  const href = hrefFor({ ...a, createdAt: new Date(a.createdAt) });
                  const text = (
                    <>
                      <span className={cn("font-medium", dark ? "text-white" : "text-fg")}>{a.userName.split(" ")[0]}</span> {describeActivity({ ...a, createdAt: new Date(a.createdAt) })} {mounted ? <span className="opacity-60">· {relativeTime(a.createdAt)}</span> : null}
                    </>
                  );
                  return href ? (
                    <Link key={`${a.id}-${i}`} href={href} className="transition hover:opacity-80">
                      {text}
                    </Link>
                  ) : (
                    <span key={`${a.id}-${i}`}>{text}</span>
                  );
                })}
                {row.length === 0 ? <span>Waiting for the first action of the day…</span> : null}
              </div>
            </motion.div>
          )}
        </AnimatePresence>
      </div>
      <span className="shrink-0 tabular text-2xs opacity-70">{!mounted || ago < 5 ? "just now" : ago < 60 ? `${ago}s ago` : relativeTime(updatedAt)}</span>
    </div>
  );
}
