/** @file
 * @author Edouard DUPIN
 * @copyright 2018, Edouard DUPIN, all right reserved
 * @license PROPRIETARY (see license file)
 */

import { Injectable, Output, EventEmitter } from '@angular/core';

import { NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router';

import { TypeService } from './type';
import { SeriesService } from './series';
import { SeasonService } from './season';
import { MediaService } from './media';
import { environment } from 'environments/environment';
import { isNullOrUndefined, isStringNullOrUndefined, isUndefined } from '@kangaroo-and-rabbit/kar-cw';
import { Season } from 'app/back-api';

export class InputOrders {
	public typeId: number = undefined;
	public seriesId: number = undefined;
	public seasonId: number = undefined;
	public videoId: number = undefined;
}

@Injectable()
export class ArianeService {
	public typeId: number = undefined;
	public typeName: string = undefined;
	@Output() typeChange: EventEmitter<number> = new EventEmitter();

	public seriesId: number = undefined;
	public seriesName: string = undefined;
	@Output() seriesChange: EventEmitter<number> = new EventEmitter();

	public seasonId: number = undefined;
	public seasonName: string = undefined;
	@Output() seasonChange: EventEmitter<number> = new EventEmitter();

	public videoId: number = undefined;
	public videoName: string = undefined;
	@Output() videoChange: EventEmitter<number> = new EventEmitter();

	public segment: string = "";
	@Output() segmentChange: EventEmitter<string> = new EventEmitter();

	constructor(
		private router: Router,
		private MediaService: MediaService,
		private seasonService: SeasonService,
		private seriesService: SeriesService,
		private typeService: TypeService,
	) {
		let self = this;
		this.router.events.subscribe((event: any) => {
			if (event instanceof NavigationStart) {
				// Show progress spinner or progress bar
				//console.log('>>>>>>>>>>>>>> Route change detected');
			}

			if (event instanceof NavigationEnd) {
				// Hide progress spinner or progress bar
				//this.currentRoute = event.url;          
				//console.log(`>>>>>>>>>>>> ${event}`);
				self.updateProperties();
			}

			if (event instanceof NavigationError) {
				// Hide progress spinner or progress bar

				// Present error to user
				//console.log(`<<<<<<<<<<<<< ${event.error}`);
			}

		});
	}
	updateParams(params) {
		console.log(`sparams ${params}`);
		console.log(`sparams['typeId'] ${params.typeId}`);
		if (params.typeId) {
			this.setType(params.typeId);
		} else {
			this.setType(undefined);
		}
	}
	getCurrentSegment(): string | undefined {
		return this.segment;
	}

	getIsParam(params: any, name: string): undefined | number {
		let valueStr = params.get(name);
		if (isNullOrUndefined(valueStr) || isStringNullOrUndefined(valueStr)) {
			return undefined;
		}
		return parseInt(valueStr, 10);

	}

	updateProperties() {
		let elem = this.router.routerState.root;
		while (!isNullOrUndefined(elem.firstChild)) {
			elem = elem.firstChild;
		}
		//console.log(`!!!!!!!!!!!!!!!!!!!!!!!!!! ${JSON.stringify(elem.snapshot.paramMap)}`);
		let params = elem.snapshot.paramMap;
		let segment: string[] = location.pathname.split("/");
		while (segment.length > 1 && (segment[0] === "" || segment[0] === environment.applName)) {
			segment = segment.slice(1);
		}
		if (segment.length > 0) {
			if (this.segment !== segment[0]) {
				this.segment = segment[0];
				this.segmentChange.emit(this.segment)
			}
		} else {
			if (this.segment !== "") {
				this.segment = "";
				this.segmentChange.emit(this.segment)
			}
		}
		console.log(`segment: ${JSON.stringify(this.segment)}`);
		console.log(`params: ${JSON.stringify(params)}`);



		let typeId = this.getIsParam(params, 'typeId');
		let seriesId = this.getIsParam(params, 'seriesId');
		let seasonId = this.getIsParam(params, 'seasonId');
		let videoId = this.getIsParam(params, 'videoId');

		this.setType(typeId);
		this.setSeries(seriesId);
		this.setSeason(seasonId);
		this.setVideo(videoId);
	}
	reset(): void {
		this.typeId = undefined;
		this.typeName = undefined;
		this.typeChange.emit(this.typeId);
		this.seriesId = undefined;
		this.seriesName = undefined;
		this.seriesChange.emit(this.seriesId);
		this.seasonId = undefined;
		this.seasonName = undefined;
		this.seasonChange.emit(this.seasonId);
		this.videoId = undefined;
		this.videoName = undefined;
		this.videoChange.emit(this.videoId);
	}

	/*
	getCurrentRoute():InputOrders {
		let out = new InputOrders()
		out.typeId = parseInt(this.route.snapshot.paramMap.get('typeId'));
		if (out.typeId === 0){
			out.typeId = undefined;
		}
		out.seriesId = parseInt(this.route.snapshot.paramMap.get('seriesId'));
		if (out.seriesId === 0){
			out.seriesId = undefined;
		}
		out.seasonId = parseInt(this.route.snapshot.paramMap.get('seasonId'));
		if (out.seasonId === 0){
			out.seasonId = undefined;
		}
		out.videoId = parseInt(this.route.snapshot.paramMap.get('videoId'));
		if (out.videoId === 0){
			out.videoId = undefined;
		}
		return out;
	}

	routeTo(data:InputOrders, destination:string = null) {
		routeTo = ""
		//if (
		this.router.navigate(['/type/' + this.typeId + '/series/' + this.idSeries + '/season/' + IdSelected ]);
	}
	*/

	setType(id: number): void {
		if (this.typeId === id) {
			return;
		}
		this.typeId = id;
		this.typeName = '??--??';
		if (isUndefined(this.typeId)) {
			this.typeChange.emit(this.typeId);
			return;
		}
		let self = this;
		this.typeService.get(id)
			.then((response) => {
				self.typeName = response.name;
				self.typeChange.emit(self.typeId);
			}).catch((response) => {
				self.typeChange.emit(self.typeId);
			});
	}
	getTypeId(): number | undefined {
		return this.typeId;
	}
	getTypeName(): string | undefined {
		return this.typeName;
	}

	setSeries(id: number | undefined): void {
		if (this.seriesId === id) {
			return;
		}
		this.seriesId = id;
		this.seriesName = '??--??';
		if (isUndefined(this.seriesId)) {
			this.seriesChange.emit(this.seriesId);
			return;
		}
		let self = this;
		this.seriesService.get(id)
			.then((response: Season) => {
				self.seriesName = response.name;
				self.seriesChange.emit(self.seriesId);
			}).catch((response) => {
				self.seriesChange.emit(self.seriesId);
			});
	}
	getSeriesId(): number {
		return this.seriesId;
	}
	getSeriesName(): string {
		return this.seriesName;
	}

	setSeason(id: number | undefined): void {
		if (this.seasonId === id) {
			return;
		}
		this.seasonId = id;
		this.seasonName = '??--??';
		if (isUndefined(this.seasonId)) {
			this.seasonChange.emit(this.seasonId);
			return;
		}
		let self = this;
		this.seasonService.get(id)
			.then((response: Season) => {
				// self.setSeries(response.seriesId);
				self.seasonName = response.name;
				self.seasonChange.emit(self.seasonId);
			}).catch((response) => {
				self.seasonChange.emit(self.seasonId);
			});
	}
	getSeasonId(): number {
		return this.seasonId;
	}
	getSeasonName(): string {
		return this.seasonName;
	}

	setVideo(id: number | undefined): void {
		if (this.videoId === id) {
			return;
		}
		this.videoId = id;
		this.videoName = '??--??';
		if (isUndefined(this.videoId)) {
			this.videoChange.emit(this.videoId);
			return;
		}
		let self = this;
		this.MediaService.get(id)
			.then((response) => {
				// self.setSeason(response.seasonId);
				// self.setSeries(response.seriesId);
				self.videoName = response.name;
				self.videoChange.emit(self.videoId);
			}).catch((response) => {
				self.videoChange.emit(self.videoId);
			});
	}
	getVideoId(): number {
		return this.videoId;
	}
	getVideoName(): string {
		return this.videoName;
	}

	/**
	 * Generic navigation on the browser.
	 * @param destination - new destination url
	 * @param typeId - type IF
	 * @param seriesId - series real ID
	 * @param seasonId - season ID
	 * @param videoId - Video ID
	 * @param newWindows - open in a new windows
	 * @param replaceCurrentPage - consider the curent page is removed from history
	 */
	genericNavigate(
		destination: string,
		typeId: number,
		seriesId: number,
		seasonId: number,
		videoId: number,
		newWindows: boolean = false,
		replaceCurrentPage: boolean = false): void {
		let addressOffset = `${destination}/${typeId}/${seriesId}/${seasonId}/${videoId}`;
		if (newWindows === true) {
			window.open(`/${addressOffset}`);
		} else {
			this.router.navigate([addressOffset], { replaceUrl: replaceCurrentPage });
		}
	}

	navigateType(id: number, newWindows: boolean, ctrl: boolean = false): void {
		if (ctrl === true) {
			this.navigateTypeEdit(id, newWindows);
			return;
		}
		this.genericNavigate('type', id, null, null, null, newWindows);
	}
	navigateTypeEdit(id: number, newWindows: boolean): void {
		this.genericNavigate('type-edit', id, null, null, null, newWindows);
	}
	navigateSeries(id: number, newWindows: boolean, ctrl: boolean = false): void {
		if (ctrl === true) {
			this.navigateSeriesEdit(id, newWindows);
			return;
		}
		this.genericNavigate('series', this.typeId, id, null, null, newWindows);
	}
	navigateSeriesEdit(id: number, newWindows: boolean): void {
		this.genericNavigate('series-edit', this.typeId, id, null, null, newWindows);
	}
	navigateSeason(id: number, newWindows: boolean, ctrl: boolean = false, replaceCurrentPage: boolean = false): void {
		if (ctrl === true) {
			this.navigateSeasonEdit(id, newWindows);
			return;
		}
		this.genericNavigate('season', this.typeId, this.seriesId, id, null, newWindows, replaceCurrentPage);
	}
	navigateSeasonEdit(id: number, newWindows: boolean): void {
		this.genericNavigate('season-edit', this.typeId, this.seriesId, id, null, newWindows);
	}
	navigateVideo(id: number, newWindows: boolean, ctrl: boolean = false): void {
		if (ctrl === true) {
			this.navigateVideoEdit(id, newWindows);
			return;
		}
		this.genericNavigate('video', this.typeId, this.seriesId, this.seasonId, id, newWindows);
	}
	navigateVideoEdit(id: number, newWindows: boolean): void {
		this.genericNavigate('video-edit', this.typeId, this.seriesId, this.seasonId, id, newWindows);
	}
}
