"use client";

import { useEffect, useRef, useState } from "react";
import Link from "next/link";
import {
  Heart, MessageCircle, UserPlus, Repeat2, Coins, ShoppingBag, Tag, X, Briefcase } from "lucide-react";
import { Avatar } from "./Avatar";
import { sfx } from "@/lib/sfx";
import { useAuth } from "@/lib/auth-context";
import type { AppNotification } from "@/lib/types";

const ICONS = {
  like: Heart,
  comment: MessageCircle,
  follow: UserPlus,
  repost: Repeat2,
  tip: Coins,
  sale: ShoppingBag,
  offer: Tag,
  message: MessageCircle,
  job_application: Briefcase,
} as const;

/**
 * Shows a toast when something new arrives, without waiting for a refresh.
 * Polls alongside the badge counts and only reacts to ids it hasn't seen.
 */
export function LiveToasts() {
  const { user } = useAuth();
  const [live, setLive] = useState<AppNotification[]>([]);
  const seen = useRef<Set<string> | null>(null);

  useEffect(() => {
    if (!user) return;
    let stopped = false;

    async function poll() {
      const list: AppNotification[] = await fetch("/api/notifications")
        .then((r) => (r.ok ? r.json() : []))
        .catch(() => []);
      if (stopped || !Array.isArray(list)) return;

      // The first pass records what's already there, so opening the app
      // doesn't replay every old notification at you.
      if (seen.current === null) {
        seen.current = new Set(list.map((n) => n.id));
        return;
      }

      const fresh = list.filter((n) => !seen.current!.has(n.id) && !n.read);
      if (fresh.length === 0) return;

      fresh.forEach((n) => seen.current!.add(n.id));
      sfx.bubble();
      setLive((cur) => [...fresh.slice(0, 3), ...cur].slice(0, 3));

      // Each toast clears itself after a few seconds.
      fresh.forEach((n) =>
        setTimeout(
          () => setLive((cur) => cur.filter((x) => x.id !== n.id)),
          6000
        )
      );
    }

    poll();
    const t = setInterval(poll, 12000);
    return () => {
      stopped = true;
      clearInterval(t);
    };
  }, [user]);

  if (!user || live.length === 0) return null;

  return (
    <div className="lt-stack">
      {live.map((n) => {
        const Icon = ICONS[n.type as keyof typeof ICONS] ?? Heart;
        const href =
          n.link ||
          (n.postId ? `/post/${n.postId}` : `/${n.actor?.username ?? ""}`);

        return (
          <Link
            key={n.id}
            href={href}
            className="lt-toast"
            onClick={() => setLive((cur) => cur.filter((x) => x.id !== n.id))}
          >
            <span className={`lt-icon ${n.type}`}>
              <Icon size={13} />
            </span>

            {n.actor && <Avatar user={n.actor} size={30} effect={false} />}

            <span className="min-w-0 flex-1">
              <b>{n.actor?.name ?? "Someone"}</b>
              <em>{n.text}</em>
            </span>

            <button
              onClick={(e) => {
                e.preventDefault();
                setLive((cur) => cur.filter((x) => x.id !== n.id));
              }}
              className="lt-x"
              aria-label="Dismiss"
            >
              <X size={13} />
            </button>
          </Link>
        );
      })}
    </div>
  );
}
