import type { SVGProps } from "react";
import {
  Activity,
  Archive,
  ArrowRight,
  BatteryMedium,
  Bell,
  Box,
  Calendar,
  Camera,
  CarFront,
  Check,
  ChevronDown,
  ChevronLeft,
  ChevronRight,
  Circle,
  CircleCheck,
  Cloud,
  Columns3,
  Copy,
  Crosshair,
  Download,
  Ellipsis,
  FileCheck,
  FileText,
  Filter,
  Focus,
  History,
  Image as ImageIcon,
  LayoutGrid,
  ListChecks,
  Linkedin,
  Lock,
  MapPin,
  Menu,
  MessageSquareText,
  OctagonAlert,
  Phone,
  Reply,
  RotateCcw,
  Route,
  ScanBarcode,
  ScanLine,
  ScanSearch,
  Search,
  Send,
  ShieldCheck,
  SlidersHorizontal,
  Smartphone,
  StickyNote,
  Table2,
  TimerReset,
  TriangleAlert,
  UserRound,
  UsersRound,
  Video,
  Wifi,
  WifiOff,
  X,
  type LucideIcon
} from "lucide-react";

export const haloIconNames = [
  "activity",
  "alert",
  "archive",
  "arrow-right",
  "battery",
  "board",
  "calendar",
  "camera",
  "capture",
  "car",
  "chart-line",
  "check",
  "chevronDown",
  "chevronLeft",
  "chevronRight",
  "circle",
  "circle-check",
  "close",
  "cloud",
  "columns",
  "copy",
  "coverage",
  "crosshair",
  "cube",
  "download",
  "ellipsis",
  "error",
  "file-check",
  "file-text",
  "filter",
  "focus",
  "grid",
  "history",
  "image",
  "layout-grid",
  "list",
  "linkedin",
  "lock",
  "menu",
  "message",
  "more",
  "note",
  "offline",
  "online",
  "owner",
  "phone",
  "pin",
  "reply",
  "retry",
  "route",
  "scan",
  "scan-line",
  "search",
  "send",
  "shield-check",
  "sliders",
  "smartphone",
  "success",
  "sync",
  "table",
  "target",
  "team",
  "timer-reset",
  "video",
  "warning",
  "x"
] as const;

export type HaloIconName = (typeof haloIconNames)[number];
type HaloIconTone = "current" | "accent" | "muted" | "success" | "warning" | "error" | "info";
type HaloIconSize = "xs" | "sm" | "md" | "lg" | "xl" | number;

const iconMap: Record<HaloIconName, LucideIcon> = {
  activity: Activity,
  alert: Bell,
  archive: Archive,
  "arrow-right": ArrowRight,
  battery: BatteryMedium,
  board: Columns3,
  calendar: Calendar,
  camera: Camera,
  capture: Camera,
  car: CarFront,
  "chart-line": Activity,
  check: Check,
  chevronDown: ChevronDown,
  chevronLeft: ChevronLeft,
  chevronRight: ChevronRight,
  circle: Circle,
  "circle-check": CircleCheck,
  close: X,
  cloud: Cloud,
  columns: Columns3,
  copy: Copy,
  coverage: ScanSearch,
  crosshair: Crosshair,
  cube: Box,
  download: Download,
  ellipsis: Ellipsis,
  error: OctagonAlert,
  "file-check": FileCheck,
  "file-text": FileText,
  filter: Filter,
  focus: Focus,
  grid: LayoutGrid,
  history: History,
  image: ImageIcon,
  "layout-grid": LayoutGrid,
  list: ListChecks,
  linkedin: Linkedin,
  lock: Lock,
  menu: Menu,
  message: MessageSquareText,
  more: Ellipsis,
  note: StickyNote,
  offline: WifiOff,
  online: Wifi,
  owner: UserRound,
  phone: Phone,
  pin: MapPin,
  reply: Reply,
  retry: RotateCcw,
  route: Route,
  scan: ScanBarcode,
  "scan-line": ScanLine,
  search: Search,
  send: Send,
  "shield-check": ShieldCheck,
  sliders: SlidersHorizontal,
  smartphone: Smartphone,
  success: CircleCheck,
  sync: RotateCcw,
  table: Table2,
  target: Crosshair,
  team: UsersRound,
  "timer-reset": TimerReset,
  video: Video,
  warning: TriangleAlert,
  x: X
};

const sizeMap: Record<Exclude<HaloIconSize, number>, number> = {
  xs: 12,
  sm: 16,
  md: 20,
  lg: 24,
  xl: 32
};

const toneStyle: Record<HaloIconTone, { color?: string }> = {
  current: {},
  accent: { color: "var(--halo-accent)" },
  muted: { color: "var(--text-muted)" },
  success: { color: "var(--halo-capture-success)" },
  warning: { color: "var(--halo-warning, #b7791f)" },
  error: { color: "var(--halo-error, #c44d5e)" },
  info: { color: "var(--halo-info, currentColor)" }
};

export type HaloIconProps = Omit<SVGProps<SVGSVGElement>, "name"> & {
  accent?: boolean;
  decorative?: boolean;
  label?: string;
  name: HaloIconName;
  size?: HaloIconSize;
  strokeWidth?: number;
  tone?: HaloIconTone;
};

export const haloIconDefaults = {
  absoluteStrokeWidth: true,
  strokeWidth: 1.5
} as const;

export function HaloIcon({
  accent = false,
  decorative = true,
  label,
  name,
  size = "md",
  strokeWidth = haloIconDefaults.strokeWidth,
  style,
  tone = "current",
  ...props
}: HaloIconProps) {
  const Icon = iconMap[name];
  const resolvedSize = typeof size === "number" ? size : sizeMap[size];
  const resolvedTone = accent ? "accent" : tone;

  return (
    <Icon
      aria-hidden={decorative ? true : undefined}
      aria-label={!decorative ? label : undefined}
      focusable="false"
      role={!decorative ? "img" : undefined}
      size={resolvedSize}
      strokeWidth={strokeWidth}
      absoluteStrokeWidth={haloIconDefaults.absoluteStrokeWidth}
      style={{ ...toneStyle[resolvedTone], ...style }}
      {...props}
    />
  );
}
