import { Location } from '@angular/common';
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable, throwError } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';
import { BaseForm, sortByProperty } from 'src/app/core/base/base-form';
import { BaseFormUid } from 'src/app/core/base/base-form-uid';
import { UserOpenidService } from 'src/app/core/service/openid/user.service';
import { ReportInvigilatorCostService } from 'src/app/core/service/report/invigilator-cost/report-invigilator-cost.service';
import { invigilatorCostService } from 'src/app/core/service/settingPayment/invigilator-cost.service';
import { AcademicSemesterService } from 'src/app/core/service/settings/academic-semester.service';
import { AcademicYearService } from 'src/app/core/service/settings/academic-year.service';
import { BranchService } from 'src/app/core/service/settings/branch.service';
import { SweetalertService } from 'src/app/core/service/sweetalert/sweetalert';
import { TestingInformationService } from 'src/app/core/service/testing-information/testing-information.service';

@Component({
    selector: 'app-invigilate-finance-form',
    templateUrl: './invigilate-finance-form.component.html',
    styleUrls: ['./invigilate-finance-form.component.scss'],
    // changeDetection: ChangeDetectionStrategy.OnPush
})
export class InvigilateFinanceFormComponent extends BaseFormUid implements OnInit {
    editName = true;
    formArray;
    academicSem$ = new Observable();
    academicYear$ = new Observable();
    branch$ = new Observable();
    testingInformationList$ = new Observable()
    user;
    constructor(
        public fb: FormBuilder,
        public router: Router,
        public location: Location,
        public activeroute: ActivatedRoute,
        private academicSemSV: AcademicSemesterService,
        private academicYearSV: AcademicYearService,
        private invigilatorCostSV: invigilatorCostService,
        private branchSV: BranchService,
        private swSV: SweetalertService,
        private cdr: ChangeDetectorRef,
        private userOpenidSV: UserOpenidService,
        private reportInvigilatorCostSV: ReportInvigilatorCostService,
        private testingInformationSV: TestingInformationService
    ) {
        super(router,activeroute,fb,location)
     }

    ngOnInit(): void {
        this.academicSem$ = this.academicSemSV.getAll()
        this.academicYear$ = this.academicYearSV.getAll()
        this.testingInformationList$ = this.testingInformationSV.getAll()
        this.userOpenidSV.getAll().pipe(tap(x => this.user = x)).subscribe()
        this.branch$ = this.branchSV.getAll()
        if(this.state == 'edit'){
            this.invigilatorCostSV.get(this.id).pipe(
                tap(x => this.setupForm(x)),
            ).subscribe()
        }
    }

    createForm(){
        const index = 0
        return this.fb.group({
            academic_semester_uid: [null,Validators.required],
            academic_year_uid: [null,Validators.required],
            status_id: null,
            created_by: null,
            created_datetime: new Date(),
            updated_by: null,
            updated_datetime: new Date(),
            deleted_by: null,
            deleted_datetime: null,
            invigilator_cost_uid: null,
            testing_information_uid : [null,Validators.required],
            branch_uid: [null,Validators.required],
            from_date: [null,Validators.required],
            to_date: [null,Validators.required],
            invigilator_cost_groups: this.fb.array([
                this.createArray(index)
            ])
        })
    }

    setupForm(x){
        this.form.patchValue(x)
        this.form.setControl('invigilator_cost_groups',this.fb.array(x.invigilator_cost_groups.map(x => this.createCostGroup(x))))
        this.cdr.detectChanges()
    }

    getDateBetween(startDate:Date,endDate: Date,includeEndDate?: boolean){
        const dates = [];
        const currentDate = new Date(startDate);
        const end = new Date(endDate);
        while (currentDate < end) {
            dates.push(new Date(currentDate));
            currentDate.setDate(currentDate.getDate() + 1);
        }
        if (includeEndDate) dates.push(end);
        return dates;
    }

    addDate(){
        // const getDatesBetween = (
        //     startDate: Date,
        //     endDate: Date,
        //     includeEndDate?: boolean,
        // ) => {
        //     const dates = [];
        //     const currentDate = new Date(startDate);
        //     const end = new Date(endDate);
        //     while (currentDate < end) {
        //         dates.push(new Date(currentDate));
        //         currentDate.setDate(currentDate.getDate() + 1);
        //     }
        //     if (includeEndDate) dates.push(end);
        //     return dates;
        // };
        if(this.form.get('from_date').value && this.form.get('to_date').value){
            let date_array = this.getDateBetween(this.form.get('from_date').value,this.form.get('to_date').value,true)
            const form = this.form.get('invigilator_cost_groups') as FormArray
            form.controls.map((x:any) => {
                x.controls.invigilator_cost_details.controls.map((cost: any) => {
                    cost.setControl('invigilator_cost_date_details',this.fb.array(date_array.map((date,index) => this.createCostDateDetails(date,index))))
                    this.cdr.detectChanges()
                })
            })
        }
    }

    addTab(){
        const form = this.form.get('invigilator_cost_groups') as FormArray
        const index = form.length
        form.push(this.createArray(index))
    }

    removeTab(i){
        const form = this.form.get('invigilator_cost_groups') as FormArray
        form.removeAt(i)
    }

    createArray(index){
        return this.fb.group({
            invigilator_group_name: 'PAGE '+ (index+1),
            status_id: null,
            created_by: null,
            created_datetime: null,
            updated_by: null,
            updated_datetime: null,
            deleted_by: null,
            deleted_datetime: null,
            invigilator_cost_group_uid: null,
            invigilator_cost_uid: null,
            invigilator_cost_details: this.fb.array([
                this.createsub()
            ])
        })
    }

    createCostDateDetails(data?,index?){
        return this.fb.group({
            invigilator_cost_date_detail_uid: null,
            invigilator_cost_detail_uid: null,
            row: index+1,
            invigilator_date: data,
            is_check: false
        })
    }

    updateCostDateDetails(x){
        return this.fb.group({
            invigilator_cost_date_detail_uid: x.invigilator_cost_date_detail_uid,
            invigilator_cost_detail_uid: x.invigilator_cost_detail_uid,
            row: x.row,
            invigilator_date: x.invigilator_date,
            is_check: x.is_check
        })
    }

    createsub(){
        return this.fb.group({
            invigilator_cost_detail_uid: null,
            invigilator_cost_group_uid: null,
            invigilator_code: [null],
            invigilator_uid: [null],
            invigilator_name: [null,Validators.required],
            amount: [null,Validators.required],
            total_amount: [null],
            other_cost: [null,Validators.required],
            invigilator_cost_date_details: this.fb.array([])
        })
    }

    addCostDetail(x){
        return this.fb.group({
            invigilator_cost_detail_uid: null,
            invigilator_cost_group_uid: null,
            invigilator_code: [null],
            invigilator_uid: [null],
            invigilator_name: [null,Validators.required],
            amount: [null,Validators.required],
            total_amount: [null],
            other_cost: [null,Validators.required],
            invigilator_cost_date_details: this.fb.array(x.map((a,index) => this.createCostDateDetails(a,index)))
        })
    }

    createCostDetail(x){
        return this.fb.group({
            invigilator_cost_detail_uid: x.invigilator_cost_detail_uid,
            invigilator_cost_group_uid: x.invigilator_cost_group_uid,
            invigilator_code: x.invigilator_code,
            invigilator_uid: x.invigilator_uid,
            invigilator_name: x.invigilator_name,
            amount: x.amount,
            total_amount: [x.total_amount],
            other_cost: [x.other_cost],
            invigilator_cost_date_details: this.fb.array(x.invigilator_cost_date_details.sort(sortByProperty('row')).map(a => this.updateCostDateDetails(a)))
        })
    }

    createCostGroup(x){
        return this.fb.group({
            invigilator_group_name: x.invigilator_group_name,
            status_id: x.status_id,
            created_by: x.created_by,
            created_datetime: x.e,
            updated_by: x.updated_by,
            updated_datetime: x.updated_datetime,
            deleted_by: x.deleted_by,
            deleted_datetime: x.deleted_datetime,
            invigilator_cost_group_uid: x.invigilator_cost_group_uid,
            invigilator_cost_uid: x.invigilator_cost_uid,
            invigilator_cost_details: this.fb.array(x.invigilator_cost_details.map(a => this.createCostDetail(a)))
        })
    }

    add(form,index){
        index = 1
        const arr = form.get('invigilator_cost_details') as FormArray
        let date_array = this.getDateBetween(this.form.get('from_date').value,this.form.get('to_date').value,true)
        arr.push(this.addCostDetail(date_array))
    }

    removeNameArr(index,x){
        const form = x.get('invigilator_cost_details') as FormArray
        form.removeAt(index)
    }

    export(){
        const form = this.form.getRawValue()
        window.open(this.reportInvigilatorCostSV.report(form.invigilator_cost_uid))
    }

    save(){
        const form = this.form.getRawValue()
        switch (this.state) {
            case 'edit':
                this.invigilatorCostSV.update2(form).pipe(
                    tap(x => this.swSV.updateSuccess()),
                    tap(x => window.history.back()),
                    catchError(err => {
                        this.swSV.err()
                        return throwError(err)
                    })
                ).subscribe()
                break;

            case 'add':
                this.invigilatorCostSV.add(form).pipe(
                    tap(x => this.swSV.saveSuccess()),
                    tap(x => window.history.back()),
                    catchError(err => {
                        this.swSV.err()
                        return throwError(err)
                    })
                ).subscribe()
                break;
        }
    }

    cancel(){
        this.location.back()
    }

}
