import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ViewEncapsulation, OnInit, OnDestroy, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { IconDefinition } from '@fortawesome/free-solid-svg-icons';
import { 
  faCheckCircle, 
  faExclamationTriangle, 
  faExclamationCircle, 
  faInfoCircle,
  faTimes
} from '@fortawesome/free-solid-svg-icons';

type SnackbarSize = 'sm' | 'md' | 'lg';
type SnackbarVariant = 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info';
type SnackbarPosition = 'bottom-center' | 'bottom-left' | 'bottom-right' | 'top-center' | 'top-left' | 'top-right';

export interface SnackbarAction {
  label: string;
  handler: () => void;
  disabled?: boolean;
}

@Component({
  selector: 'ui-snackbar',
  standalone: true,
  imports: [CommonModule, FontAwesomeModule],
  changeDetection: ChangeDetectionStrategy.Default,
  encapsulation: ViewEncapsulation.None,
  template: `
    <div 
      class="ui-snackbar"
      [class.ui-snackbar--sm]="size === 'sm'"
      [class.ui-snackbar--md]="size === 'md'"
      [class.ui-snackbar--lg]="size === 'lg'"
      [class.ui-snackbar--primary]="variant === 'primary'"
      [class.ui-snackbar--success]="variant === 'success'"
      [class.ui-snackbar--warning]="variant === 'warning'"
      [class.ui-snackbar--danger]="variant === 'danger'"
      [class.ui-snackbar--info]="variant === 'info'"
      [class.ui-snackbar--top]="position.startsWith('top')"
      [class.ui-snackbar--left]="position.includes('left')"
      [class.ui-snackbar--right]="position.includes('right')"
      [class.ui-snackbar--entering]="isEntering"
      [class.ui-snackbar--exiting]="isExiting"
      [attr.role]="role"
      [attr.aria-live]="ariaLive"
      [attr.aria-labelledby]="message ? 'snackbar-message-' + snackbarId : null">
      
      @if (showIcon && snackbarIcon) {
        <fa-icon 
          class="ui-snackbar__icon" 
          [icon]="snackbarIcon"
          [attr.aria-hidden]="true">
        </fa-icon>
      }
      
      <div class="ui-snackbar__content" [class.ui-snackbar__content--multiline]="isMultiline">
        <div 
          class="ui-snackbar__message"
          [id]="'snackbar-message-' + snackbarId">
          {{ message }}
          <ng-content></ng-content>
        </div>
      </div>
      
      @if (actions && actions.length > 0) {
        <div class="ui-snackbar__actions">
          @for (action of actions; track action.label) {
            <button
              type="button"
              class="ui-snackbar__action"
              [disabled]="action.disabled"
              [attr.aria-label]="action.label"
              (click)="handleActionClick(action)">
              {{ action.label }}
            </button>
          }
        </div>
      }
      
      @if (dismissible) {
        <button
          type="button"
          class="ui-snackbar__dismiss"
          [attr.aria-label]="dismissLabel"
          (click)="handleDismiss()"
          (keydown)="handleDismissKeydown($event)">
          <fa-icon [icon]="faTimes" [attr.aria-hidden]="true"></fa-icon>
        </button>
      }
    </div>
  `,
  styleUrl: './snackbar.component.scss'
})
export class SnackbarComponent implements OnInit, OnDestroy {
  @Input() size: SnackbarSize = 'md';
  @Input() variant: SnackbarVariant = 'default';
  @Input() message = '';
  @Input() showIcon = false;
  @Input() dismissible = true;
  @Input() autoDismiss = true;
  @Input() duration = 4000; // 4 seconds - shorter than toast
  @Input() position: SnackbarPosition = 'bottom-center';
  @Input() dismissLabel = 'Dismiss snackbar';
  @Input() role = 'status';
  @Input() ariaLive: 'polite' | 'assertive' | 'off' = 'polite';
  @Input() actions: SnackbarAction[] = [];
  @Input() isMultiline = false;
  
  @Output() dismissed = new EventEmitter<void>();
  @Output() expired = new EventEmitter<void>();
  @Output() shown = new EventEmitter<void>();
  @Output() hidden = new EventEmitter<void>();
  @Output() actionClicked = new EventEmitter<SnackbarAction>();
  
  // Icons
  readonly faCheckCircle = faCheckCircle;
  readonly faExclamationTriangle = faExclamationTriangle;
  readonly faExclamationCircle = faExclamationCircle;
  readonly faInfoCircle = faInfoCircle;
  readonly faTimes = faTimes;
  
  // Generate unique ID for accessibility
  readonly snackbarId = Math.random().toString(36).substr(2, 9);
  
  // State management
  isEntering = false;
  isExiting = false;
  private autoDismissTimeout?: any;
  private enterTimeout?: any;
  private exitTimeout?: any;
  
  get snackbarIcon(): IconDefinition | null {
    if (!this.showIcon) return null;
    
    switch (this.variant) {
      case 'success':
        return this.faCheckCircle;
      case 'warning':
        return this.faExclamationTriangle;
      case 'danger':
        return this.faExclamationCircle;
      case 'info':
        return this.faInfoCircle;
      case 'primary':
      case 'default':
      default:
        return this.faInfoCircle;
    }
  }
  
  ngOnInit(): void {
    this.show();
  }
  
  ngOnDestroy(): void {
    this.clearTimeouts();
  }
  
  show(): void {
    this.isEntering = true;
    
    this.enterTimeout = setTimeout(() => {
      this.isEntering = false;
      this.shown.emit();
      
      if (this.autoDismiss && this.duration > 0) {
        this.startAutoDismissTimer();
      }
    }, 300); // Animation duration
  }
  
  hide(): void {
    this.clearTimeouts();
    this.isExiting = true;
    
    this.exitTimeout = setTimeout(() => {
      this.isExiting = false;
      this.hidden.emit();
    }, 300); // Animation duration
  }
  
  handleDismiss(): void {
    this.hide();
    this.dismissed.emit();
  }
  
  handleDismissKeydown(event: KeyboardEvent): void {
    if (event.key === 'Enter' || event.key === ' ') {
      event.preventDefault();
      this.handleDismiss();
    }
  }
  
  handleActionClick(action: SnackbarAction): void {
    if (!action.disabled) {
      action.handler();
      this.actionClicked.emit(action);
    }
  }
  
  private startAutoDismissTimer(): void {
    if (this.autoDismissTimeout) {
      clearTimeout(this.autoDismissTimeout);
    }
    
    this.autoDismissTimeout = setTimeout(() => {
      this.hide();
      this.expired.emit();
    }, this.duration);
  }
  
  private clearTimeouts(): void {
    if (this.autoDismissTimeout) {
      clearTimeout(this.autoDismissTimeout);
      this.autoDismissTimeout = undefined;
    }
    
    if (this.enterTimeout) {
      clearTimeout(this.enterTimeout);
      this.enterTimeout = undefined;
    }
    
    if (this.exitTimeout) {
      clearTimeout(this.exitTimeout);
      this.exitTimeout = undefined;
    }
  }
  
  // Pause auto-dismiss on mouse enter
  onMouseEnter(): void {
    if (this.autoDismissTimeout) {
      clearTimeout(this.autoDismissTimeout);
    }
  }
  
  // Resume auto-dismiss on mouse leave  
  onMouseLeave(): void {
    if (this.autoDismiss && this.duration > 0 && !this.isExiting) {
      this.startAutoDismissTimer();
    }
  }
}