/**
 * Available spaces:
 *
 * _window.$usb - Basic object for mounting and initializing all extensions of the builder
 * _window.$usbcore - Auxiliary functions for the builder and its extensions
 * _window.$ush - US Helper Library
 *
 * Note: Double underscore `__funcname` is introduced for functions that are created through `$ush.debounce(...)`.
 */
! function( $, _undefined ) {

	const _window = window;

	if ( ! _window.$usb ) {
		return;
	}

	_window.$ush = _window.$ush || {};
	_window.$usbcore = _window.$usbcore || {};

	/**
	 * @class Panel - Basic panel functionality (left sidebar)
	 * @param {String} container The container
	 */
	function Panel( container ) {
		const self = this;

		// Bindable events
		self._events = {
			switch: self._switch.bind( self ),
			urlManager: self._urlManager.bind( self ),
		};

		$( () => {

			// Elements
			self.$container = $( container );
			self.$header = $( '.usb-panel-header', self.$container );
			self.$title = $( '.usb-panel-header-title', self.$header );
			self.$body = $( '.usb-panel-body', self.$container );
			self.$messages = $( '.usb-panel-messages', self.$container );

			// Actions
			self.$actionSaveChanges = $( '.usb_action_save_changes', self.$container );

			// Events
			self.$container
				// Switch show/hide panel
				.on( 'click', '.usb-panel-switcher', self._events.switch )
				// Save changes to the backend
				.on( 'click', '.usb_action_save_changes', () => {
					$usb.trigger( 'panel.saveChanges' ); // event for react in extensions
				} );
		} );

		// Private events
		$usb.on( 'urlManager.changed', self._events.urlManager );
	}

	// Panel API
	$.extend( Panel.prototype, {
		/**
		 * Determines if ready
		 *
		 * @return {Boolean} True if ready, False otherwise
		 */
		isReady: function() {
			return ! $ush.isUndefined( this.$container );
		},

		/**
		 * Check the panel is visible.
		 *
		 * @return {Boolean} true if the panel is visible.
		 */
		isVisible: function() {
			return ! $usb.$body.hasClass( 'hide_sidebars' );
		},

		/**
		 * Hide all sections in panel
		 */
		clearBody: function() {
			this.hideMessage();
			$usb.trigger( 'panel.clearBody' );
		},

		/**
		 * Reset scroll for the panel body
		 */
		resetBodyScroll: function() {
			this.$body[0].scrollTo( 0, 0 );
		},

		/**
		 * Set the header title
		 *
		 * @param {String} title The title
		 * @param {Boolean} isTranslationKey Is the key to translation
		 */
		setTitle: function ( title, isTranslationKey ) {
			const self = this;
			if ( self.isReady() && title ) {
				// Get text translation by key
				if ( isTranslationKey ) {
					title = $usb.getTextTranslation( title );
				}
				self.$title.html( typeof title === 'string' ? title : 'no_title' );
			}
		},

		/**
		 * Show the messages
		 *
		 * @param {String} text The message text
		 */
		showMessage: function( text ) {
			const self = this;
			self.clearBody();
			$usb.trigger( 'panel.showMessage', text );
			self.$messages.removeClass( 'hidden' ).html( text );
		},

		/**
		 * Hide the message
		 */
		hideMessage: function() {
			const self = this;
			if ( self.isReady() ) {
				self.$messages.addClass( 'hidden' ).html( '' );
			}
		},

		/**
		 * Switch show/hide panel
		 *
		 * @event handler
		 */
		_switch: function() {
			const self = this;

			$usb.$body.toggleClass( 'hide_sidebars', self.isVisible() );
			$usb.trigger( 'panel.switch', self.isVisible() );
			$usb.postMessage( 'changeSwitchPanel' );
		},

		/**
		 * Show the preloader
		 */
		showPreloader: function() {
			this.$container.addClass( 'show_preloader' );
		},

		/**
		 * Hide the preloader
		 */
		hidePreloader: function() {
			this.$container.removeClass( 'show_preloader' );
		},

		/**
		 * Switch for enable/disable save button
		 *
		 * @param {Boolean} enable The enable button
		 * @param {Boolean} isLoading indicates if loading
		 */
		switchSaveButton: function( enable, isLoading ) {
			this.$actionSaveChanges
				.prop( 'disabled', ! enable )
				.toggleClass( 'disabled', ! enable )
				.toggleClass( 'loading', isLoading === true ? enable : false );
		},

		/**
		 * Handler of change or move event on the history stack
		 *
		 * @event handler
		 * @param {{}|undefined} state Data object associated with history and current location
		 */
		_urlManager: function( state ) {
			const self = this;

			if ( ! self.isReady() ) {
				return;
			}

			const _siteSettings = $usb.config( 'actions.site_settings' );
			if ( state.setParams.action === _siteSettings ) {
				$( '.usb_action_add_elms', self.$header ).addClass( 'hidden' );
				$( '.usb_action_go_to_back', self.$header ).removeClass( 'hidden' );
			}
			else if( state.oldParams.action === _siteSettings ) {
				$( '.usb_action_add_elms', self.$header ).removeClass( 'hidden' );
				$( '.usb_action_go_to_back', self.$header ).addClass( 'hidden' );
			}
		}
	} );

	// Export API
	$usb.panel = new Panel( /* container */'#usb-panel' );

}( jQuery );
