"use client";

/* Site-wide emoji → animated icon replacement.

   Every emoji used across the story sections maps to a solid black Lucide
   glyph with no border and no background, plus a looping idle motion that
   suits its meaning. Motion is pure CSS (see `globals.css`) so ~100 icons on
   a page cost nothing, and it's disabled under prefers-reduced-motion.

   Two entry points:
     <Ico e="🚶" />      — drop an icon into JSX where an emoji used to sit
     {withIcons(str)}    — render a string that has emoji baked into it
                           (used for copy that lives inside const arrays) */

import type { ReactNode } from "react";
import {
  Heart, Flame, Gift, Mail, Clapperboard, Users, Sparkles, Zap, X, Check,
  CircleAlert, Tv, ShoppingCart, CreditCard, Smartphone, Gamepad2, Footprints,
  Coffee, MapPin, Store, Sprout, Trophy, TreePalm, MessageCircle, Laptop,
  Rocket, Recycle, Sunrise, Globe, Megaphone, Hand, Handshake, Folder, Repeat,
  Brain, TrendingDown, Camera, FerrisWheel, Ticket, ShoppingBag, PartyPopper,
  Tag, EyeOff, Rainbow, Wallet, Fingerprint, Star, Clock,
  type LucideIcon,
} from "lucide-react";

/* motion kinds — matched to CSS keyframes in globals.css */
type Motion = "bob" | "swing" | "spin" | "pulse" | "rock";

const MAP: Record<string, [LucideIcon, Motion]> = {
  // hearts / feelings
  "♡": [Heart, "pulse"], "♥": [Heart, "pulse"], "💗": [Heart, "pulse"],
  "💞": [Heart, "pulse"], "🤍": [Heart, "pulse"], "💚": [Heart, "pulse"],
  "🫂": [Users, "rock"], "🤲": [Hand, "rock"],
  // sparkle / energy
  "✨": [Sparkles, "pulse"], "✦": [Sparkles, "pulse"], "⚡": [Zap, "pulse"],
  "🔥": [Flame, "bob"], "🌈": [Rainbow, "pulse"], "🚀": [Rocket, "bob"],
  // marks
  "✗": [X, "pulse"], "✓": [Check, "pulse"], "❗": [CircleAlert, "pulse"],
  // people / social
  "👯": [Users, "rock"], "👥": [Users, "rock"], "🙋": [Hand, "swing"],
  "🤝": [Handshake, "rock"], "💬": [MessageCircle, "bob"], "📢": [Megaphone, "swing"],
  "🤳": [Camera, "pulse"], "🪞": [Fingerprint, "pulse"], "🧠": [Brain, "pulse"],
  // movement / places
  "🚶": [Footprints, "bob"], "👟": [Footprints, "bob"], "📍": [MapPin, "bob"],
  "🏪": [Store, "bob"], "🌴": [TreePalm, "swing"], "🌱": [Sprout, "bob"],
  "🌅": [Sunrise, "bob"], "🌐": [Globe, "spin"], "☕": [Coffee, "bob"],
  // commerce
  "🛒": [ShoppingCart, "bob"], "🛍️": [ShoppingBag, "swing"], "🛍": [ShoppingBag, "swing"],
  "💳": [CreditCard, "bob"], "💰": [Wallet, "bob"], "🏷️": [Tag, "swing"], "🏷": [Tag, "swing"],
  "🎁": [Gift, "bob"], "📉": [TrendingDown, "bob"],
  // media / tech
  "📺": [Tv, "pulse"], "🎬": [Clapperboard, "rock"], "📱": [Smartphone, "bob"],
  "💻": [Laptop, "bob"], "🎮": [Gamepad2, "rock"], "💌": [Mail, "bob"],
  "📁": [Folder, "bob"], "🔁": [Repeat, "spin"], "♻️": [Recycle, "spin"], "♻": [Recycle, "spin"],
  // fun / rewards
  "🏆": [Trophy, "pulse"], "🎉": [PartyPopper, "rock"], "🎡": [FerrisWheel, "spin"],
  "🎟️": [Ticket, "swing"], "🎟": [Ticket, "swing"], "🫥": [EyeOff, "pulse"],
  "⏰": [Clock, "rock"], "⏳": [Clock, "rock"], "⭐": [Star, "pulse"], "🌟": [Star, "pulse"],
};

/** Matches any emoji we know how to swap (longest keys first for ZWJ/VS16). */
const EMOJI_RE = new RegExp(
  `(${Object.keys(MAP)
    .sort((a, b) => b.length - a.length)
    .map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
    .join("|")})`,
  "gu",
);

export function Ico({
  e,
  size = 16,
  className = "",
}: {
  e: string;
  size?: number;
  className?: string;
}) {
  const hit = MAP[e] ?? MAP[e.replace(/️/g, "")];
  if (!hit) return null;
  const [Glyph, motion] = hit;
  return (
    <span aria-hidden className={`ico ico-${motion} ${className}`}>
      <Glyph size={size} strokeWidth={2.6} color="#0a0a0a" />
    </span>
  );
}

/** Swap every known emoji inside a plain string for an animated icon. */
export function withIcons(text: string, size = 16): ReactNode {
  const parts = text.split(EMOJI_RE).filter((p) => p !== "");
  return parts.map((p, i) =>
    MAP[p] || MAP[p.replace(/️/g, "")] ? (
      <Ico key={i} e={p} size={size} />
    ) : (
      <span key={i}>{p}</span>
    ),
  );
}
