import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { Status } from '@app/core/common/enum/status';
import { DmpProfile, DmpProfileDefinition } from '@app/core/model/dmp-profile/dmp-profile';
import { DmpModel } from '@app/core/model/dmp/dmp';
import { DmpDynamicField } from '@app/core/model/dmp/dmp-dynamic-field';
import { DmpDynamicFieldDependency } from '@app/core/model/dmp/dmp-dynamic-field-dependency';
import { OrganizationModel } from '@app/core/model/organisation/organization';
import { ResearcherModel } from '@app/core/model/researcher/researcher';
import { UserModel } from '@app/core/model/user/user';
import { ValidJsonValidator } from '@app/library/auto-complete/auto-complete-custom-validator';
import { FunderFormModel } from '@app/ui/dmp/editor/grant-tab/funder-form-model';
import { GrantTabModel } from '@app/ui/dmp/editor/grant-tab/grant-tab-model';
import { ProjectFormModel } from '@app/ui/dmp/editor/grant-tab/project-form-model';
import { BackendErrorValidator } from '@common/forms/validation/custom-validator';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { ValidationContext } from '@common/forms/validation/validation-context';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties-form.model';
import { UserInfoListingModel } from '@app/core/model/user/user-info-listing';

export class DmpWizardEditorModel {
	public id: string;
	public label: string;
	public groupId: String;
	public profile: String;
	public version: number;
	public lockable: boolean;
	public creator: UserModel;
	public status: DmpStatus = DmpStatus.Draft;
	public description: String;
	public grant: GrantTabModel;
	public funder: FunderFormModel;
	public project: ProjectFormModel;
	public organisations: OrganizationModel[] = [];
	public researchers: ResearcherModel[] = [];
	public profiles: DmpProfile[] = [];
	public associatedUsers: UserModel[] = [];
	public users: UserInfoListingModel[] = [];
	public definition: DmpProfileDefinition;
	public dynamicFields: Array<DmpDynamicFieldEditorModel> = [];
	public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
	public extraProperties: ExtraPropertiesFormModel;

	fromModel(item: DmpModel): DmpWizardEditorModel {
		this.id = item.id;
		this.profile = item.profile;
		this.label = item.label;
		this.groupId = item.groupId;
		this.version = item.version;
		this.status = item.status;
		this.lockable = item.lockable;
		this.description = item.description;
		this.grant.fromModel(item.grant);
		this.project.fromModel(item.project);
		this.funder.fromModel(item.funder);
		this.organisations = item.organisations;
		this.researchers = item.researchers;
		this.profiles = item.profiles;
		this.associatedUsers = item.associatedUsers;
		this.users = item.users;
		if (item.definition) { this.definition = item.definition; }
		if (item.dynamicFields) { item.dynamicFields.map(x => this.dynamicFields.push(new DmpDynamicFieldEditorModel().fromModel(x))); }
		this.creator = item.creator;
		this.extraProperties.fromModel(item.extraProperties);
		return this;
	}

	buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup {
		if (context == null) { context = this.createValidationContext(); }

		const formGroup = new FormBuilder().group({
			id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators],
			profile: [{ value: this.profile, disabled: disabled }, context.getValidation('profile').validators],
			label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators],
			groupId: [{ value: this.groupId, disabled: disabled }, context.getValidation('groupId').validators],
			version: [{ value: this.version, disabled: disabled }, context.getValidation('version').validators],
			status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators],
			description: [{ value: this.description, disabled: disabled }],
			// grant: [{ value: this.grant, disabled: disabled }, context.getValidation('grant').validators],
			grant: this.grant.buildForm(),
			project: this.project.buildForm(),
			funder: this.funder.buildForm(),
			organisations: [{ value: this.organisations, disabled: disabled }, context.getValidation('organisations').validators],
			researchers: [{ value: this.researchers, disabled: disabled }, context.getValidation('researchers').validators],
			profiles: [{ value: this.profiles, disabled: disabled }, context.getValidation('profiles').validators],
			associatedUsers: [{ value: this.associatedUsers, disabled: disabled }, context.getValidation('associatedUsers').validators],
			users: [{ value: this.users, disabled: disabled }, context.getValidation('users').validators],
			extraProperties: this.extraProperties.buildForm(),
		});

		const dynamicFields = new Array<FormGroup>();
		if (this.dynamicFields) { this.dynamicFields.forEach(item => dynamicFields.push(item.buildForm())); }

		formGroup.addControl('dynamicFields', new FormBuilder().array(dynamicFields));

		return formGroup;
	}

	createValidationContext(): ValidationContext {
		const baseContext: ValidationContext = new ValidationContext();
		baseContext.validation.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] });
		baseContext.validation.push({ key: 'profile', validators: [BackendErrorValidator(this.validationErrorModel, 'profile')] });
		baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] });
		baseContext.validation.push({ key: 'groupId', validators: [BackendErrorValidator(this.validationErrorModel, 'groupId')] });
		baseContext.validation.push({ key: 'version', validators: [BackendErrorValidator(this.validationErrorModel, 'version')] });
		baseContext.validation.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] });
		baseContext.validation.push({ key: 'description', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'description')] });
		baseContext.validation.push({ key: 'grant', validators: [Validators.required, ValidJsonValidator, BackendErrorValidator(this.validationErrorModel, 'grant')] });
		baseContext.validation.push({ key: 'project', validators: [BackendErrorValidator(this.validationErrorModel, 'project')] });
		baseContext.validation.push({ key: 'funder', validators: [BackendErrorValidator(this.validationErrorModel, 'funder')] });
		baseContext.validation.push({ key: 'organisations', validators: [BackendErrorValidator(this.validationErrorModel, 'organisations')] });
		baseContext.validation.push({ key: 'researchers', validators: [BackendErrorValidator(this.validationErrorModel, 'researchers')] });
		baseContext.validation.push({ key: 'profiles', validators: [Validators.required, ValidJsonValidator, BackendErrorValidator(this.validationErrorModel, 'profiles')] });
		baseContext.validation.push({ key: 'associatedUsers', validators: [BackendErrorValidator(this.validationErrorModel, 'associatedUsers')] });
		baseContext.validation.push({ key: 'users', validators: [BackendErrorValidator(this.validationErrorModel, 'users')] });

		return baseContext;
	}
}

export class DmpDynamicFieldEditorModel {

	public id: string;
	public name: string;
	public required: boolean;
	public queryProperty;
	public value: string;
	public dependencies: Array<DmpDynamicFieldDependencyEditorModel> = [];

	fromModel(item: DmpDynamicField): DmpDynamicFieldEditorModel {
		this.id = item.id;
		this.name = item.name;
		this.required = item.required;
		this.value = item.value;
		this.queryProperty = item.queryProperty;
		if (item.dependencies) { item.dependencies.map(x => this.dependencies.push(new DmpDynamicFieldDependencyEditorModel().fromModel(x))); }
		return this;
	}

	buildForm(): FormGroup {
		const builder = new FormBuilder();
		const formGroup = builder.group({
			id: [this.id],
			name: [this.name],
			required: [this.required],
			value: [this.value],
			queryProperty: [this.queryProperty],
			dependencies: [this.dependencies]
		});
		return formGroup;
	}
}

export class DmpDynamicFieldDependencyEditorModel {
	public id: string;
	public queryProperty: string;

	fromModel(item: DmpDynamicFieldDependency): DmpDynamicFieldDependencyEditorModel {
		this.id = item.id;
		this.queryProperty = item.queryProperty;
		return this;
	}

	buildForm(): FormGroup {
		return new FormBuilder().group({
			id: [this.id],
			queryProperty: [this.queryProperty]
		});
	}
}
