import axios from 'axios';

export class WirecastConnection {
	ip: string;
	port: number;

	clockInterval: any;

	shots: Shots;
	layers: Layers;

	constructor() {
		this.shots = {
			'1': { shots: {} },
			'2': { shots: {} },
			'3': { shots: {} },
			'4': { shots: {} },
			'5': { shots: {} }
		};
		this.layers = {
			'1': { id: null, name: null },
			'2': { id: null, name: null },
			'3': { id: null, name: null },
			'4': { id: null, name: null },
			'5': { id: null, name: null }
		};
		this.clockInterval = setInterval(() => {
			this.clock();
		}, 30000);
	}

	destroy() {
		clearInterval(this.clockInterval);
	}

	clock() {
		this.update();
	}

	update() {
		if (this.ip != undefined && this.port != undefined) {
			// axios
			// 	.get(`http://${this.ip}:${this.port}/api/v2/shots/get`)
			// 	.then((response) => {
			// 		if (response.data != undefined && response.data.succeed == true) {
			// 			this.shots = response.data.shots;
			// 		}
			// 	})
			// 	.catch(() => {});
			// axios
			// 	.get(`http://${this.ip}:${this.port}/api/v2/layers/get`)
			// 	.then((response) => {
			// 		if (response.data != undefined && response.data.succeed == true) {
			// 			this.layers = response.data.layers;
			// 		}
			// 	})
			// 	.catch(() => {});
		}
	}

	setHost(ip: string, port: number) {
		this.ip = ip;
		this.port = port;
		this.update();
	}

	ping(callback?: (state: boolean) => void): Promise<void> {
		return new Promise((resolve, reject) => {
			axios
				.get(`http://${this.ip}:${this.port}/api/v2/ping`)
				.then(() => {
					if (callback) callback(true);
					if (callback == undefined) resolve();
				})
				.catch((error) => {
					if (callback) callback(false);
					if (callback == undefined) reject();
				});
		});
	}

	setShotLiveByID(shotID: number): Promise<void> {
		return new Promise((resolve, reject) => {
			axios
				.get(`http://${this.ip}:${this.port}/api/v2/shots/liveByID/${shotID}`)
				.then((response) => {
					if (response.data.succeed == true) resolve();
					else reject();
				})
				.catch((error) => {
					console.log(error);
					reject();
				});
		});
	}

	clearShotIfLive(shotID: number): Promise<void> {
		return new Promise((resolve, reject) => {
			axios
				.get(`http://${this.ip}:${this.port}/api/v2/shots/clearIfLive/${shotID}`)
				.then((response) => {
					if (response.data.succeed == true) resolve();
					else reject();
				})
				.catch((error) => {
					console.log(error);
					reject();
				});
		});
	}

	clearLayer(layerID: number): Promise<void> {
		return new Promise((resolve, reject) => {
			axios
				.get(`http://${this.ip}:${this.port}/api/v2/layers/clear/${layerID}`)
				.then((response) => {
					if (response.data.succeed == true) resolve();
					else reject();
				})
				.catch((error) => {
					console.log(error);
					reject();
				});
		});
	}

	go(): Promise<void> {
		return new Promise((resolve, reject) => {
			console.log(`http://${this.ip}:${this.port}/api/v2/document/go`);
			axios
				.get(`http://${this.ip}:${this.port}/api/v2/document/go`)
				.then((response) => {
					if (response.data.succeed == true) resolve();
					else reject();
				})
				.catch((error) => {
					console.log(error);
					reject();
				});
		});
	}

	multiShot(
		layer1Shot: number,
		layer2Shot: number,
		layer3Shot: number,
		layer4Shot: number,
		layer5Shot: number
	): Promise<void> {
		return new Promise((resolve, reject) => {
			axios
				.get(
					`http://${this.ip}:${this
						.port}/api/v2/shots/multi/${layer1Shot}/${layer2Shot}/${layer3Shot}/${layer4Shot}/${layer5Shot}`
				)
				.then((response) => {
					if (response.data.succeed == true) resolve(response.data);
					else reject(response.data);
				})
				.catch((error) => {
					console.log(error);
					reject({ succeed: false, error: 'Unable to reach Wirecast-Bridge' });
				});
		});
	}

	setBroadcasting(state: boolean): Promise<void> {
		return new Promise((resolve, reject) => {
			axios
				.get(`http://${this.ip}:${this.port}/api/v2/document/broadcasting/${state}`)
				.then((response) => {
					if (response.data.succeed == true) resolve();
					else reject();
				})
				.catch((error) => {
					console.log(error);
					reject('Unable to reach Wirecast-Bridge');
				});
		});
	}
	setRecording(state: boolean): Promise<void> {
		return new Promise((resolve, reject) => {
			axios
				.get(`http://${this.ip}:${this.port}/api/v2/document/recording/${state}`)
				.then((response) => {
					if (response.data.succeed == true) resolve();
					else reject();
				})
				.catch((error) => {
					console.log(error);
					reject('Unable to reach Wirecast-Bridge');
				});
		});
	}
	setAutoLive(state: boolean): Promise<void> {
		return new Promise((resolve, reject) => {
			axios
				.get(`http://${this.ip}:${this.port}/api/v2/document/autolive/${state}`)
				.then((response) => {
					if (response.data.succeed == true) resolve();
					else reject();
				})
				.catch((error) => {
					console.log(error);
					reject('Unable to reach Wirecast-Bridge');
				});
		});
	}
	setTransitionSpeed(speed: string): Promise<void> {
		return new Promise((resolve, reject) => {
			axios
				.get(`http://${this.ip}:${this.port}/api/v2/document/transitionspeed/${speed}`)
				.then((response) => {
					if (response.data.succeed == true) resolve();
					else reject();
				})
				.catch((error) => {
					console.log(error);
					reject('Unable to reach Wirecast-Bridge');
				});
		});
	}

	getShots(callback: (shots: Shots) => void) {
		if (this.ip != undefined && this.port != undefined) {
			axios
				.get(`http://${this.ip}:${this.port}/api/v2/shots/get`)
				.then((response) => {
					if (response.data != undefined && response.data.succeed == true) {
						this.shots = response.data.shots;
						callback(this.shots);
					}
				})
				.catch(() => {});
		}
	}

	getShotsList(layerIndex?: number, callback?: (shots: { id: number; name: string }[]) => void) {
		this.getShots(() => {
			var list: { id: number; name: string }[] = [];
			if (layerIndex == undefined)
				for (var layer in this.shots) {
					for (var shot in this.shots[layer].shots) {
						list.push(this.shots[layer].shots[shot]);
					}
				}
			else {
				for (var shot in this.shots[layerIndex].shots) {
					list.push(this.shots[layerIndex].shots[shot]);
				}
			}

			callback(list);
		});
	}

	getLayers(callback: (layers: Layers) => void) {
		axios
			.get(`http://${this.ip}:${this.port}/api/v2/layers/get`)
			.then((response) => {
				if (response.data != undefined && response.data.succeed == true) {
					this.layers = response.data.layers;
					callback(this.layers);
				}
			})
			.catch(() => {});
	}

	getLayersList(callback: (layers: { id: number; name: string }[]) => void) {
		this.getLayers(() => {
			var list: { id: number; name: string }[] = [];
			for (var layer in this.layers) {
				list.push(this.layers[layer]);
			}
			callback(list);
		});
	}
}

interface Shots {
	[index: string]: {
		shots: {
			[index: string]: {
				name: string;
				id: number;
			};
		};
	};
}

interface Layers {
	[index: string]: {
		name: string;
		id: number;
	};
}
