import { SmartFox, SFSEvent, LogLevel, NetDebugLevel, ConfigData, EventParam, ClientDisconnectionReason } from 'sfs3-api';
import { LoginRequest } from 'sfs3-api';

// IP address or domain name of the SmartFoxServer instance; if encryption is enabled, a domain name must be used
const host = "127.0.0.1";

// HTTP listening port of the SmartFoxServer instance
const httpPort = 8088;

// HTTPS listening port of the SmartFoxServer instance, used when connection encryption in enabled
const httpsPort = 8843;

// Enable SmartFoxServer protocol encryption; 'host' must be a domain name and an SSL certificate must have been deployed
const encrypt = false;

// Name of the SmartFoxServer Zone to join
const zone = "Playground";

// Display SmartFoxServer client debug messages
const debug = false;

// Client-side SmartFoxServer logging level
const logLevel = LogLevel.INFO;

let loginView;
let mainView;
let nameInput;
let loginButton;
let errorAlert;
let userLabel;
let sfs;

document.addEventListener('DOMContentLoaded', () => {

	loginView = document.getElementById('loginView');
	mainView = document.getElementById('mainView');
	nameInput = document.getElementById('nameInput');
	loginButton = document.getElementById('loginButton');
	errorAlert = document.getElementById('errorAlert');
	userLabel = document.getElementById('userLabel');

    // Add form submit listener
	const loginForm = document.getElementById('loginForm');
	loginForm.addEventListener('submit', onLoginFormSubmit);

    // Add logout listener
	const logoutButton = document.getElementById('logoutButton');
	logoutButton.addEventListener('click', onLogoutButtonClick);

	// Focus on username input
	nameInput.focus();
});

//----------------------------------------------------------
// UI event listeners
//----------------------------------------------------------

/**
 * On Login form submit, connect to SmartFoxServer.
 */
function onLoginFormSubmit(e)
{
	e.preventDefault();

	connect();
}

/**
 * On Logout button click, disconnect from SmartFoxServer.
 */
function onLogoutButtonClick(e)
{
	sfs.disconnect();
}

//----------------------------------------------------------
// Helper methods
//----------------------------------------------------------

function trace(str)
{
	console.log('%c' + str, 'color: #6FBFF9');
}

function enableUI(enable)
{
	nameInput.disabled = !enable;
	loginButton.disabled = !enable;
}

function setErrorMessage(msg)
{
	if (msg == null || msg.length == 0)
	{
		errorAlert.innerHTML = '';
		errorAlert.hidden = true;
	}
	else
	{
		errorAlert.innerHTML = msg;
		errorAlert.hidden = false;
	}
}

function switchView()
{
	loginView.hidden = !loginView.hidden;
	mainView.hidden = !mainView.hidden;
}

function connect()
{
	trace('Attempting connection to SmartFoxServer...');

	// Disable user interface
	enableUI(false);

	// Clear any previour error message
	setErrorMessage();

	// Initialize SmartFox client
	sfs = new SmartFox();

	// Add event listeners
	sfs.addEventListener(SFSEvent.CONNECTION, onConnection);
	sfs.addEventListener(SFSEvent.CONNECTION_LOST, onConnectionLost);
	sfs.addEventListener(SFSEvent.LOGIN, onLogin);
	sfs.addEventListener(SFSEvent.LOGIN_ERROR, onLoginError);

	// Configure internal logger
	sfs.logger.level = logLevel

	// Set connection parameters
	const cfg = new ConfigData();
	cfg.host = host;
	cfg.port = encrypt ? httpsPort : httpPort;
	cfg.useSSL = encrypt;
	cfg.zone = zone;
	cfg.netDebugLevel = debug ? NetDebugLevel.PROTOCOL : NetDebugLevel.OFF;

	// Connect to SmartFoxServer
	sfs.connect(cfg);
}

function login()
{
	trace("Performing login...");

	// Login
	sfs.send(new LoginRequest(nameInput.value));
}

//----------------------------------------------------------
// SmartFoxServer event listeners
//----------------------------------------------------------

function onConnection(evtParams)
{
	const success = evtParams[EventParam.Success];

	// Check if the conenction was established or not
	if (success)
	{
		trace("Connection established successfully");
		trace("SFS3 API version: " + sfs.version);

		// Attempt login
		login();
	}
	else
	{
		// Show error message
		setErrorMessage('Connection failed; is the server running at all?');

		// Enable user interface
		enableUI(true);
	}
}

function onConnectionLost(evtParams)
{
	// Show login view
	switchView();

	// Show error message
	const reason = evtParams[EventParam.DisconnectionReason];

	trace(`Connection to SmartFoxServer lost; reason is: ${reason}`);

	if (reason != ClientDisconnectionReason.MANUAL)
	{
		// Show error message
		let connLostMsg = 'An unexpected disconnection occurred; ';

		switch (reason)
		{
			case ClientDisconnectionReason.IDLE:
				connLostMsg += 'you have been idle for too much time.';
				break;

			case ClientDisconnectionReason.KICKED:
				connLostMsg += 'you have been kicked.';
				break;

			case ClientDisconnectionReason.BANNED:
				connLostMsg += 'you have been banned.';
				break;

			default:
				connLostMsg += 'reason is unknown.';
		}

		setErrorMessage(connLostMsg);
	}

	// Enable user interface
	enableUI(true);
}

function onLogin(evtParams)
{
	trace("Login successful");

	// Display user name
	userLabel.innerText = sfs.mySelf.name;

	// Update view
	switchView();
}

function onLoginError(evtParams)
{
	trace("Login failed");

	// Disconnect
	// NOTE: this causes a CONNECTION_LOST event with reason "manual"
	sfs.disconnect();

	// Show error message
	setErrorMessage(`Login failed due to the following error: ${evtParams[EventParam.ErrorMessage]}`);

	// Enable user interface
	enableUI(true);
}