import {Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef} from '@angular/core';
import {Observable, throwError} from 'rxjs';
import {FormArray, FormBuilder, FormGroup, Validators} from '@angular/forms';
import {BaseForm} from '../../../../../../core/base/base-form';
import {ActivatedRoute, Router} from '@angular/router';
import {formatDate, Location} from '@angular/common';
import {AcademicSemesterService} from '../../../../../../core/service/settings/academic-semester.service';
import {AcademicYearService} from '../../../../../../core/service/settings/academic-year.service';
import {TestingInformationService} from '../../../../../../core/service/testing-information/testing-information.service';
import {SweetalertService} from '../../../../../../core/service/sweetalert/sweetalert';
import {catchError, concatMap, filter, tap} from 'rxjs/operators';
import {SubjectsService} from '../../../../../../core/service/settings/subjects.service';
import {TestingCenterService} from '../../../../../../core/service/TestingCenter/testing-center.service';
import {TestingFieldService} from '../../../../../../core/service/settings/testing-field.service';
import {BranchService} from '../../../../../../core/service/settings/branch.service';
import {MatDialog} from '@angular/material/dialog';
import {EducationTypesService} from '../../../../../../core/service/settings/education-types.service';
import {CalendarTypeService} from '../../../../../../core/service/settings/calendar-type.service';

@Component({
  selector: 'app-create-exam-subject-form',
  templateUrl: './create-exam-subject-form.component.html',
  styleUrls: ['./create-exam-subject-form.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class CreateExamSubjectFormComponent extends BaseForm implements OnInit{
  subjectOldList;
  testingInfoData;
  subjectListSend = new Observable;
  SubjectGetCheck$ = [];
  setexamform: FormGroup;
  public model = [
    // new Date('2/8/2022'),
    // new Date('2/9/2022'),
    // new Date('2/11/2022'),
  ];
  sectionsFakeFalse = [
    {
      status_id: 1,
      testing_center_period_uid: null,
      period_id: 1,
      is_check: false,
      start_time: '09:00'
    },
    {
      status_id: 1,
      testing_center_period_uid: null,
      period_id: 2,
      is_check: false,
      start_time: '12:00'
    },
    {
      status_id: 1,
      testing_center_period_uid: null,
      period_id: 3,
      is_check: false,
      start_time: '15:00'
    },
    {
      status_id: 1,
      testing_center_period_uid: null,
      period_id: 4,
      is_check: false,
      start_time: '18:00'
    }
  ];

  constructor(
    private subjectSV: SubjectsService,
    private testcenterSV: TestingCenterService,
    private testFiledSV: TestingFieldService,
    private branchSV: BranchService,
    private testingFieldSV: TestingFieldService,
    private formBuilder: FormBuilder,
    private dialog: MatDialog,
    public router: Router,
    public activeRoute: ActivatedRoute,
    public location: Location,
    private swSV: SweetalertService,
    private cdRef: ChangeDetectorRef,
    private TestInformationSV: TestingInformationService,
    private EductiontionTypeSV: EducationTypesService,
    private AcademicYearSV: AcademicYearService,
    private AcademicSemSV: AcademicSemesterService,
    private CalendarTypeSV: CalendarTypeService,
    private cdr: ChangeDetectorRef
  ) {
    super(
      router,
      activeRoute,
      formBuilder,
      location
    );
    this.setexamform = this.formBuilder.group({
      status_id: null,
      created_by: null,
      created_datetime: null,
      updated_by: null,
      updated_datetime: null,
      deleted_by: null,
      deleted_datetime: null,
      testing_information_uid: null,
      testing_information_name: [null, Validators.required],
      testing_information_code: null,
      academic_semester_code: [null, Validators.required],
      academic_year_code: [null, Validators.required],
      testing_information_status: null,
      type_of_examinee: [null, Validators.required],
      is_student_code: false,
      first_student_code: '',
      last_student_code: '',
      start_datetime: null,
      end_datetime: null,
      registration_start_datetime: null,
      registration_end_datetime: null,
      testing_start_datetime: null,
      testing_end_datetime: null,
      is_number_of_times_testing: false,
      is_online_register: true,
      number_of_times_testing: null,
      times_the_score_is_calculated: 1,
      is_main: true,
      main_testing_information_uid: null,
      registration_type: 1,
      is_open: null,
      is_upload_document: false,
      is_register_verify: false,
      is_register: false,
      is_counter: false,
      days_without_testings: this.formBuilder.array([
        this.block_days(null)
      ]),
      testing_calendars: this.formBuilder.array([
        this.testing_calendars(null)
      ]),
      testing_subjects: this.formBuilder.array([
        this.testing_subjects()
      ]),
      testing_rooms: this.formBuilder.array([
        this.testing_rooms()
      ]),
      testing_periods: this.formBuilder.array([
        this.testing_periods()
      ])
    });
  }


  block_days(blockdays?){
    return this.formBuilder.group({
      status_id: null,
      testing_information_uid: blockdays?.testing_information_uid,
      days_without_testing_uid: blockdays?.days_without_testing_uid,
      date_without_testing: blockdays?.date_without_testing,
    });
  }

  testing_calendars(calender?){
    return this.formBuilder.group({
      status_id: null,
      testing_calendar_uid: calender?.testing_calendar_uid,
      start_datetime: calender?.start_datetime,
      end_datetime: calender?.end_datetime,
      calendar_type_uid: calender?.calendar_type_uid,
      calendar_type_name_th: calender?.calendar_type_name_th,
      testing_information_uid: calender?.testing_information_uid,
    });
  }

  testing_subjects(data?){
    return this.formBuilder.group({
      status_id: null,
      // created_by: null,
      // created_datetime: null,
      // updated_by: null,
      // updated_datetime: null,
      // deleted_by: null,
      // deleted_datetime: null,
      testing_subject_uid: data?.testing_subject_uid,
      subject_uid: data?.subject_uid,
      subject_code: data?.subject_code,
      subject_name_th: data?.subject_name_th,
      amount: data?.amount,
      random_status: data?.random_status,
      grading_status: data?.grading_status,
      grading_type: data?.grading_type,
      announcement_type: data?.announcement_type,
      grading_characteristic: data?.grading_characteristic,
      random_question_code: data?.random_question_code,
      random_question_type: data?.random_question_type,
      random_type: data?.random_type,
    });
  }

  testing_periods(data?){
    return this.formBuilder.group({
      status_id: null,
      // created_by: null,
      // created_datetime: null,
      // updated_by: null,
      // updated_datetime: null,
      // deleted_by: null,
      // deleted_datetime: null,
      // deleted_datetime: null,
      is_check: data?.is_check,
      testing_information_uid: data?.testing_information_uid,
      testing_period_uid: data?.testing_period_uid,
      period_id: data?.period_id,
      start_time: data?.start_time,
    });
  }

  testing_rooms(data?){
    return this.formBuilder.group({
      testing_room_uid: data?.testing_room_uid,
      testing_center_uid: data?.testing_center_uid,
      // testing_center_name_th: data?.testing_center_name_th,
      branch_uid: data?.branch_uid,
      branch_name_th: data?.branch_name_th,
      testing_field_uid: data?.testing_field_uid,
      testing_information_uid: data?.testing_information_uid,
      testing_field_name_th: data?.testing_field_name_th,
      testing_room_name_th: data?.testing_room_name_th,
      testing_auth_name: data?.testing_auth_name,
      is_random_seat: data?.is_random_seat,
      testing_seats: this.formBuilder.array([
        this.testing_seats(data?.testing_seats)
      ]),
    });
  }

  testing_seats(data?){
    return this.formBuilder.group({
      status_id: null,
      // created_by: null,
      // created_datetime: null,
      // updated_by: null,
      // updated_datetime: null,
      // deleted_by: null,
      // deleted_datetime: null,
      no_of_seats: data?.no_of_seats,
      row_name: data?.row_name,
      testing_seat_uid: data?.testing_seat_uid,
      testing_center_row_uid: data?.testing_center_row_uid,
      is_specify_subject: data?.is_specify_subject,
      testing_room_uid: data?.testing_room_uid,
      testing_seat_subjects: this.formBuilder.array([
        this.testing_seat_subjects(data?.testing_seat_subjects)
      ]),
    });
  }

  testing_seat_subjects(data?){
    return this.formBuilder.group({
      status_id: null,
      testing_seat_subject_uid: data?.testing_seat_subject_uid,
      subject_uid: data?.subject_uid,
      subject_code: data?.subject_code,
      subject_name_th: data?.subject_name_th,
      start_seat_no: data?.start_seat_no,
      end_seat_no: data?.end_seat_no,
      testing_seat_uid: data?.testing_seat_uid,
    });
  }

  ngOnInit(): void {
    const form = this.setexamform.get('testing_calendars') as FormArray;
    const form2 = this.setexamform.get('testing_subjects') as FormArray;
    const form3 = this.setexamform.get('testing_rooms') as FormArray;
    const form4 = this.setexamform.get('testing_periods') as FormArray;
    const form5 = this.setexamform.get('days_without_testings') as FormArray;
    this.subjectListSend = this.subjectSV.getSubjectReady();
    switch (this.state) {
      case 'edit':
        this.TestInformationSV.get(this.id).pipe(
          tap(x => this.testingInfoData = x),
          tap(x =>  {
            form.clear();
            form2.clear();
            form3.clear();
            form4.clear();
            form5.clear();
          }),
          tap(x => {
            const data: any = x;
            this.setexamform.patchValue(data);
          }),
          tap(x => this.add3Edit(x)),
          tap(x => this.addPeriodEdit(x)),
          tap(x => this.addCalendaEdit(x)),
          tap(x => this.addSubject(x)),
          tap(x => this.addEditBlockadd(x)),
          tap(x => this.cdr.detectChanges())
        ).subscribe();
        break;
      case 'add':
        break;
    }
  }

  add3Edit(data){
    const form = this.setexamform.get('testing_rooms') as FormArray;
    for (let i = 0; i < data.testing_rooms.length; i++) {
      form.push(this.testing_rooms(data.testing_rooms[i]));
      const formArray = form.controls[i].get('testing_seats') as FormArray;
      const FormArraySeat = form.controls[i].get('testing_seat_subjects') as FormArray;
      formArray.clear();
      for (let j = 0; j < data.testing_rooms[i].testing_seats.length; j++) {
        formArray.push(this.testing_seats(data.testing_rooms[i].testing_seats[j]));
        const formArraySeatSubject = formArray.controls[j].get('testing_seat_subjects') as FormArray;
        formArraySeatSubject.clear();
        for (let k = 0; k < data.testing_rooms[i].testing_seats[j].testing_seat_subjects.length; k++) {
          formArraySeatSubject.push(this.testing_seat_subjects(data.testing_rooms[i].testing_seats[j].testing_seat_subjects[k]));
        }
      }
    }
  }

  addCalendaEdit(x){
    const form2 = this.setexamform.get('testing_calendars') as FormArray;
    for (let i = 0; i < x.testing_calendars.length; i++) {
      x.testing_calendars[i].end_datetime = formatDate(x.testing_calendars[i].end_datetime, 'yyyy-MM-dd', 'en-US');
      x.testing_calendars[i].start_datetime = formatDate(x.testing_calendars[i].start_datetime, 'yyyy-MM-dd', 'en-US');
      form2.push(this.testing_calendars(x.testing_calendars[i]));
    }
  }

  addPeriodEdit(x){
    const form = this.setexamform.get('testing_periods') as FormArray;
    for (let i = 0; i < x.testing_periods.length; i++) {
      const foundIndex = this.sectionsFakeFalse.findIndex(v => v.period_id === x.testing_periods[i].period_id);
      this.sectionsFakeFalse[foundIndex].is_check = true;
      this.sectionsFakeFalse[foundIndex].start_time = x.testing_periods[i].start_time;
    }
    for (let i = 0; i < this.sectionsFakeFalse.length; i++) {
      form.push(this.testing_periods(this.sectionsFakeFalse[i]));
    }
  }

  addEditBlockadd(x){
    const form = this.setexamform.get('days_without_testings') as FormArray;
    for (let i = 0; i < x.days_without_testings.length; i++) {
      x.days_without_testings[i].date_without_testing = formatDate(x.days_without_testings[i].date_without_testing, 'yyyy-MM-dd', 'en-US');
      form.push(this.block_days(x.days_without_testings[i]));
      this.model.push(x.days_without_testings[i].date_without_testing);
    }
  }

  addSubject(x){
    const form = this.setexamform.get('testing_subjects') as FormArray;
    this.SubjectGetCheck$ = x.testing_subjects;
    if (x.testing_subjects != null){
      for (let i = 0; i < x.testing_subjects.length; i++) {
        console.log(x.testing_subjects[i]);
        form.push(this.testing_subjects(x.testing_subjects[i]));
      }
    }
    this.subjectOldList = form.getRawValue();
  }

  GetSubjectChoose(data){
    const form = this.setexamform.get('testing_subjects') as FormArray;
    form.clear();
    console.log(data)
    const oldSubjectlist = this.testingInfoData.testing_subjects;
    console.log(oldSubjectlist)
    const Newdata = data.filter(x => {
      return !!oldSubjectlist.map(y => {
        if (x.subject_uid === y.subject_uid){
          x.testing_subject_uid = y.testing_subject_uid;
          x.amount = y.amount;
          x.random_status = y.random_status;
          x.grading_status = y.grading_status;
          x.grading_type = y.grading_type;
          x.announcement_type = y.announcement_type;
          x.grading_characteristic = y.grading_characteristic;
          x.random_question_code = y.random_question_code;
          x.random_question_type = y.random_question_type;
          x.random_status = y.random_status;
          x.random_type = y.random_type;
          return x;
        }
      });
    });
    for (let i = 0; i < Newdata.length; i++) {
      form.push(this.testing_subjects(Newdata[i]));
    }
  }

  save(){
    switch (this.state) {
      case 'edit':
        console.log(this.testingInfoData);
        const form2 = this.setexamform.get('testing_subjects') as FormArray;
        let subjectNewList = form2.getRawValue();
        let allowedRoles = null;
        let isAdd = null;
        console.log(subjectNewList);
        // console.log(this.subjectOldList);
        // for (let i = 0; i < this.subjectOldList.length; i++) {
        //   subjectNewList.push(this.subjectOldList[i])
        // }
        subjectNewList = subjectNewList.reduce((unique, o) => {
          if (!unique.some(obj => obj.subject_uid === o.subject_uid)) {
            unique.push(o);
          }
          return unique;
        }, []);
        console.log(subjectNewList);
        // this.ClearSubjectBefore(subjectNewList, this.subjectOldList);

        if (this.subjectOldList.length < subjectNewList.length){
          isAdd = true;
          allowedRoles = subjectNewList.filter(role => !this.subjectOldList.some(present => present.subject_uid === role.subject_uid));
        }else if (this.subjectOldList.length > subjectNewList.length){
          isAdd = false;
          allowedRoles = this.subjectOldList.filter(role => !subjectNewList.some(present => present.subject_uid === role.subject_uid));
        }else{
          allowedRoles = subjectNewList.filter(role => !this.subjectOldList.some(present => present.subject_uid === role.subject_uid));
        }
        // if (allowedRoles != null){
        //
        //   console.log(allowedRoles);
        //   this.CloneAndAddSeat(allowedRoles, isAdd);
        // }
        this.CloneAndAddSeat(allowedRoles, isAdd);
        const form1 = this.setexamform.getRawValue();
        form1.testing_periods = form1.testing_periods.filter((member) => {
          return member.is_check === true;
        });
        console.log(form1);
        console.log(form1.testing_information_uid);
        this.swSV.confirmSubject().pipe(
          filter(x => x.isConfirmed),
          concatMap(x => {
            return this.TestInformationSV.update2(form1).pipe(
              tap(x => this.swSV.updateSuccess()),
              tap(x => console.log(x)),
              tap(x => window.history.back()),
              catchError(err => {
                this.swSV.err();
                return throwError(err);
              })
            );
          })
        ).subscribe();
        // const form1 = this.setexamform.getRawValue();
        // form1.testing_periods = form1.testing_periods.filter((member) => {
        //   return member.is_check === true;
        // });
        // this.TestInformationSV.update2(form1).pipe(
        //   tap(x => this.swSV.updateSuccess()),
        //   tap(x => window.history.back()),
        //   catchError(err => {
        //     this.swSV.err();
        //     return throwError(err);
        //   })
        // ).subscribe();
        break;
    }
  }

  ClearSubjectBefore(New, Old){
    let SubjectOldinNew = [];
    SubjectOldinNew = New.filter((el) => {
      return Old.some((f) => {
        return f.subject_uid === el.subject_uid;
      });
    });
    console.log(SubjectOldinNew);
    if (SubjectOldinNew.length !== 0){
      const form = this.setexamform.get('testing_rooms') as FormArray;
      const data = form.getRawValue();
      for (let i = 0; i < data.length; i++) {
        console.log(1);
        const formArray = form.controls[i].get('testing_seats') as FormArray;
        for (let j = 0; j < data[i].testing_seats.length; j++){
          console.log(2);
          const seatandsubject = data[i].testing_seats[j];
          const formArraySeatSubject = formArray.controls[j].get('testing_seat_subjects') as FormArray;
          const SubjectForm = formArraySeatSubject.getRawValue();
          console.log(SubjectForm);
          console.log(SubjectOldinNew);
          const arr = [];
          for (let k = 0; k < SubjectOldinNew.length; k++){
            const index = SubjectForm.findIndex(x => {
              return x.subject_uid !== SubjectOldinNew[k].subject_uid;
            });
            if (index != -1){
              arr.push(index);
            }
            // console.log(formArraySeatSubject.getRawValue());
            // const SubjectIndex = data[i].testing_seats[j].testing_seat_subjects[k];
            // console.log(SubjectOldinNew);
            // console.log(SubjectIndex);
            // const someResult = SubjectOldinNew.some((member) => {
            //   return member.subject_uid === SubjectIndex.subject_uid
            // });
            // if (someResult === true){
            //   formArraySeatSubject.removeAt(k)
            // }
          }
          this.removeForm(formArraySeatSubject, arr);
        }
      }
    }else {
      console.log(New);
    }
    // allowedRoles = New.filter((word.subject_uid) => !Old.includes(word.subject_uid));
    // allowedRoles = Old.filter(role => New.some(present => present.subject_uid === role.subject_uid));

  }

  removeForm(form, array){
    const reverse = array.reverse()
    for (let a = 0 ; a < reverse.length; a++){
      console.log(reverse[a]);
      // form.removeAt(reverse[a])
    }
  }

  checkDuplicate2(arr){
    const isDupicate = arr.
    map((value) => {
      return value.testing_datetime.getTime() + value.period_id;
    }).some((value, index, array) => {
      return array.indexOf(value) !== array.lastIndexOf(value);
    });
    return !isDupicate;
  }

  CloneAndAddSeat(SubjectDiffList, isAdd){
    const form = this.setexamform.get('testing_rooms') as FormArray;
    const data = form.getRawValue();
    if (isAdd === true){
      for (let i = 0; i < data.length; i++) {
        const formArray = form.controls[i].get('testing_seats') as FormArray;
        for (let j = 0; j < data[i].testing_seats.length; j++){
          const seatandsubject = data[i].testing_seats[j];
          const formArraySeatSubject = formArray.controls[j].get('testing_seat_subjects') as FormArray;
          for (let k = 0; k < SubjectDiffList.length; k++){
            console.log(SubjectDiffList[k]);
            formArraySeatSubject.push(this.testing_seat_subjects(SubjectDiffList[k]));
            // for (let h = 0; h < SubjectDiffList.length; h++){
            //   formArraySeatSubject.push(this.testing_seat_subjects(SubjectDiffList[h]));
            // }
          }
        }
      }
    }else if (isAdd === false) {
      console.log(11111)
      for (let i = 0; i < data.length; i++) {
        const formArray = form.controls[i].get('testing_seats') as FormArray;
        for (let j = 0; j < data[i].testing_seats.length; j++){
          const seatandsubject = data[i].testing_seats[j];
          formArray.at(i).get('is_specify_subject').setValue(false);
          const formArraySeatSubject = formArray.controls[j].get('testing_seat_subjects') as FormArray;
          for (let k = 0; k < data[i].testing_seats[j].testing_seat_subjects.length; k++){
            for (let h = 0; h < SubjectDiffList.length; h++){
              if (data[i].testing_seats[j].testing_seat_subjects[k].subject_uid === SubjectDiffList[h].subject_uid){
                formArraySeatSubject.reset();
              }
            }
          }
        }
      }
    }
  }

  checkSubjectAlready(seat, subject){
    const SubjectOld = seat.testing_seat_subjects;
    const SubjectChange = subject;
    const SubjectDiff = SubjectChange.filter(role => SubjectOld.some(present => present.subject_uid === role.subject_uid));
    console.log(SubjectDiff);
  }

}
