<script lang="ts">
  // 정사각형 아이콘 전용 버튼. nav/toolbar에서 사용.
  // aria-label 필수 (스크린 리더 라벨링).
  import { Loader2 } from 'lucide-svelte';

  // lucide-svelte v0.400은 legacy 타입. 향후 v0.469+ 업그레이드 후 정식 타입으로 좁히기.
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  type IconComponent = any;

  type Variant = 'primary' | 'secondary' | 'ghost' | 'danger';
  type Size = 'sm' | 'md';

  interface Props {
    icon: IconComponent;
    'aria-label': string;
    variant?: Variant;
    size?: Size;
    loading?: boolean;
    disabled?: boolean;
    type?: 'button' | 'submit' | 'reset';
    href?: string;
    target?: string;
    onclick?: (e: MouseEvent) => void;
    onmousedown?: (e: MouseEvent) => void;
    onpointerdown?: (e: PointerEvent) => void;
    class?: string;
  }

  let {
    icon: Icon,
    'aria-label': ariaLabel,
    variant = 'ghost',
    size = 'md',
    loading = false,
    disabled = false,
    type = 'button',
    href,
    target,
    onclick,
    class: className = '',
    ...rest
  }: Props = $props();

  const variantClass: Record<Variant, string> = {
    primary: 'bg-accent text-white hover:bg-accent-hover',
    secondary: 'bg-surface border border-default text-text hover:bg-surface-hover',
    ghost: 'text-dim hover:bg-surface hover:text-text',
    danger: 'text-error hover:bg-error/10',
  };

  const sizeClass: Record<Size, string> = {
    sm: 'h-7 w-7',
    md: 'h-9 w-9',
  };

  let iconSize = $derived(size === 'sm' ? 14 : 16);

  let baseClass = $derived(
    [
      'inline-flex items-center justify-center rounded-md',
      'transition-colors',
      'focus-visible:ring-2 focus-visible:ring-accent-ring focus-visible:outline-none',
      'disabled:opacity-50 disabled:cursor-not-allowed',
      sizeClass[size],
      variantClass[variant],
      className,
    ].join(' ')
  );

  let isDisabled = $derived(disabled || loading);
</script>

{#if href}
  <a
    {href}
    {target}
    class={baseClass}
    aria-label={ariaLabel}
    aria-disabled={isDisabled || undefined}
    tabindex={isDisabled ? -1 : undefined}
    {...rest}
  >
    {#if loading}
      <Loader2 size={iconSize} class="animate-spin" />
    {:else}
      <Icon size={iconSize} />
    {/if}
  </a>
{:else}
  <button
    {type}
    class={baseClass}
    disabled={isDisabled}
    aria-label={ariaLabel}
    aria-busy={loading || undefined}
    {onclick}
    {...rest}
  >
    {#if loading}
      <Loader2 size={iconSize} class="animate-spin" />
    {:else}
      <Icon size={iconSize} />
    {/if}
  </button>
{/if}
