import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';

import { CourseInstructorData } from '../structures/course-instructor-data';

import * as Globals from '../globals';

@Injectable({
  providedIn: 'root'
})
export class CourseInstructorService {

  // stav ukladani instruktoru propojenych s akci
  private courseInstructorsSaveStatus = new BehaviorSubject<number>(Globals.savingStatus.none);
  courseInstructorsSaveStatus$ = this.courseInstructorsSaveStatus.asObservable();

  constructor(private http: HttpClient) { }

  saveStatusReset(): void {
    if(this.courseInstructorsSaveStatus.value != Globals.savingStatus.inProgress) {
      this.courseInstructorsSaveStatus.next(Globals.savingStatus.none);
    }
  }

  async saveCourseInstructors(data: CourseInstructorData[]): Promise<void> {
    this.courseInstructorsSaveStatus.next(Globals.savingStatus.inProgress);
    if(Globals.isMock) {
      this.courseInstructorsSaveStatus.next(Globals.savingStatus.success);
    } else {
      await this.http.post<any>(Globals.api.updateCourseInstructors, data, Globals.httpOptions).pipe( catchError(this.handleError)).toPromise().then(
        (val) => this.courseInstructorsSaveStatus.next(Globals.savingStatus.success),
        (err) => this.courseInstructorsSaveStatus.next(Globals.savingStatus.failed)
      );
    }
  }

  async saveInterest(courseId: number, role: number): Promise<void> {
    this.courseInstructorsSaveStatus.next(Globals.savingStatus.inProgress);
    var data = { courseId: courseId, role: role };
    if(Globals.isMock) {
      this.courseInstructorsSaveStatus.next(Globals.savingStatus.success);
    } else {
      await this.http.post<any>(Globals.api.saveInterest, data, Globals.httpOptions).pipe( catchError(this.handleError)).toPromise().then(
        (val) => this.courseInstructorsSaveStatus.next(Globals.savingStatus.success),
        (err) => this.courseInstructorsSaveStatus.next(Globals.savingStatus.failed)
      );
    }
  }

  async removeInterest(courseId: number): Promise<void> {
    this.courseInstructorsSaveStatus.next(Globals.savingStatus.inProgress);
    await this.http.post<any>(Globals.api.removeInterest + '?courseId=' + courseId, {}, Globals.httpOptions).pipe( catchError(this.handleError)).toPromise().then(
      (val) => this.courseInstructorsSaveStatus.next(Globals.savingStatus.success),
      (err) => this.courseInstructorsSaveStatus.next(Globals.savingStatus.failed)
    );
  }

  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong.
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    // Return an observable with a user-facing error message.
    return throwError(
      'Something bad happened; please try again later.');
  }
}
