import { classNames } from '@/lib/components/classNames';
import type { ReactNode, SVGProps } from 'react';
import styles from './Icon.module.css';

export const approvedIconNames = [
  'arrow-back',
  'arrow-forward',
  'calendar',
  'car',
  'check',
  'chevron-down',
  'chevron-forward',
  'close',
  'error',
  'external',
  'globe',
  'info',
  'menu',
  'minus',
  'plus',
  'search',
  'settings',
  'spinner',
  'warning',
] as const;

export type ApprovedIconName = (typeof approvedIconNames)[number];
export type IconSize = 'sm' | 'md' | 'lg';
export type IconDirectionBehavior = 'fixed' | 'mirror';

interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'name'> {
  name: ApprovedIconName;
  size?: IconSize;
  decorative?: boolean;
  label?: string;
  directionBehavior?: IconDirectionBehavior;
}

const paths: Record<ApprovedIconName, ReactNode> = {
  'arrow-back': <path d="m15 18-6-6 6-6M9 12h10" />,
  'arrow-forward': <path d="m9 18 6-6-6-6m6 6H5" />,
  calendar: (
    <>
      <rect x="3" y="5" width="18" height="16" rx="2" />
      <path d="M16 3v4M8 3v4M3 10h18" />
    </>
  ),
  car: (
    <>
      <path d="m5 11 2-5h10l2 5" />
      <path d="M3 11h18v7H3zM6 18v2m12-2v2M7 14h.01M17 14h.01" />
    </>
  ),
  check: <path d="m5 12 4 4L19 6" />,
  'chevron-down': <path d="m6 9 6 6 6-6" />,
  'chevron-forward': <path d="m9 18 6-6-6-6" />,
  close: <path d="M6 6l12 12M18 6 6 18" />,
  error: (
    <>
      <circle cx="12" cy="12" r="9" />
      <path d="M12 7v6m0 4h.01" />
    </>
  ),
  external: (
    <>
      <path d="M14 4h6v6M20 4l-9 9" />
      <path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6" />
    </>
  ),
  globe: (
    <>
      <circle cx="12" cy="12" r="9" />
      <path d="M3 12h18M12 3c3 3 3 15 0 18M12 3c-3 3-3 15 0 18" />
    </>
  ),
  info: (
    <>
      <circle cx="12" cy="12" r="9" />
      <path d="M12 11v6m0-10h.01" />
    </>
  ),
  menu: <path d="M4 7h16M4 12h16M4 17h16" />,
  minus: <path d="M5 12h14" />,
  plus: <path d="M12 5v14M5 12h14" />,
  search: (
    <>
      <circle cx="11" cy="11" r="7" />
      <path d="m16 16 5 5" />
    </>
  ),
  settings: (
    <>
      <circle cx="12" cy="12" r="3" />
      <path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1-2.8 2.8-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.6v.2h-4V21a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1L4.2 17l.1-.1a1.7 1.7 0 0 0 .3-1.9A1.7 1.7 0 0 0 3 14H2.8v-4H3a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9L4.2 7 7 4.2l.1.1A1.7 1.7 0 0 0 9 4.6 1.7 1.7 0 0 0 10 3V2.8h4V3a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1L19.8 7l-.1.1a1.7 1.7 0 0 0-.3 1.9 1.7 1.7 0 0 0 1.6 1h.2v4H21a1.7 1.7 0 0 0-1.6 1Z" />
    </>
  ),
  spinner: <path d="M21 12a9 9 0 1 1-9-9" />,
  warning: (
    <>
      <path d="M12 3 2.5 20h19L12 3Z" />
      <path d="M12 9v5m0 3h.01" />
    </>
  ),
};

export function Icon({
  name,
  size = 'md',
  decorative = true,
  label,
  directionBehavior = 'fixed',
  className,
  ...props
}: IconProps) {
  const accessibleProps = decorative
    ? ({ 'aria-hidden': true } as const)
    : ({ role: 'img', 'aria-label': label ?? name } as const);
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="2"
      strokeLinecap="round"
      strokeLinejoin="round"
      focusable="false"
      className={classNames(
        styles.icon,
        styles[size],
        directionBehavior === 'mirror' && styles.mirror,
        className,
      )}
      {...accessibleProps}
      {...props}
    >
      {paths[name]}
    </svg>
  );
}
