
import window from 'window';
import ko from 'ko';

import {DesktopNotification, Magics} from 'Common/Enums';
import * as Events from 'Common/Events';
import Audio from 'Common/Audio';

import * as Settings from 'Storage/Settings';

class NotificationUserStore
{
	constructor() {
		this.enableSoundNotification = ko.observable(false);
		this.soundNotificationIsSupported = ko.observable(false);

		this.allowDesktopNotification = ko.observable(false);

		this.desktopNotificationPermissions = ko.computed(() => {

			this.allowDesktopNotification();

			let result = DesktopNotification.NotSupported;

			const NotificationClass = this.notificationClass();
			if (NotificationClass && NotificationClass.permission)
			{
				switch (NotificationClass.permission.toLowerCase())
				{
					case 'granted':
						result = DesktopNotification.Allowed;
						break;
					case 'denied':
						result = DesktopNotification.Denied;
						break;
					case 'default':
						result = DesktopNotification.NotAllowed;
						break;
					// no default
				}
			}
			else if (window.webkitNotifications && window.webkitNotifications.checkPermission)
			{
				result = window.webkitNotifications.checkPermission();
			}

			return result;

		}).extend({notify: 'always'});

		this.enableDesktopNotification = ko.computed({
			read: () => this.allowDesktopNotification() && DesktopNotification.Allowed === this.desktopNotificationPermissions(),
			write: (value) => {
				if (value)
				{
					const
						NotificationClass = this.notificationClass(),
						permission = this.desktopNotificationPermissions();

					if (NotificationClass && DesktopNotification.Allowed === permission)
					{
						this.allowDesktopNotification(true);
					}
					else if (NotificationClass && DesktopNotification.NotAllowed === permission)
					{
						NotificationClass.requestPermission(() => {

							this.allowDesktopNotification.valueHasMutated();

							if (DesktopNotification.Allowed === this.desktopNotificationPermissions())
							{
								if (this.allowDesktopNotification())
								{
									this.allowDesktopNotification.valueHasMutated();
								}
								else
								{
									this.allowDesktopNotification(true);
								}
							}
							else
							{
								if (this.allowDesktopNotification())
								{
									this.allowDesktopNotification(false);
								}
								else
								{
									this.allowDesktopNotification.valueHasMutated();
								}
							}
						});
					}
					else
					{
						this.allowDesktopNotification(false);
					}
				}
				else
				{
					this.allowDesktopNotification(false);
				}
			}
		}).extend({notify: 'always'});

		if (!this.enableDesktopNotification.valueHasMutated)
		{
			this.enableDesktopNotification.valueHasMutated = () => {
				this.allowDesktopNotification.valueHasMutated();
			};
		}

		this.computers();

		this.initNotificationPlayer();
	}

	computers() {
		this.isDesktopNotificationSupported = ko.computed(
			() => DesktopNotification.NotSupported !== this.desktopNotificationPermissions()
		);

		this.isDesktopNotificationDenied = ko.computed(
			() => DesktopNotification.NotSupported === this.desktopNotificationPermissions() ||
				DesktopNotification.Denied === this.desktopNotificationPermissions()
		);
	}

	initNotificationPlayer() {
		if (Audio && Audio.supportedNotification)
		{
			this.soundNotificationIsSupported(true);
		}
		else
		{
			this.enableSoundNotification(false);
			this.soundNotificationIsSupported(false);
		}
	}

	playSoundNotification(skipSetting) {
		if (Audio && Audio.supportedNotification && (skipSetting ? true : this.enableSoundNotification()))
		{
			Audio.playNotification();
		}
	}

	displayDesktopNotification(imageSrc, title, text, nessageData) {
		if (this.enableDesktopNotification())
		{
			const
				NotificationClass = this.notificationClass(),
				notification = NotificationClass ? new NotificationClass(title, {
					body: text,
					icon: imageSrc
				}) : null;

			if (notification)
			{
				if (notification.show)
				{
					notification.show();
				}

				if (nessageData)
				{
					notification.onclick = () => {

						window.focus();

						if (nessageData.Folder && nessageData.Uid)
						{
							Events.pub('mailbox.message.show', [nessageData.Folder, nessageData.Uid]);
						}
					};
				}

				window.setTimeout((function(localNotifications) {
					return () => {
						if (localNotifications.cancel)
						{
							localNotifications.cancel();
						}
						else if (localNotifications.close)
						{
							localNotifications.close();
						}
					};
				}(notification)), Magics.Time7s);
			}
		}
	}

	populate() {
		this.enableSoundNotification(!!Settings.settingsGet('SoundNotification'));
		this.enableDesktopNotification(!!Settings.settingsGet('DesktopNotifications'));
	}

	/**
	 * @returns {*|null}
	 */
	notificationClass() {
		return window.Notification && window.Notification.requestPermission ? window.Notification : null;
	}
}

export default new NotificationUserStore();
