import { ApplicationRef, Component, OnInit, HostBinding, Input, Output, EventEmitter, NgZone } from '@angular/core';
import { SpaAlertSeverityEnum } from './spa-alert-severity.enum';


@Component({
  selector: 'spa-alert',
  template: `<div class="spa-alert__container"
    (click)="doClose()">
      <div class="spa-alert__icon-box">
          <i class="spa-alert__icon fal"
            [class.fa-times]="severity === 'error'"
            [class.fa-check]="severity === 'success'"
            [class.fa-exclamation-triangle]="severity === 'warning'"
            [class.fa-info-circle]="severity === 'info'">
          </i>
      </div>
      <div class="spa-alert__content">
          <div *ngIf="!hideTitle" class="spa-alert__title">{{title}}</div>
          {{content}}<ng-content></ng-content>
      </div>
      <i *ngIf="closeable" class="spa-alert__close-button fal fa-times"></i>
  </div>`,
  styles: [`
  :host {
    background-color: rgba(247, 247, 247, 1);
    border-radius: 4px;
    color: rgba(0, 0, 0, .9);
    display: block;
    line-height: 1.6;
  }

  :host(.spa-alert--closeable) {
    cursor: pointer;
  }

  :host(.spa-alert--closeable):hover {
    opacity: 0.6;
  }

  :host(.spa-alert--margin-top) {
    margin-top: 15px;
  }

  .spa-alert__icon-box {
        border-radius: 3px;
        color: #FFFFFF;
        font-size: 20px;
        width: 34px;
        margin: 12px;
        text-align: center;
        align-self: center;
        text-align: center;
  }

  .spa-alert__icon {
      font-size: 18px;
  }

  .spa-alert__container {
    font-size: 16px;
    align-items: center;
    box-sizing: border-box;
    display: flex;
    justify-content: center;
    width: 100%;
    position: relative;
  }

  .spa-alert__content {
    box-sizing: border-box;
    flex: 1;
    padding: 8px 0;
    line-height: 1.3;
    overflow-wrap: break-word;
    word-wrap: break-word;
    -ms-word-break: break-all;
    word-break: break-word;
    -ms-hyphens: auto;
    -moz-hyphens: auto;
    -webkit-hyphens: auto;
    white-space: pre-line;
    hyphens: auto;
  }

  .spa-alert__title {
    font-weight: bold;
    text-transform: uppercase;
    line-height: 1.6;
    margin-bottom: -1px;
  }

  .spa-alert__close-button {
    box-sizing: border-box;
    margin: 12px;
    padding: 5px;
  }

  :host(.spa-alert--error) {
    background-color: #f9e8e9;
  }

  :host(.spa-alert--error) .spa-alert__icon-box {
        background-color: #D9434E;
  }

  :host(.spa-alert--error) .spa-alert__title {
      color: #D9434E;
  }

  :host(.spa-alert--info) {
    background-color: #e8eff9;
  }

  :host(.spa-alert--info) .spa-alert__icon-box {
        background-color: #4A8BDB;
  }

  :host(.spa-alert--info) .spa-alert__title {
      color: #4A8BDB;
  }

  :host(.spa-alert--success) {
    background-color: #e9f9e8;
  }

  :host(.spa-alert--success) .spa-alert__icon-box {
    background-color: #3BB85D;
  }

  :host(.spa-alert--success) .spa-alert__title {
      color: #3BB85D;
  }

  :host(.spa-alert--warning) {
    background-color: #f9f6e8;
  }

  :host(.spa-alert--warning) .spa-alert__icon-box {
    background-color: #F59B43;
  }

  :host(.spa-alert--warning) .spa-alert__title {
      color: #F59B43;
  }
  `]
})
export class SpaAlertComponent implements OnInit {
  @HostBinding('class.spa-alert') hostClass = true;
  @HostBinding('class.spa-alert--closeable') get hostClassCloseable(): boolean { return this.closeable!; }
  @HostBinding('class.spa-alert--error') get hostClassError(): boolean { return this.severity === SpaAlertSeverityEnum.ERROR; }
  @HostBinding('class.spa-alert--info') get hostClassInfo(): boolean { return this.severity === SpaAlertSeverityEnum.INFO; }
  @HostBinding('class.spa-alert--success') get hostClassSucess(): boolean { return this.severity === SpaAlertSeverityEnum.SUCCESS; }
  @HostBinding('class.spa-alert--warning') get hostClassWarning(): boolean { return this.severity === SpaAlertSeverityEnum.WARNING; }
  @Input() public autoClose?: number;      // AutoClose: Time after which alert disappears automatically, in milliseconds.
  @Input() public closeable?= false;      // Closeable: May user close the alert by clicking on the cross icon?
  @Input() public content?: string;        // Content: The text of the message
  @Input() public hideTitle = false;      // HideTitle: If you want to hide the title above the alert
  @Input() public title?: string;                  // Title: The title that will be above the alert message
  @Input() public severity?: SpaAlertSeverityEnum; // Status: The severity determines the color of the alert
  AlertSeverityEnum = SpaAlertSeverityEnum.INFO;
  @Output() public spClose: // spClose: This action is dispatched when the user closes the alert.
    EventEmitter<void> = new EventEmitter<void>();

  private _autoCloseTimeout?: NodeJS.Timeout | null;


  constructor(
    private readonly ngZone: NgZone,
    private readonly applicationRef: ApplicationRef,
  ) { }

  public ngOnInit(): void {
    if (this.autoClose) {
      this.prepareAutoClose();
    }
    if (!this.title) {
      this._assignDefaultTitle();
    }
  }

  public doClose(): void {
    if (this.closeable) {
      this.spClose.emit();
      this.applicationRef.tick();
    }
  }

  private prepareAutoClose(): void {
    this.ngZone.runOutsideAngular(() => {
      this._autoCloseTimeout = setTimeout(() => {
        this.doClose();
        this._autoCloseTimeout = null;
      }, this.autoClose);
    });
  }

  private _assignDefaultTitle(): void {
    switch (this.severity) {
      case SpaAlertSeverityEnum.ERROR:
        this.title = 'Error';
        break;
      case SpaAlertSeverityEnum.INFO:
        this.title = 'Info';
        break;
      case SpaAlertSeverityEnum.SUCCESS:
        this.title = 'Notification';
        break;
      case SpaAlertSeverityEnum.WARNING:
        this.title = 'Warning';
        break;
    }
  }
}
