import { Subscription } from 'rxjs';

import { Router, NavigationStart } from '@angular/router';
import { Component, OnInit, OnDestroy, Input, inject } from '@angular/core';

import { AlertService } from './alert.service';
import { Alert, AlertType } from './alert.model';

@Component({
  standalone: true,
  selector: 'alert',
  templateUrl: './alert.component.html',
  styleUrls: ['alert.component.css'],
  imports: []
})
export class AlertComponent implements OnInit, OnDestroy
{
  private readonly router = inject(Router);
  private readonly alertService = inject(AlertService);

  @Input() fade: boolean = true;
  @Input() id: string = 'default-alert';

  alerts: Alert[] = [];
  alertSubscription: Subscription;
  routeSubscription: Subscription;

  ngOnInit()
  {
    // subscribe to new alert notifications
    this.alertSubscription = this.alertService.onAlert(this.id)
      .subscribe(alert =>
      {
        // clear alerts when an empty alert is received
        if (!alert.message)
        {
          // filter out alerts without 'keepAfterRouteChange' flag
          this.alerts = this.alerts.filter(x => x.keepAfterRouteChange);

          // remove 'keepAfterRouteChange' flag on the rest
          this.alerts.forEach(x => delete x.keepAfterRouteChange);

          return;
        }

        // add alert to array
        this.alerts.push(alert);

        // auto close alert if required
        if (alert.autoClose)
        {
          setTimeout(() => this.removeAlert(alert), 3000);
        }

        // Comment out this line If alert position in botton
        if (this.alerts.length > 0)
          window.scroll({ top: 0, left: 0, behavior: 'smooth' });
      });

    // clear alerts on location change
    this.routeSubscription = this.router.events.subscribe(event =>
    {
      if (event instanceof NavigationStart)
      {
        this.alertService.clear(this.id);
      }
    });
  }

  ngOnDestroy()
  {
    // unsubscribe to avoid memory leaks
    this.alertSubscription.unsubscribe();
    this.routeSubscription.unsubscribe();
  }

  removeAlert(alert: Alert)
  {
    // check if already removed to prevent error on auto close
    if (!this.alerts.includes(alert)) return;

    if (this.fade)
    {
      // fade out alert
      this.alerts.find(x => x === alert).fade = true;

      // remove alert after faded out
      setTimeout(() =>
      {
        this.alerts = this.alerts.filter(x => x !== alert);
      }, 250);
    } else
    {
      // remove alert
      this.alerts = this.alerts.filter(x => x !== alert);
    }
  }

  cssClass(alert: Alert)
  {
    if (!alert)
      return;

    const classes = ['alert', 'alert-dismissable'];
    const alertTypeClass = {
      [AlertType.Success]: 'alert alert-success',
      [AlertType.Error]: 'alert alert-danger',
      [AlertType.Info]: 'alert alert-info',
      [AlertType.Warning]: 'alert alert-warning'
    }

    classes.push(alertTypeClass[alert.type]);

    if (alert.fade)
    {
      classes.push('fade');
    }

    return classes.join(' ');
  }
}
