import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { ChangeDetectorRef, Inject, OnDestroy } from '@angular/core';
import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { FormArray, FormGroup } from '@angular/forms';
import { FieldEditorModel } from '@app/ui/admin/dataset-profile/admin/field-editor-model';
import { FieldSetEditorModel } from '@app/ui/admin/dataset-profile/admin/field-set-editor-model';
import { SectionEditorModel } from '@app/ui/admin/dataset-profile/admin/section-editor-model';
import { BaseComponent } from '@common/base/base.component';
import { Guid } from '@common/types/guid';
import { DragulaService } from 'ng2-dragula';
import { Subscription } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { ToCEntry, ToCEntryType } from '../../../table-of-contents/table-of-contents-entry';

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

export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnChanges, OnDestroy {
	// @Input() form: FormGroup;
	//@Input() dataModel: SectionEditorModel;
	// @Input() indexPath: string;
	@Input() viewOnly: boolean;
	// @Input() numbering: string;
	@Input() tocentry: ToCEntry;

	@Output() selectedEntryId = new EventEmitter<string>();
	@Output() dataNeedsRefresh = new EventEmitter<void> ();
	@Output() removeFieldSet = new EventEmitter<string>();
	@Output() addNewFieldSet = new EventEmitter<FormGroup>();
	@Output() cloneFieldSet = new EventEmitter<FormGroup>();


	// FIELDSET_PREFIX_ID="FIELDSET_PREFIX_ID";

	// @Output() fieldsetAdded = new EventEmitter<String>(); //returns the id of the fieldset added
	idprefix = "id";
	private subs = new Subscription();
	private FIELDSETS = 'FIELDSETS';
	constructor(
		private dragulaService: DragulaService,
		private myElement: ElementRef
	) 
	{ 
		if(this.dragulaService.find(this.FIELDSETS)){
			this.dragulaService.destroy(this.FIELDSETS);	
		}


		this.dragulaService.createGroup(this.FIELDSETS,{
			moves:(el, container, handle)=>{
				// if(this.viewOnly) return false; //uncomment if want to unable drag n drop in viewonly mode
				if(el.id != (this.idprefix+this.tocentry.id)) return false;
				if(handle.className && handle.classList.contains('handle')) return true;
				return false;
			}
		});
		this.subs.add(this.dragulaService.drop(this.FIELDSETS).subscribe(obs=>{


			(this.form.get('fieldSets') as FormArray).controls.forEach((e,i)=>{
				e.get('ordinal').setValue(i);
			});


			// obs.
			this.dataNeedsRefresh.emit();
			return ;
		}));
	
	}
	ngOnDestroy(){
		// console.log('elemement destroyed -->');
		
		this.subs.unsubscribe();
	}
	ngOnChanges(changes: SimpleChanges): void {
		// console.log('---------element updated-------');
		// console.log('numbering before:', this.numbering);
		
		
		this.initialize();
		// console.log('----post update----');
		// console.log('numbering now', this.numbering, ' changes detected:', changes);
		
		
	}


	form;
	numbering;



	private _selectedFieldSetId: string = null;
	get selectedFieldSetId(){
		return this._selectedFieldSetId;
	}
	set selectedFieldSetId(id: string){

		if(id === this._selectedFieldSetId) return;
		this._selectedFieldSetId = id;
		this.selectedEntryId.emit(this._selectedFieldSetId);
	}

	private _findParentSection():FormGroup{
		const parent = this.form.parent;

		return parent;
	}


	private initialize(){
		if(this.tocentry.type === ToCEntryType.Section){
			this.form = this.tocentry.form;
			this.numbering = this.tocentry.numbering;
			this._selectedFieldSetId = null;

			this._scrollToElement(this.tocentry.id);
		}else if(this.tocentry.type === ToCEntryType.FieldSet){
			this.form = this.tocentry.form.parent.parent;
			const numberingArray = this.tocentry.numbering.split('.');
			if(numberingArray.length){
				numberingArray.splice(numberingArray.length-1);
				this.numbering = numberingArray.join('.');
			}else{
				// console.warn('!not found numbering');
			}
			this.selectedFieldSetId = this.tocentry.id;

			this._scrollToElement(this.selectedFieldSetId);
		}else{//scroll on top
			this._scrollOnTop();
		}
	}

	private _scrollToElement(id: string){
		let el = this.myElement.nativeElement.querySelector("#"+this.idprefix+id);
			// let el = this.myElement.nativeElement.getElementbyId (this.selectedFieldSetId);
			
		if(el){

			/*
				Give time to template to build itself (extending and collapsing).
				In case we are dragging from one container to another, then  the ui takes around 600ms to build 
				individual previews (dataset-profile-editor-field.component.ts);

			*/
			setTimeout(() => {
				const el = this.myElement.nativeElement.querySelector("#"+this.idprefix+id);
				if(el){
					el.scrollIntoView({behavior: "smooth"});
				}
			}, 700);
		}

	}
	private _scrollOnTop(){
		setTimeout(() => {
			const el = this.myElement.nativeElement.querySelector('#topofcontainer');
			if(el){
				el.scrollIntoView({behavior:'smooth'})
			}
		},200);

	}
	ngOnInit() {

		// console.log('<-- element created');
		// this.initialize();
		


		//TODO 
		// this.form.root.get('pages').valueChanges
		// 	.pipe(takeUntil(this._destroyed))
		// 	.subscribe(x =>
		// 		this.keepPageSelectionValid(x)
		// 	);
	}

	drop(event: CdkDragDrop<string[]>) {
		// if(!this.links || !this.links.length) return;

		if(event.container === event.previousContainer){
			// moveItemInArray(this.links, event.previousIndex, event.currentIndex);
	
			let arrayToUpdate: FormArray = this.form.get('fieldSets') as FormArray;
			// if(this.parentLink && this.parentLink.form){
			// 	switch(this.parentLink.subEntriesType){
			// 		case this.tocEntryType.Field: 
			// 			arrayToUpdate = (this.parentLink.form.get('fields') as FormArray);
			// 			break;
			// 		case this.tocEntryType.FieldSet: 
			// 			arrayToUpdate = (this.parentLink.form.get('fieldSets') as FormArray);
			// 			break;
			// 		case this.tocEntryType.Section: 
			// 			arrayToUpdate = (this.parentLink.form.get('sections') as FormArray);
			// 			break
			// 	}
				
			// }
			if(arrayToUpdate.controls){
				moveItemInArray(arrayToUpdate.controls, event.previousIndex, event.currentIndex);
				//update ordinality
				arrayToUpdate.controls.forEach((element,idx ) => {
					element.get('ordinal').setValue(idx);
					element.updateValueAndValidity();
				});
			}
	
			this.dataNeedsRefresh.emit();
		}else{
			console.log('not same container');
		}

	}


	onRemoveFieldSet(fieldsetId: string){
		this.removeFieldSet.emit(fieldsetId);
	}

	onCloneFieldSet(fieldset: FormGroup){
		this.cloneFieldSet.emit(fieldset);
	}
	onAddFieldSet(){
		this.addNewFieldSet.emit(this.form);
	}


	// addField() {
	// 	const fieldSet: FieldSetEditorModel = new FieldSetEditorModel();
	// 	fieldSet.ordinal = (this.form.get('fieldSets') as FormArray).length;

	// 	const field: FieldEditorModel = new FieldEditorModel();
	// 	field.id = Guid.create().toString();
	// 	field.ordinal = 0;//first field in fields
	// 	fieldSet.fields.push(field);
	// //	if (this.dataModel.fieldSets) {
	// 		fieldSet.id = Guid.create().toString();
	// 		//this.dataModel.fieldSets.push(fieldSet);
	// 	//}
	// 	const fieldsetsArray = this.form.get('fieldSets') as FormArray;
	// 	fieldsetsArray.push(fieldSet.buildForm());

	// 	const fieldSetForm = fieldsetsArray.at(fieldsetsArray.length-1);
	// 	//emit id inserted
	// 	if(fieldSetForm){
	// 		const id: string = fieldSetForm.get('id').value;
	// 		this.fieldsetAdded.emit(id);
	// 	}
	// }

	// addSectioninSection() {
	// 	const section: SectionEditorModel = new SectionEditorModel();
	// 	//this.dataModel.sections.push(section);
	// 	(<FormArray>this.form.get('sections')).push(section.buildForm());
	// }

	// DeleteSectionInSection(index) {
	// 	//this.dataModel.sections.splice(index, 1);
	// 	(<FormArray>this.form.get('sections')).removeAt(index);
	// }

	// deleteFieldSet(index) {
	// 	//this.dataModel.fieldSets.splice(index, 1);
	// 	(<FormArray>this.form.get('fieldSets')).removeAt(index);
	// }

	// keepPageSelectionValid(pagesJson: Array<any>) {
	// 	const selectedPage = this.form.get('page').value as String;
	// 	// const pages: Array<PageEditorModel> = JsonSerializer.fromJSONArray(pagesJson, Page);
	// 	if (pagesJson.find(elem => elem.id === selectedPage) === undefined) {
	// 		this.form.get('page').reset();
	// 	}
	// }

	// getFieldTile(formGroup: FormGroup, index: number) {
	// 	if (formGroup.get('title') && formGroup.get('title').value && formGroup.get('title').value.length > 0) { return formGroup.get('title').value; }
	// 	return "Field " + (index + 1);
	// }
	private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{
		if(!tocentries){
			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;
	}
}
