/* eslint-disable @typescript-eslint/no-explicit-any */
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
import * as brands from "@fortawesome/free-brands-svg-icons";
import * as regular from "@fortawesome/free-regular-svg-icons";
import * as solid from "@fortawesome/free-solid-svg-icons";
import { IconCategory, IconType } from "./types";

// Track seen unicodes to filter duplicates globally
const seenUnicodes = new Set<string>();

/**
 * Gets the icon class name
 */
export const getIconClassName = (iconDef: IconDefinition): string => {
  if (!iconDef || !iconDef.iconName) return "";
  return `fa-${iconDef.iconName}`;
};

/**
 * Gets the icon unicode
 */
export const getIconUnicode = (icon: IconDefinition): string => {
  if (!icon || !icon.icon) return "";
  const unicodeHex =
    Array.isArray(icon.icon) && icon.icon.length > 0
      ? (icon.icon[3] as string)
      : "";
  return unicodeHex ? `\\u${unicodeHex}` : "";
};

/**
 * Extract icons from a FontAwesome package
 */
function extractIcons(
  pkg: Record<string, any>,
  categoryName: string,
  prefixTag: string,
): IconType[] {
  return Object.values(pkg)
    .filter(
      (def): def is IconDefinition & { iconName: string; prefix: string } =>
        Boolean(def?.iconName),
    )
    .map((def) => {
      const name = def.iconName;

      const unicode = getIconUnicode(def);
      return {
        id: unicode || `${prefixTag}-${name}`, // fallback to name if unicode missing
        name: `${prefixTag}-${name}`,
        icon: def,
        unicode,
        class: getIconClassName(def),
        category: categoryName,
      };
    })
    .filter((icon) => {
      if (!icon.unicode || seenUnicodes.has(icon.unicode)) return false;
      seenUnicodes.add(icon.unicode);
      return true;
    });
}

/**
 * Categorized icon list with prefix-tagged names
 */
const iconCategories: IconCategory[] = [
  { name: "Solid", icons: extractIcons(solid, "Solid", "solid") },
  { name: "Regular", icons: extractIcons(regular, "Regular", "regular") },
  { name: "Brands", icons: extractIcons(brands, "Brands", "brands") },
];

/**
 * Get all icons as flat list
 */
export function getAllIcons(): IconType[] {
  return iconCategories.flatMap((category) => category.icons);
}

/**
 * Get icon categories
 */
export function getIconCategories(): IconCategory[] {
  return iconCategories;
}

/**
 * Generate random icon name
 */
export const generateRandomIconName = (prefix = "icon"): string => {
  const randomId = Math.floor(Math.random() * 10000);
  const suffixes = [
    "home",
    "user",
    "settings",
    "file",
    "folder",
    "chart",
    "mail",
    "calendar",
    "map",
    "image",
    "video",
    "audio",
    "lock",
    "key",
  ];
  const randomSuffix = suffixes[Math.floor(Math.random() * suffixes.length)];
  return `${prefix}-${randomSuffix}-${randomId}`;
};
