import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ViewEncapsulation, OnInit, OnDestroy, ElementRef, 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 ToastSize = 'sm' | 'md' | 'lg';
type ToastVariant = 'primary' | 'success' | 'warning' | 'danger' | 'info';
type ToastPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';

@Component({
  selector: 'ui-toast',
  standalone: true,
  imports: [CommonModule, FontAwesomeModule],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  template: `
    <div 
      class="ui-toast"
      [class.ui-toast--sm]="size === 'sm'"
      [class.ui-toast--md]="size === 'md'"
      [class.ui-toast--lg]="size === 'lg'"
      [class.ui-toast--primary]="variant === 'primary'"
      [class.ui-toast--success]="variant === 'success'"
      [class.ui-toast--warning]="variant === 'warning'"
      [class.ui-toast--danger]="variant === 'danger'"
      [class.ui-toast--info]="variant === 'info'"
      [class.ui-toast--dismissible]="dismissible"
      [class.ui-toast--with-progress]="showProgress && autoDismiss"
      [class.ui-toast--entering]="isEntering"
      [class.ui-toast--exiting]="isExiting"
      [attr.role]="role"
      [attr.aria-live]="ariaLive"
      [attr.aria-labelledby]="title ? 'toast-title-' + toastId : null"
      [attr.aria-describedby]="'toast-content-' + toastId">
      
      @if (showIcon && toastIcon) {
        <fa-icon 
          class="ui-toast__icon" 
          [icon]="toastIcon"
          [attr.aria-hidden]="true">
        </fa-icon>
      }
      
      <div class="ui-toast__content">
        @if (title) {
          <h4 
            class="ui-toast__title"
            [class.ui-toast__title--bold]="boldTitle"
            [id]="'toast-title-' + toastId">
            {{ title }}
          </h4>
        }
        
        <div 
          class="ui-toast__message"
          [id]="'toast-content-' + toastId">
          <ng-content></ng-content>
        </div>
        
        @if (actions && actions.length > 0) {
          <div class="ui-toast__actions">
            <ng-content select="[slot=actions]"></ng-content>
          </div>
        }
      </div>
      
      @if (dismissible) {
        <button
          type="button"
          class="ui-toast__dismiss"
          [attr.aria-label]="dismissLabel"
          (click)="handleDismiss()"
          (keydown)="handleDismissKeydown($event)">
          <fa-icon [icon]="faTimes" [attr.aria-hidden]="true"></fa-icon>
        </button>
      }
      
      @if (showProgress && autoDismiss && duration > 0) {
        <div class="ui-toast__progress">
          <div 
            class="ui-toast__progress-bar"
            [style.--duration]="duration + 'ms'">
          </div>
        </div>
      }
    </div>
  `,
  styleUrl: './toast.component.scss'
})
export class ToastComponent implements OnInit, OnDestroy {
  @Input() size: ToastSize = 'md';
  @Input() variant: ToastVariant = 'primary';
  @Input() title?: string;
  @Input() boldTitle = false;
  @Input() showIcon = true;
  @Input() dismissible = true;
  @Input() autoDismiss = true;
  @Input() duration = 5000; // 5 seconds
  @Input() showProgress = true;
  @Input() position: ToastPosition = 'top-right';
  @Input() dismissLabel = 'Dismiss toast';
  @Input() role = 'alert';
  @Input() ariaLive: 'polite' | 'assertive' | 'off' = 'assertive';
  @Input() actions: any[] = [];
  
  @Output() dismissed = new EventEmitter<void>();
  @Output() expired = new EventEmitter<void>();
  @Output() shown = new EventEmitter<void>();
  @Output() hidden = new EventEmitter<void>();
  
  // Icons
  readonly faCheckCircle = faCheckCircle;
  readonly faExclamationTriangle = faExclamationTriangle;
  readonly faExclamationCircle = faExclamationCircle;
  readonly faInfoCircle = faInfoCircle;
  readonly faTimes = faTimes;
  
  // Generate unique ID for accessibility
  readonly toastId = Math.random().toString(36).substr(2, 9);
  
  // State management
  isEntering = false;
  isExiting = false;
  private autoDismissTimeout?: any;
  private enterTimeout?: any;
  private exitTimeout?: any;
  private elementRef = inject(ElementRef);
  
  get toastIcon(): 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':
      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();
    }
  }
  
  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();
    }
  }
}