import axios from 'axios';
import { ConnectionManager_Connection } from '../../../../ConnectionManager';
import { ActionAPI } from '../../../ActionAPI';
import { EditorAPI, EditorAPI_Field } from '../../../EditorAPI';
import { Mitti } from '../MittiClass';

module.exports = (actionAPI: ActionAPI) => {
	//Handle the action when executed
	actionAPI.handle(
		(properties: Source_Properties, status: (text: string, type?: 'info' | 'error' | 'warn') => void) => {
			var connectionID = properties.connectionID != undefined ? properties.connectionID : 'none';
			var clipID = properties.clipID != undefined ? properties.clipID : 'none';
			if (connectionID != 'none') {
				if (clipID != 'none') {
					var connection = actionAPI.getConnection('mitti', connectionID);
					var ip = <string>connection.properties.ip;
					var mitti = new Mitti(ip);

					mitti.on('connected', () => {
						mitti
							.selectClip(parseInt(clipID))
							.then(() => {
								status(`Clip ${clipID} has been selected`, 'info');
							})
							.catch((error: Error) => {
								status(error.message, 'error');
							});
					});
				} else status('No clip specified', 'error');
			} else status('No connection specified', 'error');
		}
	);

	//Handle the interactive editor
	actionAPI.onOpenEditor((editorAPI: EditorAPI, properties: Source_Properties) => {
		var connectionID = properties.connectionID != undefined ? properties.connectionID : 'none';
		var clipID = properties.clipID != undefined ? properties.clipID : 'none';

		var currentIP: string;
		var currentPort: number;

		var fields: EditorAPI_Field[] = [
			{
				id: 'connectionID',
				name: 'Connection',
				type: 'connection',
				value: connectionID,
				connectionType: 'mitti'
			},
			{
				id: 'clipID',
				name: 'Clip',
				type: 'select',
				value: clipID,
				values: []
			}
		];

		function updateAddress(connectionID: string, callback: (changed: boolean) => void) {
			if (connectionID != 'none') {
				var connection = actionAPI.getConnection('mitti', connectionID);

				var ip: string = <string>connection.properties.ip;
				var port: number = <number>connection.properties.port;

				if (currentIP != ip || currentPort != port) {
					currentIP = ip;
					currentPort = port;
					callback(true);
				} else {
					callback(false);
				}
			} else {
				if (currentIP != null || currentPort != null) {
					currentIP = <any>null;
					currentPort = <any>null;
					callback(true);
				} else {
					callback(false);
				}
			}
		}

		function updateSources(callback: () => void) {
			var mitti = new Mitti(currentIP);
			mitti
				.getClips()
				.then((clips) => {
					var fieldValues: { id: string; text: string }[] = [];
					for (var clipID in clips) {
						var query = clips[clipID];
						var name = query.split(' ').splice(query.split(' ').length - 3, 2);
						fieldValues.push({ id: clipID, text: `${clipID} - ${name}` });
					}
					fields[1].values = fieldValues;

					callback();
				})
				.catch((error) => {
					fields[1].values = [];
					callback();
				});
		}

		function validate(fieldValues: Source_Properties) {
			fields[0].value = fieldValues.connectionID;
			fields[1].value = fieldValues.clipID;

			editorAPI.saveProperties({ connectionID: fieldValues.connectionID, clipID: fieldValues.clipID });

			updateAddress(fieldValues.connectionID, (changed) => {
				if (changed) {
					updateSources(() => {
						editorAPI.setFields(fields);
					});
				} else editorAPI.setFields(fields);
			});
		}

		validate({ connectionID, clipID });

		editorAPI.onFieldChanges((fields: EditorAPI_Field[]) => {
			var fieldValues: Source_Properties = <any>editorAPI.tools.objectifyFieldsValues(fields);

			validate(fieldValues);
		});
	});
};

interface Source_Properties {
	connectionID: string;
	clipID: string;
}
