"use strict";

/**
 * @name Account
 *
 * @description
 * Implements actions with accounts
 *
 * @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
 * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
 */
export default class account {
	/**
	 * @name Type of the program
	 */
	static type = "module";

	// Wrap of indicator of the account
	static wrap = document.getElementById("account");

	// Indicator of the account
	static indicator = this.wrap?.getElementsByTagName("i")[0] ?? null;

	// Description of the account
	static description = this.wrap?.getElementsByTagName("small")[0] ?? null;

	/**
	 * Authentication
	 *
	 * @return {void}
	 */
	static authentication() {
		core.status_loading.removeAttribute("disabled");

		const timer_for_response = setTimeout(() => {
			core.status_loading.setAttribute("disabled", true);
		}, 200);

		core.modules.connect("telegram").then(() => {
			// Imported the telegram module

			if (core.telegram.api.initData.length > 0) {
				core
					.request(
						"/session/connect/telegram",
						core.telegram.api.initData,
						'PUT'
					)
					.then((json) => {
						if (json) {
							// Received a JSON-response

							if (
								json.errors !== null &&
								typeof json.errors === "object" &&
								json.errors.length > 0
							) {
								// Fail (received errors)

								// Exit (fail)
								reject(json);
							} else {
								// Success (not received errors)

								if (json.connected === true) {
									core.status_loading.setAttribute("disabled", true);
									clearTimeout(timer_for_response);

									const a = core.status_account.getElementsByTagName("a")[0];
									a.setAttribute("onclick", "core.account.profile()");
									a.innerText = json.domain.length > 0
										? "@" + json.domain
										: "ERROR";
								}

								if (
									json.language !== null &&
									typeof json.language === "string" &&
									json.langiage.length === 2
								) {
									core.language = json.language;
								}
							}
						}
					});
			}
		});
	}

	/**
	 * @name Buffer
	 */
	static buffer = class buffer {
		/**
		 * @name Write
		 *
		 * @description
		 * Write to the account buffer (interface)
		 *
		 * @param {string} name Name of the parameter
		 * @param {string} value Value of the parameter (it can be JSON)
		 * @param {bool} force Ignore the damper? (false)
		 *
		 * @return {bool} Did the execution complete without errors?
		 */
		static write = (name, value, force = false) => {
			core.modules.connect("damper").then(
				() => {
					// Imported the damper module

					// Execute under damper
					this.write.damper(name, value, force);
				},
				() => {
					// Not imported the damper module

					// Execute
					this.write.system(name, value, force);
				},
			);

			// Exit (success)
			return true;
		};
	};
}

core.modules.connect("damper").then(() => {
	// Imported the damper module

	Object.assign(
		account.buffer.write,
		{
			/**
			 * @name Write (damper)
			 *
			 * @description
			 * Write to the account buffer
			 *
			 * @memberof account.buffer.write
			 *
			 * @param {string} name Name of the parameter
			 * @param {string} value Value of the parameter (it can be JSON)
			 * @param {bool} force Ignore the damper? (false)
			 *
			 * @return {Promise}
			 */
			damper: core.damper(
				(...variables) => account.buffer.write.system(...variables),
				300,
				2,
			),
		},
	);
});

Object.assign(
	account.buffer.write,
	{
		/**
		 * @name Write (system)
		 *
		 * @description
		 * Write to the account buffer
		 *
		 * @memberof account.buffer.write
		 *
		 * @param {string} name Name of the parameter
		 * @param {string} value Value of the parameter (it can be JSON)
		 *
		 * @return {Promise}
		 */
		async system(
			name,
			value,
			resolve = () => {},
			reject = () => {},
		) {
			try {
				if (
					typeof name === "string" &&
					(typeof value === "string" || typeof value === "number")
				) {
					// Received and validated required arguments

					// Sending request to the server
					return await core.request(
						"/account/write",
						`${name}=${value}`,
						"PATCH",
					)
						.then(
							(json) => {
								if (json) {
									// Received a JSON-response

									if (
										json.errors !== null &&
										typeof json.errors === "object" &&
										json.errors.length > 0
									) {
										// Fail (received errors)

										// Exit (fail)
										reject(json);
									} else {
										// Success (not received errors)

										// Exit (success)
										resolve(json);
									}
								}
							},
							() => reject(),
						);
				}
			} catch (e) {
				// Exit (fail)
				reject(e);
			}
		},
	},
);

// Connecting to the core
if (!core.account) core.account = account;
