import type { Color } from '@yaakapp-internal/plugins';
import classNames from 'classnames';
import * as lucide from 'lucide-react';
import type { CSSProperties, HTMLAttributes } from 'react';
import { memo } from 'react';

const icons = {
  alert_triangle: lucide.AlertTriangleIcon,
  archive: lucide.ArchiveIcon,
  arrow_big_down_dash: lucide.ArrowBigDownDashIcon,
  arrow_big_left_dash: lucide.ArrowBigLeftDashIcon,
  arrow_big_right: lucide.ArrowBigRightIcon,
  arrow_big_right_dash: lucide.ArrowBigRightDashIcon,
  arrow_big_up_dash: lucide.ArrowBigUpDashIcon,
  arrow_down: lucide.ArrowDownIcon,
  arrow_down_to_dot: lucide.ArrowDownToDotIcon,
  arrow_down_to_line: lucide.ArrowDownToLineIcon,
  arrow_right_circle: lucide.ArrowRightCircleIcon,
  arrow_up: lucide.ArrowUpIcon,
  arrow_up_down: lucide.ArrowUpDownIcon,
  arrow_up_from_dot: lucide.ArrowUpFromDotIcon,
  arrow_up_from_line: lucide.ArrowUpFromLineIcon,
  badge_check: lucide.BadgeCheckIcon,
  book_open_text: lucide.BookOpenText,
  box: lucide.BoxIcon,
  cake: lucide.CakeIcon,
  chat: lucide.MessageSquare,
  check: lucide.CheckIcon,
  check_circle: lucide.CheckCircleIcon,
  check_square_checked: lucide.SquareCheckIcon,
  check_square_unchecked: lucide.SquareIcon,
  chevron_down: lucide.ChevronDownIcon,
  chevron_left: lucide.ChevronLeftIcon,
  chevron_right: lucide.ChevronRightIcon,
  circle_alert: lucide.CircleAlertIcon,
  circle_dollar_sign: lucide.CircleDollarSignIcon,
  circle_fading_arrow_up: lucide.CircleFadingArrowUpIcon,
  clock: lucide.ClockIcon,
  code: lucide.CodeIcon,
  columns_2: lucide.Columns2Icon,
  command: lucide.CommandIcon,
  corner_right_up: lucide.CornerRightUpIcon,
  credit_card: lucide.CreditCardIcon,
  cookie: lucide.CookieIcon,
  copy: lucide.CopyIcon,
  copy_check: lucide.CopyCheck,
  download: lucide.DownloadIcon,
  ellipsis: lucide.EllipsisIcon,
  expand: lucide.ExpandIcon,
  external_link: lucide.ExternalLinkIcon,
  eye: lucide.EyeIcon,
  eye_closed: lucide.EyeOffIcon,
  file_code: lucide.FileCodeIcon,
  filter: lucide.FilterIcon,
  flame: lucide.FlameIcon,
  flask: lucide.FlaskConicalIcon,
  folder: lucide.FolderIcon,
  folder_cog: lucide.FolderCogIcon,
  folder_code: lucide.FolderCodeIcon,
  folder_git: lucide.FolderGitIcon,
  folder_input: lucide.FolderInputIcon,
  folder_open: lucide.FolderOpenIcon,
  folder_output: lucide.FolderOutputIcon,
  folder_symlink: lucide.FolderSymlinkIcon,
  folder_sync: lucide.FolderSyncIcon,
  folder_up: lucide.FolderUpIcon,
  git_branch: lucide.GitBranchIcon,
  git_branch_plus: lucide.GitBranchPlusIcon,
  git_commit: lucide.GitCommitIcon,
  git_commit_vertical: lucide.GitCommitVerticalIcon,
  git_fork: lucide.GitForkIcon,
  git_pull_request: lucide.GitPullRequestIcon,
  grip_vertical: lucide.GripVerticalIcon,
  hand: lucide.HandIcon,
  help: lucide.CircleHelpIcon,
  history: lucide.HistoryIcon,
  house: lucide.HomeIcon,
  import: lucide.ImportIcon,
  info: lucide.InfoIcon,
  key_round: lucide.KeyRoundIcon,
  keyboard: lucide.KeyboardIcon,
  left_panel_hidden: lucide.PanelLeftOpenIcon,
  left_panel_visible: lucide.PanelLeftCloseIcon,
  lock: lucide.LockIcon,
  lock_open: lucide.LockOpenIcon,
  magic_wand: lucide.Wand2Icon,
  merge: lucide.MergeIcon,
  minus: lucide.MinusIcon,
  minus_circle: lucide.MinusCircleIcon,
  moon: lucide.MoonIcon,
  more_vertical: lucide.MoreVerticalIcon,
  palette: lucide.PaletteIcon,
  paste: lucide.ClipboardPasteIcon,
  pencil: lucide.PencilIcon,
  pin: lucide.PinIcon,
  plug: lucide.Plug,
  plus: lucide.PlusIcon,
  plus_circle: lucide.PlusCircleIcon,
  puzzle: lucide.PuzzleIcon,
  refresh: lucide.RefreshCwIcon,
  rocket: lucide.RocketIcon,
  rows_2: lucide.Rows2Icon,
  save: lucide.SaveIcon,
  search: lucide.SearchIcon,
  send_horizontal: lucide.SendHorizonalIcon,
  settings: lucide.SettingsIcon,
  shield: lucide.ShieldIcon,
  shield_check: lucide.ShieldCheckIcon,
  shield_off: lucide.ShieldOffIcon,
  sparkles: lucide.SparklesIcon,
  square_terminal: lucide.SquareTerminalIcon,
  sun: lucide.SunIcon,
  table: lucide.TableIcon,
  text: lucide.FileTextIcon,
  trash: lucide.Trash2Icon,
  unpin: lucide.PinOffIcon,
  update: lucide.RefreshCcwIcon,
  upload: lucide.UploadIcon,
  variable: lucide.VariableIcon,
  wrench: lucide.WrenchIcon,
  x: lucide.XIcon,
  _unknown: lucide.ShieldAlertIcon,

  empty: (props: HTMLAttributes<HTMLSpanElement>) => <div {...props} />,
};

export interface IconProps {
  icon: keyof typeof icons;
  className?: string;
  style?: CSSProperties;
  size?: '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
  spin?: boolean;
  title?: string;
  color?: Color | 'custom' | 'default';
}

export const Icon = memo(function Icon({
  icon,
  color = 'default',
  spin,
  size = 'md',
  style,
  className,
  title,
}: IconProps) {
  const Component = icons[icon] ?? icons._unknown;
  return (
    <Component
      style={style}
      title={title}
      className={classNames(
        className,
        !spin && 'transform-gpu',
        spin && 'animate-spin',
        'flex-shrink-0',
        size === 'xl' && 'h-6 w-6',
        size === 'lg' && 'h-5 w-5',
        size === 'md' && 'h-4 w-4',
        size === 'sm' && 'h-3.5 w-3.5',
        size === 'xs' && 'h-3 w-3',
        size === '2xs' && 'h-2.5 w-2.5',
        color === 'default' && 'inherit',
        color === 'danger' && 'text-danger',
        color === 'warning' && 'text-warning',
        color === 'notice' && 'text-notice',
        color === 'info' && 'text-info',
        color === 'success' && 'text-success',
        color === 'primary' && 'text-primary',
        color === 'secondary' && 'text-secondary',
      )}
    />
  );
});
