/**
 * ResilientActivityProgress WIDGET
 * 
 * Resilient component widget to show a progress bar, for ActivityDomain's.
 * Input's:
 *  - activityDomain: The entity domain instance. Must be a ActivityDomain
 *
 * Event's:
 *  - activityFinished: Fired when the progress bar reaches the end. The event sends a string, with the constant value "ended"
 * 
 * Usage
 *  - In the intended *.component.html insert the code:
 *    <jhi-activity-progress [activityDomain]="_entity()" (activityFinished)="_activityFinishedHandler($event)"></jhi-activity-progress>
 *  - In the *.component.ts insert the code:
 *    import { ResilientActivityProgressComponent } from 'app/resilient/resilient-activity/progress/resilient-activity-progress.component';
 *    ...
 *    _entity = input<IEntity | null>(null);
 *    ...
 *    _activityFinishedHandler(message: string): void {
 *      <react to the activityFinished event>
 *    }
 */

import { Component, Input, Output, OnInit, EventEmitter, inject } from '@angular/core';
import { RouterModule } from '@angular/router';
import { HttpResponse } from '@angular/common/http';

import SharedModule from 'app/shared/shared.module';
import { DurationPipe, FormatMediumDatetimePipe, FormatMediumDatePipe } from 'app/shared/date';
import { IActivityProgress } from '../resilient-activity.model';
import { MatProgressBarModule } from '@angular/material/progress-bar';

import { ResilientActivityService } from '../service/resilient-activity.service';

@Component({
  standalone: true,
  selector: 'jhi-activity-progress',
  templateUrl: './resilient-activity-progress.component.html',
  imports: [SharedModule, RouterModule, DurationPipe, FormatMediumDatetimePipe, FormatMediumDatePipe, MatProgressBarModule],
  styles: [`
    mat-progress-bar { margin: 10px 0; width: 100%; }
  `]
})
export class ResilientActivityProgressComponent implements OnInit {
  @Output() activityFinished = new EventEmitter<string>();
  @Input() activityDomain : any;  // Assumes an Entity instance that extends ActivityDomain
  
  progress: number = -1;
  progressInfo: String = "";

  protected resilientActivityService = inject(ResilientActivityService);

  ngOnInit(): void {
    this.startProgress();
  }
  
  previousState(): void {
    window.history.back();
  }
  
  startProgress(): void {
    // Can't check progress activity without a domain id
    if (!this.activityDomain?.id) return;
    // Can't check progress activity without a domain class
    if (!this.activityDomain?.activityDomainClass) return;
    
    const activityKey = this.activityDomain?.activityDomainClass + "@" + this.activityDomain?.id;
    
    // Default. Just to show the progress bar
    // this.progress = -1;
    // this.progressInfo = "In progress ...";
	
    // Invoke remote activity progress service to get the progress
    const intervalId = setInterval(() => {
		this.resilientActivityService
		  .progress(activityKey)
		  .subscribe({
        next: (res: HttpResponse<IActivityProgress>) => {
          const activityProgress: IActivityProgress | null = res.body ?? null;
          if (activityProgress) {
            const oldProgress = this.progress;
            
            this.progress = activityProgress.progressPercentage;
            this.progressInfo = activityProgress.progressTask;
            
            if (this.progress < 0 || (oldProgress < 0 && this.progress >= 100)) {
              // this.progress < 0 => Negative progress means: nothing is running in the server
              // (oldProgress < 0 && this.progress >= 100) => Progress is 100%, but the progress bar was never started (-1). This is an old progress, that alresdy finished.
              clearInterval(intervalId);	        // Stop the loop
              this.progress = -1;
            } else if (this.progress >= 100) {
              clearInterval(intervalId);	        // Stop the loop
              this.progress = 100; 			          // No sense in having a job with >100%
              this.activityFinished.emit("ended"); // Fire event for other component's reaction
            } else if (oldProgress > 0 && this.progress < 0) {
              // Special case. It was in progress and ended. 
              // When it ends, the progress is removed from the server. 
              // Thats why a negative progress was returned.
              // Assume same behavior as 100%.
              clearInterval(intervalId);
              this.progress = 100;
              this.activityFinished.emit("ended");
            } 
          } else {
            //This is strange. Just report an error in the progressInfo
            this.progressInfo = "Unknown progress information";
          }
        },
        error: (res: HttpResponse<IActivityProgress>) => {
          // Error. No sense in keeping invoking the server. 
          // Give up
          this.progressInfo = "Error fetching the progress information. STOPED";
          clearInterval(intervalId);
        },
		  })
		  ;
    }, 1000);
  }
}
