
import { Component, OnInit, ViewChild } from '@angular/core';
import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatStepper } from '@angular/material/stepper';
import { Router } from '@angular/router';
import { DatasetStatus } from '@app/core/common/enum/dataset-status';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DatasetService } from '@app/core/services/dataset/dataset.service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { QuickWizardService } from '@app/core/services/quick-wizard/quick-wizard.service';
import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate.component';
import { DmpFinalizeDialogComponent, DmpFinalizeDialogDataset, DmpFinalizeDialogInput } from '@app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component';
import { FunderFormModel } from '@app/ui/dmp/editor/grant-tab/funder-form-model';
import { ProjectFormModel } from '@app/ui/dmp/editor/grant-tab/project-form-model';
import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
import { IBreadCrumbComponent } from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent';
import { DatasetEditorWizardComponent } from '@app/ui/quick-wizard/dataset-editor/dataset-editor-wizard.component';
import { GrantEditorWizardModel } from '@app/ui/quick-wizard/grant-editor/grant-editor-wizard-model';
import { QuickWizardEditorWizardModel } from '@app/ui/quick-wizard/quick-wizard-editor/quick-wizard-editor.model';
import { FormService } from '@common/forms/form-service';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { TranslateService } from '@ngx-translate/core';
import { Observable, of as observableOf } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
	selector: 'app-quick-wizard-editor-component',
	templateUrl: 'quick-wizard-editor.component.html',
	styleUrls: ['./quick-wizard-editor.component.scss']
})
export class QuickWizardEditorComponent extends CheckDeactivateBaseComponent implements OnInit, IBreadCrumbComponent {

	breadCrumbs: Observable<BreadcrumbItem[]> = observableOf([]);
	@ViewChild('stepper', { static: true }) stepper: MatStepper;
	@ViewChild(DatasetEditorWizardComponent) datasetEditorWizardComponent: DatasetEditorWizardComponent;
	isNew = true;
	isSubmitted = false;
	quickWizard: QuickWizardEditorWizardModel;
	allDatasets: DmpFinalizeDialogDataset[] = [];
	formGroup: FormGroup = null;

	constructor(
		public snackBar: MatSnackBar,
		public router: Router,
		public language: TranslateService,
		public datasetService: DatasetService,
		public quickWizardService: QuickWizardService,
		private uiNotificationService: UiNotificationService,
		private dialog: MatDialog,
		private formService: FormService
	) {
		super();
	}

	ngOnInit(): void {
		this.quickWizard = new QuickWizardEditorWizardModel();
		this.quickWizard.grant = new GrantEditorWizardModel();
		this.quickWizard.funder = new FunderFormModel();
		this.quickWizard.project = new ProjectFormModel();
		this.formGroup = this.quickWizard.buildForm();
		this.language.get('NAV-BAR.DMP-WIZARD').pipe(takeUntil(this._destroyed)).subscribe(x => {
			this.breadCrumbs = observableOf([
				{
					parentComponentName: 'Dashboard',
					label: x,
					url: '/quick-wizard'
				}]
			);
		})
	}

	isActive(step: string): boolean {
		switch (step) {
			case 'step1':
				return this.stepper.selectedIndex == 0;
			case 'step2':
				return this.stepper.selectedIndex == 1;
			case 'step3':
				return this.stepper.selectedIndex == 2;
		}
	}

	formSubmit(): void {
		this.formService.touchAllFormFields(this.formGroup);
		if (this.formGroup.get('datasets') && this.formGroup.get('datasets').get('datasetsList') && (this.formGroup.get('datasets').get('datasetsList') as FormArray).length > 0) {
			for (let control of (this.formGroup.get('datasets').get('datasetsList') as FormArray).controls) {
				control.get('status').setValue(DatasetStatus.Draft);
			}
			this.onSubmitSave();
		} else {
			this.uiNotificationService.popupNotification(this.language.instant('GENERAL.NOTIFICATION-DIALOG.POPUP.TITLE'), this.language.instant('GENERAL.NOTIFICATION-DIALOG.POPUP.MESSAGE'));
			return;
		}
	}

	saveFinalize() {
		if (!this.isFormValid()) { return; }

		const dialogInputModel: DmpFinalizeDialogInput = {
			dmpLabel: this.formGroup.get('dmp').get('label').value,
			dmpDescription: this.formGroup.get('dmp').get('description').value,
			datasets: (this.formGroup.get('datasets').get('datasetsList') as FormArray).controls.map(x => {
				return { label: x.get('datasetLabel').value, status: DatasetStatus.Finalized };
			})
		}

		const dialogRef = this.dialog.open(DmpFinalizeDialogComponent, {
			maxWidth: '500px',
			restoreFocus: false,
			autoFocus: false,
			data: {
				dialogInputModel: dialogInputModel,
				confirmButton: this.language.instant('DMP-FINALISE-DIALOG.SUBMIT'),
				cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
			}
		});
		dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
			if (result && !result.cancelled) {
				if (this.formGroup.get('datasets') && this.formGroup.get('datasets').get('datasetsList') && (this.formGroup.get('datasets').get('datasetsList') as FormArray).length > 0) {
					for (let control of (this.formGroup.get('datasets').get('datasetsList') as FormArray).controls) {
						control.get('status').setValue(DatasetStatus.Finalized);
					}
					this.formGroup.get('dmp').get('status').setValue(DmpStatus.Finalized);
					this.onSubmitSaveAndFinalize();
				} else {
					this.uiNotificationService.popupNotification(this.language.instant('GENERAL.NOTIFICATION-DIALOG.POPUP.TITLE'), this.language.instant('GENERAL.NOTIFICATION-DIALOG.POPUP.MESSAGE'));
				}
			}
		});
	}

	hasDatasets() {
		return this.formGroup.get('datasets').get('datasetsList').valid;
	}

	public isFormValid() {
		return this.formGroup.get('grant').valid && this.formGroup.get('funder').valid;
	}

	onSubmitSaveAndFinalize() {
		this.quickWizardService.createQuickWizard(this.formGroup.getRawValue())
			.pipe(takeUntil(this._destroyed))
			.subscribe(
				complete => this.onCallbackSuccess(),
				error => this.onCallbackError(error)
			);
	}

	onSubmitSave(): void {
		const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
			restoreFocus: false,
			data: {
				message: this.language.instant('QUICKWIZARD.SAVE-DIALOG.TITLE'),
				confirmButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.AFFIRMATIVE'),
				cancelButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.NEGATIVE'),
				isDeleteConfirmation: false
			}
		});
		dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
			if (result) {
				this.datasetEditorWizardComponent.addDataset(false);
			} else if (result === false) {
				this.quickWizardService.createQuickWizard(this.formGroup.value)
					.pipe(takeUntil(this._destroyed))
					.subscribe(
						complete => this.onCallbackSuccess()
					)
			}
		});
	}

	onCallbackSuccess(): void {
		this.isSubmitted = true;
		this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
		this.router.navigate(['/home']);
	}

	onCallbackError(errorResponse: any) {
		this.setErrorModel(errorResponse.error.payload);
		this.formService.validateAllFormFields(this.formGroup);
	}

	public setErrorModel(validationErrorModel: ValidationErrorModel) {
		Object.keys(validationErrorModel).forEach(item => {
			(<any>this.quickWizard.validationErrorModel)[item] = (<any>validationErrorModel)[item];
		});
	}

	getGrantLabel(): string {
		if (this.formGroup.get('grant').get('existGrant').value) {
			return this.formGroup.get('grant').get('existGrant').value['label'];
		} else {
			return this.formGroup.get('grant').get('label').value;
		}
	}

	canDeactivate(): boolean {
		return this.isSubmitted || !this.formGroup.dirty;
	}

}
