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

import { Injectable } from '@angular/core';
import { DataStore, SessionService, TypeCheck } from '@kangaroo-and-rabbit/kar-cw';
import { Media, Season, SeasonResource, UUID } from 'app/back-api';
import { ProgressCallback, RESTAbort, RESTConfig } from 'app/back-api/rest-tools';
import { environment } from 'environments/environment';
import { GenericDataService } from './GenericDataService';
import { MediaService } from './media';


@Injectable()
export class SeasonService extends GenericDataService<Season> {


	getRestConfig(): RESTConfig {
		return {
			server: environment.server.karideo,
			token: this.session.getToken()
		}
	}
	private lambdaGets(): Promise<Season[]> {
		return SeasonResource.gets({ restConfig: this.getRestConfig() });
	}

	constructor(
		private session: SessionService,
		private MediaService: MediaService,
	) {
		super();
		console.log('Start SeasonService');
		const self = this;
		this.setStore(new DataStore<Season>(() => self.lambdaGets()));
	}
	/**
	 * Get all the video for a specific season
	 * @param id - Id of the season.
	 * @returns a promise on the list of video elements
	 */
	getVideo(id: number): Promise<Media[]> {
		let self = this;
		return new Promise((resolve, reject) => {
			self.MediaService.getsWhere(
				[
					{
						check: TypeCheck.EQUAL,
						key: 'seasonId',
						value: id,
					},
				],
				['episode', 'name'])
				.then((data: Media[]) => {
					resolve(data);
				})
				.catch((response) => {
					reject(response);
				});
		});
	}

	/**
	 * Get the number of video in this season ID
	 * @param id - Id of the season.
	 * @returns The number of element present in this season
	 */
	countVideo(id: number): Promise<number> {
		let self = this;
		return new Promise((resolve, reject) => {
			self.MediaService.getsWhere([
				{
					check: TypeCheck.EQUAL,
					key: 'seasonId',
					value: id,
				},
			])
				.then((data: Media[]) => {
					resolve(data.length);
				})
				.catch((response) => {
					reject(response);
				});
		});
	}


	patch(id: number, data: Season): Promise<Season> {
		const self = this;
		return new Promise((resolve, reject) => {
			SeasonResource.patch({
				restConfig: this.getRestConfig(),
				params: {
					id
				},
				data
			}).then((value: Media) => {
				self.dataStore.updateValue(value);
				resolve(value);
			}).catch((error) => {
				reject(error);
			});
		});
	}

	delete(id: number): Promise<void> {
		const self = this;
		return new Promise((resolve, reject) => {
			SeasonResource.remove({
				restConfig: this.getRestConfig(),
				params: {
					id
				}
			}).then(() => {
				self.dataStore.delete(id);
				resolve();
			}).catch((error) => {
				reject(error);
			});
		});
	}

	deleteCover(id: number, coverId: UUID): Promise<Season> {
		let self = this;
		return new Promise((resolve, reject) => {
			SeasonResource.removeCover({
				restConfig: this.getRestConfig(),
				params: {
					id,
					coverId
				}
			}).then((value) => {
				self.dataStore.updateValue(value);
				resolve(value);
			}).catch((error) => {
				reject(error);
			});
		});
	}
	uploadCover(id: number,
		file: File,
		progress: ProgressCallback | undefined = undefined,
		cancelHandle: RESTAbort | undefined = undefined): Promise<Season> {
		let self = this;
		return new Promise((resolve, reject) => {
			SeasonResource.uploadCover({
				restConfig: this.getRestConfig(),
				params: {
					id,
				},
				data: {
					file,
				},
				callbacks: {
					progressUpload: progress,
					abortHandle: cancelHandle,
				}
			}).then((value) => {
				self.dataStore.updateValue(value);
				resolve(value);
			}).catch((error) => {
				reject(error);
			});
		});
	}
}
