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

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { isNullOrUndefined } from '@kangaroo-and-rabbit/kar-cw';
import { UUID, UserMediaAdvancement } from 'app/back-api';
import { DataService, MediaService, SeriesService, SeasonService, ArianeService, AdvancementService } from 'app/service';


@Component({
	selector: 'app-video',
	templateUrl: './video.html',
	styleUrls: ['./video.less']
})

export class VideoScene implements OnInit {
	videoGlobal: any;
	@ViewChild('globalVideoElement')
	set mainDivEl(el: ElementRef) {
		if (!isNullOrUndefined(el)) {
			this.videoGlobal = el.nativeElement;
		}
	}
	videoPlayer: HTMLVideoElement;
	@ViewChild('videoPlayer')
	set mainVideoEl(el: ElementRef) {
		if (!isNullOrUndefined(el)) {
			this.videoPlayer = el.nativeElement;
		}
	}
	videoCanva: any;
	@ViewChild('canvascreenshoot')
	set mainCanvaEl(el: ElementRef) {
		if (!isNullOrUndefined(el)) {
			this.videoCanva = el.nativeElement;
		}
	}
	haveNext = null;
	havePrevious = null;
	idVideo: number = -1;

	mediaIsNotFound: boolean = false;
	mediaIsLoading: boolean = true;
	error: string = '';

	name: string = '';
	description: string = '';
	episode: number = undefined;
	seriesId: number = undefined;
	seriesName: string = undefined;
	seasonId: number = undefined;
	seasonName: string = undefined;
	dataId: UUID;
	time: number = undefined;
	typeId: number = undefined;
	generatedName: string = '';
	videoSource: string = '';
	covers: string[];

	playVideo: boolean = false;
	displayVolumeMenu: boolean = false;
	isPlaying: boolean = false;
	isFullScreen: boolean = false;
	currentTime: number = 0;
	currentTimeDisplay: string = '00';
	duration: number = 0;
	durationDisplay: string = '00';
	volumeValue: number = 100;

	displayNeedHide: boolean = false;
	timeLeft: number = 10;
	interval = null;

	userMetaData: UserMediaAdvancement & { percentDisplay: number } = undefined

	previousTime: number = 0;
	startPlayingTime: number = undefined;
	hasFullReadTheVideo: {
		previousTime: number,
		totalCount: number,
		registered: boolean
	} = {
			previousTime: 0,
			totalCount: 0,
			registered: false
		};

	constructor(
		private dataService: DataService,
		private advancementService: AdvancementService,
		private MediaService: MediaService,
		private seasonService: SeasonService,
		private seriesService: SeriesService,
		private arianeService: ArianeService,) {

	}

	startHideTimer() {
		this.displayNeedHide = false;
		this.timeLeft = 5;
		if (this.interval !== null) {
			return;
		}
		let self = this;
		this.interval = setInterval(() => {
			console.log(`periodic event: ${self.timeLeft}`);
			if (self.timeLeft > 0) {
				self.timeLeft--;
			} else {
				clearInterval(self.interval);
				self.timeOutDetected();
			}
		}, 1000);
	}
	timeOutDetected() {
		console.log(' ==> stop timer');
		this.displayNeedHide = true;
		clearInterval(this.interval);
		this.interval = null;
	}
	onRequireNext(event: any) {
		console.log(`generate next : ${this.haveNext.id}`);
		this.arianeService.navigateVideo(this.haveNext.id, event.which === 2, event.ctrlKey);
		this.arianeService.setVideo(this.haveNext.id);
	}
	onRequirePrevious(event: any) {
		console.log(`generate previous : ${this.havePrevious.id}`);
		this.arianeService.navigateVideo(this.havePrevious.id, event.which === 2, event.ctrlKey);
		this.arianeService.setVideo(this.havePrevious.id);
	}
	generateName() {
		this.generatedName = '';
		if (this.seriesName !== undefined) {
			this.generatedName = `${this.generatedName}${this.seriesName}-`;
		}
		if (this.seasonName !== undefined) {
			if (this.seasonName.length < 2) {
				this.generatedName = `${this.generatedName}s0${this.seasonName}-`;
			} else {
				this.generatedName = `${this.generatedName}s${this.seasonName}-`;
			}
		}
		if (this.episode !== undefined) {
			if (this.episode < 10) {
				this.generatedName = `${this.generatedName}e0${this.episode}-`;
			} else {
				this.generatedName = `${this.generatedName}e${this.episode}-`;
			}
		}
		this.generatedName = this.generatedName + this.name;
		this.generatedName = this.generatedName.replace(new RegExp('&', 'g'), '_');
		this.generatedName = this.generatedName.replace(new RegExp('/', 'g'), '_');
		// update the path of the uri request
		this.videoSource = this.dataService.getUrl(
			this.dataId,
			this.generatedName,
		);
	}

	myPeriodicCheckFunction() {
		console.log('check ... ');
	}
	changeMetadata() {
		console.log('list of the stream:');

		/*
		let captureStream = this.videoPlayer.audioTracks;
		for (let iii=0; iii < captureStream.length; iii++) {
			console.log("  - " + captureStream[iii].language);
			if (captureStream[iii].language.substring(0,2) === "fr") {
				captureStream[iii].enabled = true;
			} else {
				captureStream[iii].enabled = false;
			}
		}
		*/
	}
	audioTracks(event) {
		console.log(`list of the stream:${event}`);

		/*
		let captureStream = this.videoPlayer.audioTracks;
		for (let iii=0; iii < captureStream.length; iii++) {
			console.log("  - " + captureStream[iii].language);
			if (captureStream[iii].language.substring(0,2) === "fr") {
				captureStream[iii].enabled = true;
			} else {
				captureStream[iii].enabled = false;
			}
		}
		*/
	}

	ngOnInit() {
		let self = this;
		this.startHideTimer();
		this.idVideo = this.arianeService.getVideoId();
		this.arianeService.videoChange.subscribe((videoId) => {
			console.log(`Detect videoId change...${videoId}`);
			self.idVideo = videoId;
			self.updateDisplay();
		});
		self.updateDisplay();
	}
	updateDisplay(): void {
		let self = this;
		self.haveNext = null;
		self.havePrevious = null;
		this.MediaService.get(this.idVideo)
			.then((response) => {
				console.log(`get response of video : ${JSON.stringify(response, null, 2)}`);
				self.error = '';
				self.name = response.name;
				self.description = response.description;
				self.episode = response.episode;
				self.seriesId = response.seriesId;
				self.seasonId = response.seasonId;
				self.dataId = response.dataId;
				self.time = response.time;
				self.generatedName = "????????? TODO: ???????" //response.generatedName;
				if (!isNullOrUndefined(self.dataId)) {
					self.videoSource = self.dataService.getUrl(self.dataId, self.generatedName);
				} else {
					self.videoSource = '';
				}
				self.covers = self.dataService.getListThumbnailUrl(response.covers);

				self.generateName();
				if (self.seriesId !== undefined && self.seriesId !== null) {
					self.seriesService.get(self.seriesId)
						.then((response2) => {
							self.seriesName = response2.name;
							self.generateName();
						}).catch((response3) => {
							// nothing to do ...
						});
				}
				if (self.seasonId !== undefined && self.seasonId !== null) {
					self.seasonService.get(self.seasonId)
						.then((response4) => {
							self.seasonName = response4.name;
							self.generateName();
						}).catch((response5) => {
							// nothing to do ...
						});
					self.seasonService.getVideo(self.seasonId)
						.then((response6: any) => {
							// console.log("saison property: " + JSON.stringify(response, null, 2));
							self.haveNext = null;
							self.havePrevious = null;
							for (let iii = 0; iii < response6.length; iii++) {
								if (isNullOrUndefined(response6[iii].episode)) {
									continue;
								}
								if (response6[iii].episode < self.episode) {
									if (self.havePrevious === null) {
										self.havePrevious = response6[iii];
									} else if (self.havePrevious.episode < response6[iii].episode) {
										self.havePrevious = response6[iii];
									}
								} else if (response6[iii].episode > self.episode) {
									if (self.haveNext === null) {
										self.haveNext = response6[iii];
									} else if (self.haveNext.episode > response6[iii].episode) {
										self.haveNext = response6[iii];
									}
								}
								//self.covers.push(self.dataService.getThumbnailUrl(response6[iii]));
							}
						}).catch((response7: any) => {

						});
				}
				self.mediaIsLoading = false;
				// console.log("display source " + self.videoSource);
				// console.log("set transformed : " + JSON.stringify(self, null, 2));
			}).catch((response8) => {
				self.error = 'Can not get the data';
				self.name = '';
				self.description = '';
				self.episode = undefined;
				self.seriesId = undefined;
				self.seasonId = undefined;
				self.dataId = undefined;
				self.time = undefined;
				self.generatedName = '';
				self.videoSource = '';
				self.covers = undefined;
				self.seriesName = undefined;
				self.seasonName = undefined;
				self.mediaIsNotFound = true;
				self.mediaIsLoading = false;
			});
		this.advancementService.get(this.idVideo)
			.then((response: UserMediaAdvancement) => {
				this.userMetaData = { ...response, percentDisplay: Math.floor(response.percent * 100) }
				this.startPlayingTime = response.time
			})
	}
	onRequirePlay() {
		this.startHideTimer();
		this.playVideo = true;
		this.hasFullReadTheVideo = {
			previousTime: 0,
			totalCount: 0,
			registered: false
		};
		this.displayVolumeMenu = false;
	}
	onRequireStop() {
		this.startHideTimer();
		const startPlayingTime = this.videoPlayer.currentTime
		this.playVideo = false;
		this.displayVolumeMenu = false;
		this.startPlayingTime = startPlayingTime;
	}
	onVideoEnded() {
		this.startHideTimer();
		this.playVideo = false;
		this.displayVolumeMenu = false;

		/*
		if(this.isFullScreen === true) {
			this.isFullScreen = false;
		}
		*/
	}

	changeStateToPlay() {
		this.isPlaying = true;
		if (this.isFullScreen === true) {
			this.onFullscreen();
		}
	}
	changeStateToPause() {
		this.isPlaying = false;
	}

	convertIndisplayTime(time: number): string {
		let tmpp = parseInt(`${time}`, 10);
		let heures = parseInt(`${tmpp / 3600}`, 10);
		tmpp = tmpp - heures * 3600;
		let minutes = parseInt(`${tmpp / 60}`, 10);
		let seconds = tmpp - minutes * 60;
		let out = '';
		if (heures !== 0) {
			out = `${out}${heures}:`;
		}
		if (minutes >= 10) {
			out = `${out}${minutes}:`;
		} else {
			out = `${out}0${minutes}:`;
		}
		if (seconds >= 10) {
			out = out + seconds;
		} else {
			out = `${out}0${seconds}`;
		}
		return out;
	}
	configureDefaultValue(): boolean {
		if (!isNullOrUndefined(this.startPlayingTime)) {
			this.videoPlayer.currentTime = this.startPlayingTime
			this.startPlayingTime = undefined;
			return true;
		}
		return false;
	}

	changeTimeupdate(currentTime: any) {
		// console.log("time change ");
		// console.log("    ==> " + this.videoPlayer.currentTime);
		// Normal display part
		this.currentTime = this.videoPlayer.currentTime;
		this.currentTimeDisplay = this.convertIndisplayTime(this.currentTime);

		// Cat set default value only at start
		if (this.configureDefaultValue()) {
			this.hasFullReadTheVideo.previousTime = this.currentTime;
			return;
		}
		let needAddOneCount = false;
		// Section to manage the detection of full read of the video
		if (!this.hasFullReadTheVideo.registered) {
			//console.log(`Check !!!!!!!! ${this.currentTime} / ${this.hasFullReadTheVideo.previousTime} ==> ${this.currentTime - this.hasFullReadTheVideo.previousTime}`);
			if (Math.abs(this.currentTime - this.hasFullReadTheVideo.previousTime) < 10) {
				//console.log(`  ==> step 1`);
				if (this.currentTime > this.hasFullReadTheVideo.previousTime) {
					this.hasFullReadTheVideo.totalCount += this.currentTime - this.hasFullReadTheVideo.previousTime;
				}
				//console.log(`  ==> step 2 percent = ${this.currentTime / this.duration}, total=${this.hasFullReadTheVideo.totalCount / 60}`);
				// Detect the passing of 90%
				if (this.currentTime / this.duration > 0.9) {
					//console.log(`  ==> step 3`);
					this.hasFullReadTheVideo.registered = true;
					// Add cont only if the user watching more than 3 minutes
					if (this.hasFullReadTheVideo.totalCount > 60 * 3) {
						//console.log(`  ==> step 4 ==> You win`);
						needAddOneCount = true;
					}
				}
			}
		}
		this.hasFullReadTheVideo.previousTime = this.currentTime;
		// console.log("    ==> " + this.currentTimeDisplay);
		if (needAddOneCount || Math.abs(this.previousTime - this.currentTime) > 15) {
			this.previousTime = this.currentTime;
			this.advancementService.updateTime(this.idVideo, this.currentTime, this.duration, needAddOneCount);
		}
	}
	changeDurationchange(duration: any) {
		console.log('duration change ');
		console.log(`    ==> ${this.videoPlayer.duration}`);
		this.configureDefaultValue();
		this.duration = this.videoPlayer.duration;
		this.durationDisplay = this.convertIndisplayTime(this.duration);
	}

	onPlay() {
		console.log('play');
		this.startHideTimer();
		if (this.videoPlayer === null ||
			this.videoPlayer === undefined) {
			console.log(`error element: ${this.videoPlayer}`);
			return;
		}
		this.videoPlayer.volume = this.volumeValue / 100;
		this.videoPlayer.play();
	}

	onPause() {
		console.log('pause');
		this.startHideTimer();
		if (this.videoPlayer === null ||
			this.videoPlayer === undefined) {
			console.log(`error element: ${this.videoPlayer}`);
			return;
		}
		this.videoPlayer.pause();
	}

	onPauseToggle() {
		console.log('pause toggle ...');
		if (this.isPlaying === true) {
			this.onPause();
		} else {
			this.onPlay();
		}
	}

	onStop() {
		console.log('stop');
		this.startHideTimer();
		if (isNullOrUndefined(this.videoPlayer)) {
			console.log(`error element: ${this.videoPlayer}`);
			return;
		}
		this.videoPlayer.pause();
		this.videoPlayer.currentTime = 0;
	}

	onBefore() {
		console.log('before');
		this.startHideTimer();
	}

	onNext() {
		console.log('next');
		this.startHideTimer();
	}

	seek(newValue: any) {
		console.log(`seek ${newValue.value}`);
		this.startHideTimer();
		if (isNullOrUndefined(this.videoPlayer)) {
			console.log(`error element: ${this.videoPlayer}`);
			return;
		}
		this.videoPlayer.currentTime = newValue.value;
	}

	onRewind() {
		console.log('rewind');
		this.startHideTimer();
		if (isNullOrUndefined(this.videoPlayer)) {
			console.log(`error element: ${this.videoPlayer}`);
			return;
		}
		this.videoPlayer.currentTime = this.currentTime - 10;
	}

	onForward() {
		console.log('forward');
		this.startHideTimer();
		if (isNullOrUndefined(this.videoPlayer)) {
			console.log(`error element: ${this.videoPlayer}`);
			return;
		}
		this.videoPlayer.currentTime = this.currentTime + 10;
	}

	onMore() {
		console.log('more');
		this.startHideTimer();
		if (isNullOrUndefined(this.videoPlayer)) {
			console.log(`error element: ${this.videoPlayer}`);
			return;
		}
	}
	onFullscreen() {
		console.log('fullscreen');
		this.startHideTimer();
		if (isNullOrUndefined(this.videoGlobal)) {
			console.log(`error element: ${this.videoGlobal}`);
			return;
		}
		if (this.videoGlobal.requestFullscreen) {
			this.videoGlobal.requestFullscreen();
		} else if (this.videoGlobal.mozRequestFullScreen) {
			this.videoGlobal.mozRequestFullScreen();
		} else if (this.videoGlobal.webkitRequestFullscreen) {
			this.videoGlobal.webkitRequestFullscreen();
		} else if (this.videoGlobal.msRequestFullscreen) {
			this.videoGlobal.msRequestFullscreen();
		}
	}

	onFullscreenExit() {
		this.onFullscreenExit22(document);
	}
	onFullscreenExit22(docc: any) {
		console.log('fullscreen EXIT');
		this.startHideTimer();
		if (isNullOrUndefined(this.videoGlobal)) {
			console.log(`error element: ${this.videoGlobal}`);
			return;
		}
		if (docc.exitFullscreen) {
			docc.exitFullscreen();
		} else if (docc.mozCancelFullScreen) {
			docc.mozCancelFullScreen();
		} else if (docc.webkitExitFullscreen) {
			docc.webkitExitFullscreen();
		} else if (docc.msExitFullscreen) {
			docc.msExitFullscreen();
		}
	}

	onFullscreenChange() {
		this.onFullscreenChange22(document);
	}
	onFullscreenChange22(element: any) {
		let isInFullScreen = element.fullscreenElement && element.fullscreenElement !== null ||
			element.webkitFullscreenElement && element.webkitFullscreenElement !== null ||
			element.mozFullScreenElement && element.mozFullScreenElement !== null ||
			element.msFullscreenElement && element.msFullscreenElement !== null;
		console.log(`onFullscreenChange(${isInFullScreen})`);
		this.isFullScreen = isInFullScreen;
	}

	onVolumeMenu() {
		this.displayVolumeMenu = !this.displayVolumeMenu;
		this.startHideTimer();
	}

	onVolume(newValue: any) {
		console.log(`onVolume ${newValue.value}`);
		this.startHideTimer();
		if (this.videoPlayer === null ||
			this.videoPlayer === undefined) {
			console.log(`error element: ${this.videoPlayer}`);
			return;
		}
		this.volumeValue = newValue.value;
		this.videoPlayer.volume = this.volumeValue / 100;
		this.videoPlayer.muted = false;
	}

	onVolumeMute() {
		this.startHideTimer();
		if (this.videoPlayer === null ||
			this.videoPlayer === undefined) {
			console.log(`error element: ${this.videoPlayer}`);
			return;
		}
		this.videoPlayer.muted = true;
	}

	onVolumeUnMute() {
		this.startHideTimer();
		if (this.videoPlayer === null ||
			this.videoPlayer === undefined) {
			console.log(`error element: ${this.videoPlayer}`);
			return;
		}
		this.videoPlayer.muted = false;
	}

	onTakeScreenShoot() {
		this.startHideTimer();
		// const canvas = document.createElement("canvas");
		// scale the canvas accordingly
		this.videoCanva.width = this.videoPlayer.videoWidth;
		this.videoCanva.height = this.videoPlayer.videoHeight;
		// draw the video at that frame
		this.videoCanva.getContext('2d').drawImage(this.videoPlayer, 0, 0, this.videoCanva.width, this.videoCanva.height);
		// canvas.crossorigin="anonymous"
		// convert it and send it to the server
		let self = this;
		/*
		this.videoCanva.toBlob((blob) => {
			self.MediaService.uploadCoverBlob(blob, this.idVideo);
		}, 'image/jpeg', 0.95);
		*/
		console.log("not implement upload as row data...");
		/*
		let tmpUrl = this.videoCanva.toDataURL('image/jpeg', 0.95);
		fetch(tmpUrl)
		  .then(res => res.blob()) // Gets the response and returns it as a blob
		  .then(blob => {
			  self.MediaService.uploadCoverBlob(blob, this.idVideo);
		});
		*/
	}
}
