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

@Component({
  selector: 'app-subjects',
  templateUrl: './subject-list.component.html',
  styleUrls: ['./subject-list.component.css']
})
export class SubjectListComponent implements OnInit, AfterViewInit {
  displayedColumns: string[] = ['select', 'name', 'students'];
  subjectList = new MatTableDataSource<Subject>([]);
  selection = new SelectionModel<Subject>(true, []);
  subject?: Subject;
  @ViewChild(MatTable) table!: MatTable<Subject>;
  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;

  constructor(private subjectService: SubjectService, public dialog: MatDialog) {
  }

  ngOnInit(): void {
    this.getSubjects();
  }

  ngAfterViewInit() {
    this.subjectList.paginator = this.paginator;
    this.subjectList.sort = this.sort;
  }

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

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

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

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

  getSubjects(): void {
    this.subjectService.getSubjects().subscribe(subjectList => this.subjectList.data = subjectList);
  }

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

  add(name: string): void {
    name = name.trim();
    this.subjectService.addSubject({ name } as Subject).subscribe({
        next: (subject: Subject) => {
          this.subjectList.data = [...this.subjectList.data, subject];
        },
      }
    )
  }

  delete(): void {
    const selectedSubjects: Subject[] = this.selection.selected;
    this.subjectService.deleteSubjects(selectedSubjects).subscribe({
      next: ({ records }) => {
        for (const rec of records) {
          this.subjectList.data = this.subjectList.data.filter(subject => subject.id !== rec);
        }
      },
    });
  }

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

}

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

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