import {Component, EventEmitter, Inject, OnInit, Output, Input, ViewChildren, QueryList} from '@angular/core';
import { SimpleChanges } from '@angular/core';
import { FormArray } from '@angular/forms';
import { ToCEntry, ToCEntryType } from '../../dataset-description.component';
import { VisibilityRulesService } from '../../visibility-rules/visibility-rules.service';

@Component({
	selector: 'table-of-contents-internal',
	styleUrls: ['./table-of-contents-internal.scss'],
	templateUrl: './table-of-contents-internal.html'
})
export class TableOfContentsInternal implements OnInit {

	@Input() tocentries: ToCEntry[] = null;
	@Input() selected: ToCEntry = null;
	// @Input() visibilityRules:Rule[] = [];
	@Output() entrySelected = new EventEmitter<ToCEntry>();

	expandChildren:boolean[];
	tocEntryTypeEnum = ToCEntryType;
	@Input() TOCENTRY_ID_PREFIX="";
	@Input() showErrors: boolean = false;
	@Input() hiddenEntries: string[] =[];
	@Input() visibilityRulesService: VisibilityRulesService;
	@ViewChildren(TableOfContentsInternal) internalTables: QueryList<TableOfContentsInternal>;

	constructor(){
	}
	ngOnInit(): void {
		// console.log('component created');
		if(this.tocentries){
			this.expandChildren = this.tocentries.map(()=>false);
			if(this.selected){
				for(let i=0; i<this.tocentries.length;i++ ){
					if(this._findTocEntryById(this.selected.id, this.tocentries[i].subEntries)){
						if(this.expandChildren){
							this.expandChildren[i] = true;
						}
						break;
					}
				}
			}
		}
	}

	ngOnChanges(changes: SimpleChanges) {
		if(changes.selected && this.selected){
			for(let i=0; i<this.tocentries.length;i++ ){
				if(this._findTocEntryById(this.selected.id, this.tocentries[i].subEntries)){
					if(this.expandChildren){
						this.expandChildren[i] = true;
					}
					break;
				}
			}
		}
		// if (!this.isActive && this.links && this.links.length > 0) {
		// 	this.links.forEach(link => {
		// 		link.selected = false;
		// 	})
		// 	this.links[0].selected = true;
		// }
	}

	toggleExpand(index){
		this.expandChildren[index] = !this.expandChildren[index];
		// console.log(this.expandChildren);
	}

	navigateToFieldSet(entry:ToCEntry, event){
		if(entry.type === ToCEntryType.FieldSet){

			const fieldSetId = entry.id;
			const element = document.getElementById(this.TOCENTRY_ID_PREFIX+fieldSetId);
			if(element){
				element.click();//open mat expansion panel

				//scroll asyn in 200 ms so the expansion panel is expanded and the element coordinates are updated
				setTimeout(() => {
					const element = document.getElementById(this.TOCENTRY_ID_PREFIX+fieldSetId);
					if(element){
						element.scrollIntoView({behavior:'smooth'});
					}
				}, 300);
			}

		}
	}


	onEntrySelected(entry:ToCEntry){
		this.entrySelected.emit(entry);
	}


	calculateStyle(entry: ToCEntry){
		const style = {};
		style['font-size'] = entry.type ===this.tocEntryTypeEnum.FieldSet? '.9em': '1em';
		return style;
	}

	calculateClass(entry:ToCEntry){
		const myClass= {};

		if(this.selected && entry.id === this.selected.id){
			myClass['selected'] = true;
		}

		if(entry.type != this.tocEntryTypeEnum.FieldSet){
			myClass['section'] = true;
		}

		return myClass;
	}

	private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{
		if(!tocentries || !tocentries.length){
			return null;
		}

		let tocEntryFound = tocentries.find(entry=>entry.id === id);

		if(tocEntryFound){
			return tocEntryFound;
		}

		for(let entry of tocentries){
			const result = this._findTocEntryById(id, entry.subEntries);
			if(result){
				tocEntryFound = result;
				break;
			}
		}

		return tocEntryFound? tocEntryFound: null;
	}
	public invalidChildsVisible(entry: ToCEntry):boolean {
		if(!entry || !this.visibilityRulesService){
			return false;
		}

		if(entry.type!= this.tocEntryTypeEnum.FieldSet){
			return entry.subEntries.some(_ => this.invalidChildsVisible(_));
		}
		if(entry.type === this.tocEntryTypeEnum.FieldSet){
			const id = entry.form.get('id').value
			if(!this.visibilityRulesService.checkElementVisibility(id)){
				return false;
			}
			const fieldsArray = entry.form.get('fields') as FormArray;
			const hasError = !fieldsArray.controls.every(field=>{//every invalid field should be invisible
				if(field.invalid){
					const id = field.get('id').value;
					const isVisible = this.visibilityRulesService.checkElementVisibility(id);
					if(isVisible){
						return false;
					}
				}
				return true;
			});
			return hasError;
		}
		return false;
	}
}
