import {HttpClient} from "@angular/common/http";
import {Component, OnDestroy, OnInit} from "@angular/core";
import {Subscription} from "rxjs";

import {Breadcrumb} from "../openaireLibrary/utils/breadcrumbs/breadcrumbs.component";
import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties";
import {properties} from "src/environments/environment";
import {FormBuilder, FormControl} from "@angular/forms";
import {ActivatedRoute, Router} from "@angular/router";
import {Meta, Title} from "@angular/platform-browser";
import {Location} from "@angular/common";
import {StringUtils} from "../openaireLibrary/utils/string-utils.class";
import {SEOService} from "../openaireLibrary/sharedComponents/SEO/SEO.service";
import {PiwikService} from "../openaireLibrary/utils/piwik/piwik.service";

@Component({
	selector: 'fos',
	templateUrl: 'fos.component.html',
	styleUrls: ['fos.component.css']
})
export class FosComponent implements OnInit, OnDestroy {
	public url: string = null;
	public pageTitle: string = "OpenAIRE | Fields of Science";
	public pageDescription: string = "We have integrated a Field-of-Science (FoS) taxonomy into our dataset to organize and discover research more effectively. Using the full capabilities of the OpenAIRE Research Graph (full-texts, citations, references, venues) we apply AI and bring forward any multidisciplinarity potential.";

	public fos: any[] = [];
	public fosOptions: string[] = [];
	public index: number = 0;

	public keywordControl: FormControl;
	public keyword: string = null;

	public viewResults = [];

	public result = [];

	properties: EnvProperties = properties;
	public breadcrumbs: Breadcrumb[] = [{name: 'home', route: '/'}, {name: 'Fields of Science'}];

	subscriptions: Subscription[] = [];

	constructor(
		private httpClient: HttpClient,
		private fb: FormBuilder,
		private location: Location,
		private route: ActivatedRoute,
		private _router: Router,
		private _meta: Meta,
		private _title: Title,
		private seoService: SEOService,
		private _piwikService: PiwikService
	) {}

	ngOnInit() {
		if (this.properties.enablePiwikTrack && (typeof document !== 'undefined')) {
      this.subscriptions.push(this._piwikService.trackView(this.properties, this.pageTitle, this.properties.piwikSiteId).subscribe());
    }
		this.url = this.properties.domain + this.properties.baseLink + this._router.url;
		this.seoService.createLinkForCanonicalURL(this.url);
		this.updateUrl(this.url);
    this.updateTitle(this.pageTitle);
    this.updateDescription(this.pageDescription);
		this.keywordControl = this.fb.control('');
		this.httpClient.get(properties.domain+'/assets/vocabulary/fos.json').subscribe(data => {
			this.fos = data['fos'];
			this.convertFosToOptions();
			this.subscriptions.push(this.route.queryParams.subscribe(params => {
				if(params.keyword) {
					this.keywordControl.setValue(params.keyword);
					this.keyword = this.keywordControl.value;
					this.findMatches();
				}
			}));
		});
	}

	public ngOnDestroy() {
    for (let sub of this.subscriptions) {
      sub.unsubscribe();
    }
  }

	changeDisplayedFos(i) {
		this.index = i;
	}

	onSubmit() {
		if(this.keywordControl.value) {
			this.keyword = this.keywordControl.value;
			// TODO: router.navigate();
			this.location.go(window.location.pathname + '?keyword=' + this.keyword);
			this.findMatches();
		}
	}
	
	convertFosToOptions() {
		this.fosOptions = [];
		this.fos.forEach(fos => {
			this.fosOptions.push(fos.id);
			if(fos.children) {
				fos.children.forEach(child => {
					this.fosOptions.push(child.id);
					if(child.children) {
						child.children.forEach(child2 => {
							this.fosOptions.push(child2.id);
						});
					}
				});
			}
		});
	}

	findMatches() {
		this.viewResults = JSON.parse(JSON.stringify(this.fos));
		let matchLevel1: boolean = false;
		let matchLevel2: boolean = false;
		// 1st level search
		if(this.viewResults.length) {
			this.viewResults = this.viewResults.filter(item => {
				if(item.id.includes(this.keyword.toLowerCase())) {
					matchLevel1 = true;
				} else {
					matchLevel1 = false;
				}
				// // 2nd level search
				if(item.children?.length && !matchLevel1) {
					item.children = item.children.filter(subItem => {
						if(subItem.id.includes(this.keyword.toLowerCase())) {
							matchLevel2 = true;
						} else {
							matchLevel2 = false;
						}
						// 3rd level search
						if(subItem.children?.length && !matchLevel2) {
							subItem.children = subItem.children.filter(subSubItem => subSubItem.id.includes(this.keyword.toLowerCase()));
						}
						return subItem.children?.length > 0 || matchLevel2;
					});
				}
				return item.children?.length > 0;
			});
		}
	}

	highlightKeyword(name) {
		if(name.includes(this.keyword.toLowerCase())) {
			return name.replace(new RegExp(this.keyword, "gi"), (matchedValue) => `<mark class="highlighted">${matchedValue}</mark>`);
		} else {
			return name;
		}
	}

	clearKeyword() {
		this.keyword = null;
		this.keywordControl.setValue('');
		this.location.go(window.location.pathname);
	}

  public urlEncodeAndQuote(str: string): string {
    return StringUtils.quote(StringUtils.URIEncode(str));
  }

	private updateUrl(url: string) {
    this._meta.updateTag({content: url}, "property='og:url'");
  }

	private updateTitle(title: string) {
    var _title = ((title.length > 50) ? title.substring(0, 50) : title);
    this._title.setTitle(_title);
    this._meta.updateTag({content: _title}, "property='og:title'");
  }

	private updateDescription(description: string) {
    this._meta.updateTag({content: description}, "name='description'");
    this._meta.updateTag({content: description}, "property='og:description'");
  }
}