import {
  ChangeDetectionStrategy,
  Component,
  computed,
  input,
  ViewEncapsulation,
} from '@angular/core';
import { NgIconComponent, provideIcons } from '@ng-icons/core';
import { ButtonColor, ButtonSize } from './types';
import { isaLoading } from '@isa/icons';

/**
 * A UI button component that supports customization of size, color, and state.
 *
 * The component uses reactive signals to dynamically update its CSS classes
 * and properties without manual DOM manipulation. In pending state, it shows
 * a loading spinner while preserving the button's content.
 *
 * Features:
 * - Customizable size and color themes
 * - Loading state with spinner overlay
 * - Disabled state handling
 * - Keyboard navigation support
 *
 * @property size - The size of the button (e.g., 'small', 'medium', 'large'). Default is 'medium'.
 * @property sizeClass - A computed CSS class based on the current size, formatted as 'ui-button__{size}'.
 * @property color - The color theme of the button (e.g., 'primary', 'secondary'). Default is 'primary'.
 * @property colorClass - A computed CSS class based on the current color, formatted as 'ui-button__{color}'.
 * @property pending - A boolean flag indicating whether to show the loading spinner overlay.
 * @property pendingClass - A computed CSS class for the loading state styling.
 * @property tabIndex - The tab index for the button, used to control keyboard navigation order.
 * @property disabled - A boolean flag indicating whether the button is disabled.
 * @property disabledClass - A computed CSS class that adds a 'disabled' style when the button is disabled.
 *
 * @example
 * ```html
 * <button uiButton color="brand" [pending]="isLoading">
 *   Submit Form
 * </button>
 * ```
 *
 * @remarks
 * - The loading spinner is rendered as an overlay, preserving the button's dimensions
 * - The spinner inherits the button's theme colors for visual consistency
 * - The component automatically handles ARIA attributes for accessibility
 */
@Component({
  selector: 'ui-button, [uiButton]',
  templateUrl: './button.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  standalone: true,
  imports: [NgIconComponent],
  providers: [provideIcons({ isaLoading })],
  host: {
    '[class]':
      '["ui-button", sizeClass(), colorClass(), pendingClass(), disabledClass()]',
    '[tabindex]': 'tabIndex()',
    '[disabled]': 'disabled()',
  },
})
export class ButtonComponent {
  /** The size of the button. */
  size = input<ButtonSize>('medium');

  /** A computed CSS class based on the current size. */
  sizeClass = computed(() => `ui-button__${this.size()}`);

  /** The color theme of the button. */
  color = input<ButtonColor>('primary');

  /** A computed CSS class based on the current color. */
  colorClass = computed(() => `ui-button__${this.color()}`);

  /**
   * Indicates whether the button is in a loading or pending state.
   * When true, displays a loading spinner overlay while maintaining button dimensions.
   */
  pending = input<boolean>(false);

  /** A computed CSS class for the pending state. */
  pendingClass = computed(() => (this.pending() ? 'ui-button__pending' : ''));

  /** The tab index for the button. */
  tabIndex = input<number>(0);

  /** Indicates whether the button is disabled. */
  disabled = input<boolean>(false);

  /** A computed CSS class for the disabled state. */
  disabledClass = computed(() => (this.disabled() ? 'disabled' : ''));
}
