import { Component, OnInit, Input, ViewChild } from '@angular/core';
import {MatTable} from '@angular/material/table'; 
import {MatDialog} from '@angular/material/dialog';
import { Observable } from 'rxjs';

import { CourseData } from '../../../structures/course-data';
import { SchoolData } from '../../../structures/school-data';
import { CourseThemeData } from '../../../structures/course-theme-data';
import { InstructorData } from '../../../structures/instructor-data';
import { CourseInstructorData } from '../../../structures/course-instructor-data';
import { LoggedUserData } from '../../../structures/logged-user-data';

import { SchoolService } from '../../../services/school.service';
import { CourseThemeService } from '../../../services/course-theme.service';
import { CourseInstructorService } from '../../../services/course-instructor.service';
import { LoginService } from '../../../services/login.service';
import { CourseService } from '../../../services/course.service';

import { CourseInstructorsDialogComponent } from '../../../courses/components/course-instructors-dialog/course-instructors-dialog.component';

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

@Component({
  selector: 'app-courses-table-with-instructors',
  templateUrl: './courses-table-with-instructors.component.html',
  styleUrls: ['./courses-table-with-instructors.component.scss']
})
export class CoursesTableWithInstructorsComponent implements OnInit {

  @Input() courses: CourseData[] = [];
  @Input() invalidation: number = 0; // promenna slouzici pro invalidaci dat ve vlozene komponente. Kurzy jsou predavany jako pole a u toho Angular nedetekuje zmeny uvnitr.

  @ViewChild(MatTable) table!: MatTable<CourseData>;

  courseThemes: CourseThemeData[] | null = null;
  schools: SchoolData[] | null = null;

  userData: LoggedUserData | null = null;

  today: Date = new Date();

  detailLink: string = Globals.pages.courseDetail.path;

  courseRoles = Globals.instructorCourseRoles;

  saveInterestSavingStatus: number = Globals.savingStatus.none;

  displayedColumns: string[] = ['date', 'class', 'schoolName', 'themeName', 'instructors-1', 'instructors-2', 'instructors-3', 'link'];

  constructor(public dialog: MatDialog, private schoolService: SchoolService, private courseThemeService: CourseThemeService, private courseInstructorService: CourseInstructorService, private loginService: LoginService, private courseService: CourseService) {
      // nacteni udaju o uzivateli
      this.loginService.userData$.subscribe((data: LoggedUserData | null) => {
        this.userData = data;
      })

      // nacteni skol
      this.schoolService.allSchools$.subscribe((schools: SchoolData[] | null) => {
        this.schools = schools;
      });
      this.schoolService.actualizeAllSchools();
  
      // nacteni temat kurzu
      this.courseThemeService.courseThemes$.subscribe((themes: CourseThemeData[] | null) => {
        this.courseThemes = themes;
      });
      this.courseThemeService.actualizeCourseThemes();
      
      // inicializace indikatoru ukladani
      this.courseInstructorService.saveStatusReset();
      this.courseInstructorService.courseInstructorsSaveStatus$.subscribe( val => this.saveInterestSavingStatus = val );
  }

  ngOnInit(): void {
  }

  ngOnChanges() {
     if(this.table != undefined) {
      this.table.renderRows();
     }
  }

  instructorsVisible(instructors: CourseInstructorData[] | null, role: number, state: string | null): boolean {
    if(instructors != null)
    {
      if(state == null) {
        var printable = instructors.filter(instructor => { return instructor.roleId == role;} );
        if(printable.length > 0) {
          return true;
        } else {
          return false;
        }
      }
      var printable = instructors.filter(instructor => { return instructor.roleId == role && instructor.state == state; } );
      if(printable.length > 0) {
        return true;
      }
    }
    return false;
  }

  showInterest(courseId: number, role: number) {
    var found = this.courses.find(course => { return course.ID == courseId; });
    if(found != undefined && this.userData != null && this.userData.instructor != null) {
      //var instructor: CourseInstructorData = { instructorId: this.userData.ID, instructorName: this.userData.firstname+' '+this.userData.lastname, roleId: role };
      this.courseInstructorService.saveInterest(courseId, role);
      found.instructors?.push({ instructorId: this.userData.instructor.ID, instructorName: this.userData.instructor.firstname+' '+this.userData.instructor.lastname, roleId: role, state: 'zadost', evaluation: null });
      found.instructors = JSON.parse(JSON.stringify(found.instructors));
      if(this.table != undefined) {
        this.table.renderRows();
      }
    }
  }

  removeInterest(courseId: number, role: number) {
    var found = this.courses.find(course => { return course.ID == courseId; });
    if(found != undefined && this.userData != null && this.userData.instructor != null) {
      this.courseInstructorService.removeInterest(courseId);
      var instructorIndex = found.instructors?.findIndex(instructor => { return instructor.instructorId == this.userData?.instructor?.ID; });
      if(instructorIndex != undefined) {
        found.instructors?.splice(instructorIndex, 1);
        found.instructors = JSON.parse(JSON.stringify(found.instructors));
        if(this.table != undefined) {
          this.table.renderRows();
        }
      }
    }
  }

  getSchoolNameById(id: number | null): string {
    if(this.schools != null && id != null) {
      var found = this.schools.find(school => { return school.ID == id; });
      if(found != undefined) {
        return found.name;
      }
    }
    return '';
  } 

  getThemeNameById(id: number | null): string {
    if(this.courseThemes != null && id != null) {
      var found = this.courseThemes.find(theme => { return theme.ID == id; });
      if(found != undefined) {
        return found.name;
      }
    }
    return '';
  } 

  isInvolved(courseData: CourseData): boolean {
    var involved = false;
    courseData.instructors?.forEach(instructor => {
      if(instructor.instructorId == this.userData?.instructor?.ID){
        involved = true;
      }
    });
    return involved;  
  }

  isInsterestedIn(courseData: CourseData, role: number): boolean {
    var involved = false;
    if(this.userData != null && this.userData.instructor != null) {
      var index = courseData.instructors?.findIndex(instructor => {
        return instructor.instructorId == this.userData?.instructor?.ID && instructor.roleId == role && instructor.state == 'zadost';
      });
      if(index != -1 && index != undefined) {
        involved = true;
      }
    }
    return involved;  
  }

  isPast(date: Date): boolean {
    var dateObject = new Date(date);
    return dateObject < this.today;
  }

  roleAtLeast(role: string): boolean {
    return this.loginService.instructorRoleAtLeast(role);
  }

  openEditCourseInstructorsDialog(course: CourseData, role: number): void {
    if(course != null) {
      const dialogRef = this.dialog.open(CourseInstructorsDialogComponent, {
        width: '480px',
        data: { instructors: course.instructors, role: role }
      });
  
      dialogRef.afterClosed().subscribe(newInstructors => {
        if(course != null && newInstructors != undefined) {


          // ulozeni nove hodnoty do kurzu v pameti
          var iterable: CourseInstructorData[] = newInstructors;
          if(course.instructors != null){
            var tmp = course.instructors?.filter(courseInstructor => { 
              var result = courseInstructor.roleId != role;
              iterable.forEach(instructor => {
                if(instructor.instructorId == courseInstructor.instructorId) {
                  result = false;
                }
              });
              return result; 
            });
            var tmp = tmp?.concat(newInstructors);
            if(tmp != undefined) {
              course.instructors = tmp;
            }
          }

          if(course.ID != null) {
            this.courseService.updateCourseInstructors(newInstructors, course.ID, role);
          }
        }
      });
    }
  }

}
