import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { FormArray, FormControl, FormGroup } from '@angular/forms';
import { DatasetProfileFieldViewStyle } from '../../../../../../core/common/enum/dataset-profile-field-view-style';
import { DatasetProfileComboBoxType } from '../../../../../../core/common/enum/dataset-profile-combo-box-type';
import { ToCEntryType } from '../../../table-of-contents/table-of-contents-entry';
import { Rule } from '@app/core/model/admin/dataset-profile/dataset-profile';
import { TranslateService } from '@ngx-translate/core';

@Component({
	selector: 'app-dataset-profile-editor-rule-component',
	templateUrl: './dataset-profile-editor-rule.component.html',
	styleUrls: ['./dataset-profile-editor-rule.component.scss']
})

export class DatasetProfileEditorRuleComponent implements OnInit {
	
	
	@Input() form: FormArray;
	
	@Input() viewStyleForCheck: DatasetProfileFieldViewStyle;
	@Input() formControlForCheck: FormControl;
	@Input() formArrayOptionsForCheck: FormArray;
	@Input() comboBoxTypeForCheck: DatasetProfileComboBoxType;
	@Input() viewOnly: boolean;
	

	options: OptionItem[];
	sectionOptions: OptionItem[];
	fieldSetOptions: OptionItem[];
	fieldOptions: OptionItem[];

	parentIds: string[] = [];
	hiddenBy: string[] = [];

	constructor(private language: TranslateService){

	}

	targetValidation() {
		//TODO
	}
	
	deleteRule(index) {
		this.form.removeAt(index);
		this.form.markAsDirty();//deactivate guard
	}

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

	private _computeOptions(){
		this.options = this.getOptions();

		this.sectionOptions = [];
		this.fieldOptions = [];
		this.fieldSetOptions = [];
		this.options.forEach(option=>{
			switch (option.type) {
				case ToCEntryType.Field:
					this.fieldOptions.push(option);
					break;
				case ToCEntryType.FieldSet:
					this.fieldSetOptions.push(option);
					break;
				case ToCEntryType.Section:
					this.sectionOptions.push(option);
					break;
				default:
					break;
			}
		});
		//remove options to hide if given fieldset is already hidden by option

		this.fieldOptions.forEach(e=>this._buildHiddenBy(e));
		this.fieldSetOptions.forEach(e=>this._buildHiddenBy(e));
		this.parentIds = this.computeParentIds();
		this.hiddenBy = this.computeHiddenBy();
	}



	computeOptions(isOpened: boolean){
		if(isOpened){
			this._computeOptions();
		}
	}

	private _buildHiddenBy(fo:OptionItem){
		try{
			this.fieldOptions.forEach(foption=>{
				const rules = (foption.form.get('visible').get('rules') as FormArray).controls.map(c=>(c as FormGroup).getRawValue()) as Rule[]
				const targets = rules.map(rule=>rule.target);
				targets.forEach(target=>{
					if(fo.parentsIds.includes(target) && !fo.hiddenBy.includes(foption.id)){
						fo.hiddenBy.push(...foption.parentsIds);
					}
				})

			});
		}catch{
			console.log('error');
		}
	}





	getOptions():OptionItem[]{
		const rootForm = this.form.root;
		if(rootForm){
			// const parentSections = rootForm.get('sections') as FormArray;

			const result:OptionItem[] =[];

			const sections = rootForm.get('sections') as FormArray;

			if(sections){
				sections.controls.forEach(section=>{
					const subResult = this.buildOptions(section as FormGroup, ToCEntryType.Section,[]);
					result.push(...subResult);
				});
			}

			//return options
			return result;

		}
		//nothing found
		return [];
	}

	private buildOptions(form: FormGroup, type: ToCEntryType, parentIds:string[]):OptionItem[]{
		
		const sections = form.get('sections') as FormArray;
		const fieldSets =  form.get('fieldSets') as FormArray;
		const fields = form.get('fields') as FormArray;

		const result:OptionItem[] = []; 

		// parentIds.push(form.get('id').value);
		const currentOptionItem:OptionItem = {
			id: form.get('id').value,
			type: type,
			label: type ===ToCEntryType.Field? form.get('data').get('label').value :form.get('title').value,
			// parentsIds: [form.get('id').value]
			parentsIds: [...parentIds, form.get('id').value],
			form: form,
			hiddenBy:[]
		}
		result.push(currentOptionItem);

		if(sections){
			sections.controls.forEach(section=>{
				result.push( ...this.buildOptions(section as FormGroup, ToCEntryType.Section, currentOptionItem.parentsIds) );
			});
		}
		if(fieldSets){
			fieldSets.controls.forEach(fieldset=>{
				result.push( ...this.buildOptions(fieldset as FormGroup, ToCEntryType.FieldSet, currentOptionItem.parentsIds) );
			});
		}
		if(fields){
			fields.controls.forEach(field=>{
				result.push( ...this.buildOptions(field as FormGroup, ToCEntryType.Field, currentOptionItem.parentsIds) ); //TODO NA TO DOUME
			});
		}

		return result;
	}

	// get parentIds(): string[]{

		
	// }
	// get hiddenBy(): string[]{
		
	// }

	computeParentIds(): string[]{
		if(!this.formControlForCheck.get('id')) return [];

		const current = this.options.find(opt=> opt.id === this.formControlForCheck.get('id').value);

		if(current){
			return current.parentsIds;
		}
		return [];
	}

	computeHiddenBy(): string[]{
		if(!this.formControlForCheck.get('id')) return [];
	
		const current = this.options.find(opt=> opt.id === this.formControlForCheck.get('id').value);
	
		if(current){
			return current.hiddenBy;
		}
		return [];
	}

	getToolTipMessage(id: string){
		if(this.parentIds.includes(id)){
			// return 'Cannot hide element that contain the field';
			return  this.language.instant('DATASET-PROFILE-EDITOR.STEPS.FORM.RULE.HINTS.ELEMENT-CHILD-OF-TARGET');
		}else if(this.hiddenBy.includes(id)){
			return  this.language.instant('DATASET-PROFILE-EDITOR.STEPS.FORM.RULE.HINTS.ELEMENT-HIDDEN-FROM-ELEMENT');
		}
		return '';
	}

}


interface OptionItem{
	id: string,
	label: string,
	type: ToCEntryType,
	parentsIds: string[],
	form:FormGroup,
	hiddenBy:string[]
}