import { AfterViewInit, Component, Inject, OnInit, ViewChild } from '@angular/core';
import { Student } from "./student.model";
import { StudentService } from "./student.service";
import { MatTable, MatTableDataSource } from "@angular/material/table";
import { MatPaginator } from "@angular/material/paginator";
import { SelectionModel } from "@angular/cdk/collections";
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from "@angular/material/dialog";
import { MatSort } from "@angular/material/sort";

@Component({
  selector: 'app-students',
  templateUrl: './students.component.html',
  styleUrls: ['./students.component.css']
})
export class StudentsComponent implements OnInit, AfterViewInit {
  displayedColumns: string[] = ['select', 'firstname', 'lastname', 'email', 'lastname'];
  studentList = new MatTableDataSource<Student>([]);
  student?: Student;
  selection = new SelectionModel<Student>(true, []);
  @ViewChild(MatTable) table!: MatTable<Student>;
  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;

  constructor(private studentService: StudentService, public dialog: MatDialog) {
  }

  ngOnInit() {
    this.getStudents();
  }

  ngAfterViewInit() {
    this.studentList.sort = this.sort;
  }

  isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.studentList.data.length;
    return numSelected === numRows;
  }

  masterToggle() {
    if (this.isAllSelected()) {
      this.selection.clear();
      return;
    }

    this.selection.select(...this.studentList.data);
  }

  checkboxLabel(row?: Student): string {
    if (!row) {
      return `${this.isAllSelected() ? 'deselect' : 'select'} all`;
    }
    return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${(row.id || 0) + 1}`;
  }

  getStudents(): void {
    this.studentService.getStudents()
      .subscribe(studentList => this.studentList.data = studentList);
  }

  add({firstname, lastname, email, telephone}: Student): void {
    firstname = firstname.trim();
    lastname = lastname.trim();
    email = email.trim();
    telephone = telephone.trim();
    this.studentService.addStudent({firstname, lastname, email, telephone} as Student).subscribe({
      next: (student: Student) => {
        this.studentList.data = [...this.studentList.data, student];
      }
    });
  }

  delete(): void {
    const selectedStudents: Student[] = this.selection.selected;
    this.studentService.deleteStudents(selectedStudents).subscribe({
      next: ({ records }) => {
        for (const rec of records) {
          this.studentList.data = this.studentList.data.filter(student => student.id !== rec);
        }
      },
    });
  }

  openDialog(): void {
    const dialogRef = this.dialog.open(AddStudentDialog, {
      width: '250px',
      data: {},
    });
    dialogRef.afterClosed().subscribe(result => {
      if (result) {
        this.add(result);
      }
    })
  }

  applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    this.studentList.filter = filterValue.trim().toLowerCase();
  }

}

@Component({
  selector: 'add-student-dialog',
  templateUrl: 'add-student-dialog.component.html',
})
export class AddStudentDialog {
  constructor(public dialogRef: MatDialogRef<AddStudentDialog>, @Inject(MAT_DIALOG_DATA) public student: Student) {
  }

  onNoClick(): void {
    this.dialogRef.close();
  }
}