import {CommonModule} from '@angular/common';
import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  ElementRef,
  EventEmitter,
  Input,
  OnDestroy,
  OnInit,
  Output
} from '@angular/core';
import {DomSanitizer, SafeStyle} from '@angular/platform-browser';
import {IconButtonComponent} from '../icon-button/icon-button.component';
import {IconComponent} from '../icon/icon.component';

@Component({
  selector: 'nj-toast',
  templateUrl: './toast.component.html',
  styleUrls: ['./toast.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [IconComponent, IconButtonComponent, CommonModule]
})
export class ToastComponent implements OnInit, OnDestroy {

  private _dismissTimeoutId: number;
  /**
   * Toast unique id used to link description to close button
   */
  @Input() toastId: string;
  /**
   * Whether toast is inverse or not
   */
  @Input() isInverse: boolean;

  /**
   * Whether toast has a close icon or not
   */
  @Input() hasCloseIcon = true;

  /**
   * Icon :<br>
   * <a href="https://material.io/resources/icons/" target="_blank">Material icons</a>
   */
  @Input() iconName?: string;

  /**
   * Time in ms to dismiss after
   */
  @Input() dismissAfter? = 5000;

  /**
   * Gauge accessible hidden label.
   * @example "The toast will be automatically closed in 10s"
   */
  @Input() gaugeLabel = 'Time left until toast is closed';

  /**
   * Whether toast should dismiss after some time elapsed
   */
  @Input() shouldDismiss?: boolean;

  /**
   * Outputs event when toast is closed
   */
  @Output() closed = new EventEmitter<Event>();

  /**
   * Outputs event when toast is dismissed
   */
  @Output() dismissed = new EventEmitter<void>();

  constructor(private sanitize: DomSanitizer, private el: ElementRef, private cdr: ChangeDetectorRef) {
  }

  ngOnInit() {
    if(this.shouldDismiss) {
      // @ts-ignore
      this._dismissTimeoutId = setTimeout(() => {
        this.removeToast();
        this.dismissed.emit();
      }, this.dismissAfter);
    }
  }

  ngOnDestroy() {
    this.clearDismissTimeout();
  }

  /**
   * @ignore
   */
  getGaugeAnimationStyles(): SafeStyle {
    if (!this.dismissAfter) {
      return null;
    }
    return this.sanitize.bypassSecurityTrustStyle(`
       animation-duration: ${this.dismissAfter}ms
    `);
  }

  /**
   * Close toast
   */
  close(event?: MouseEvent) {
    event?.preventDefault();
    event?.stopImmediatePropagation();
    this.removeToast();
    this.closed.emit(event);
    this.cdr.markForCheck();
  }

  /**
   * @ignore
   */
  clearDismissTimeout() {
    if (this._dismissTimeoutId) {
      clearTimeout(this._dismissTimeoutId);
    }
  }

  removeToast() {
    this.el?.nativeElement?.remove();
    this.clearDismissTimeout();
  }
}
