/**
 * Custom JS script loaded on Admin pages
 *
 * @package   GravityView-Calendar-Ext
 * @license   GPL2+
 * @author    Katz Web Services, Inc.
 * @link      https://www.gravitykit.com
 * @copyright Copyright 2019, Katz Web Services, Inc.
 *
 * globals jQuery, ClipboardJS
 */

( function ( $ ) {

	var gvCalendarAdmin;

	gvCalendarAdmin = {

		initSettings: function () {

			$( 'body' ).on( 'change', '.gform_settings_form, .gforms_form_settings', gvCalendarAdmin.toggleCheckboxes );

			gvCalendarAdmin.toggleRequired( '.gform_settings_form, .gforms_form_settings', 'requires' );

			/**
			 * Hide the URL field and the buttons when the "Enable feed" setting is not enabled.
			 * toggleCheckboxes only allows for one `requires` at a time.
			 */
			$( '#enable-ics-feed' ).on( 'change gv-calendar-loaded', function () {
				$( '#gv-calendar-ics-url-buttons' ).toggle( ( $( '#export-ics-url' ).val() !== '' ) );
			} ).trigger( 'gv-calendar-loaded' );


			var successTimeout, clipboard = new ClipboardJS( '.copy-attachment-url' );
			clipboard.on( 'success', function ( e ) {
				var triggerElement = $( e.trigger ),
					successElement = $( '.success', triggerElement.closest( 'div' ) );
				e.clearSelection();
				triggerElement.trigger( 'focus' );
				clearTimeout( successTimeout );
				successElement.removeClass( 'hidden' );
				successTimeout = setTimeout( function () {
					successElement.addClass( 'hidden' );
					if ( clipboard.clipboardAction.fakeElem && clipboard.clipboardAction.removeFake ) {
						clipboard.clipboardAction.removeFake();
					}
				}, 3000 );

				wp.a11y.speak( gvCalendarStrings.copiedText );
			} );

			$( '.button-primary.gfbutton' ).addClass( 'button-hero' );

			$( '.controls-tray' ).sortable( {
				connectWith: '.calendar-controls-sortable',
				helper: function ( e, li ) {
					this.copyHelper = li.clone().insertAfter( li );
					$( this ).data( 'copied', false );
					return li.clone();
				},
				stop: function () {
					var copied = $( this ).data( 'copied' );
					if ( !copied ) {
						this.copyHelper.remove();
					}
					this.copyHelper = null;
				},
				receive: function ( e, ui ) {
					ui.item.remove();
				},
			} );

			$( '.controls-drop' ).sortable( {
				connectWith: '.calendar-controls-sortable',
				placeholder: 'sortable-placeholder',
				refreshPositions: true,
				receive: function ( e, ui ) {
					ui.sender.data( 'copied', true );
				},
				start: function ( event, ui ) {
					$( ui.placeholder ).height( ui.helper.height() );
					$( ui.placeholder ).width( ui.helper.width() );
				},
				change: function ( event, ui ) {
					$( ui.placeholder ).height( ui.helper.height() );
					$( ui.placeholder ).width( ui.helper.width() );
				},
				update: function ( e, ui ) {

					var controlSettings = gvCalendarAdmin.generateControlSettings();

					$( 'input[name$="_setting_controls"]' ).val( JSON.stringify( controlSettings ) );

					gvCalendarAdmin.updateLivePreview( controlSettings );
				},
			} );

			$( document ).on( 'gv_calendar_rendered', function ( event, calendar ) {
				gvCalendarAdmin.handleRenderedCalendar( calendar );
			} );
		},

		toggleCheckboxes: function ( e ) {
			gvCalendarAdmin.toggleRequired( e.currentTarget, 'requires' );
		},

		toggleRequired: function ( currentTarget, data_attr ) {
			var $parent = $( currentTarget );

			$parent.find( '[data-' + data_attr + ']' )
			.each( function () {
				var requires = $( this ).data( data_attr ),
					requires_array = requires.split( '=' ),
					requires_name = requires_array[ 0 ],
					requires_value = requires_array[ 1 ];

				var $input = $parent.find( ':input[id="' + requires_name + '"]' );

				if ( $input.is( '[type="checkbox"]' ) || $input.is( '[type="radio"]' ) ) {
					$( this ).parents( '.gform-settings-field, tr' ).toggle( $input.is( ':checked' ) );
				} else if ( requires_value !== undefined ) {
					$( this ).parents( '.gform-settings-field, tr' ).toggle( ( $input.val() === requires_value ) );
				}
			} );
		},

		generateControlSettings: function () {
			var controlSettings = {};

			$( '.controls-drop' ).each( function ( k, v ) {
				var controlSection = $( this ).attr( 'id' );
				var buttons = [];

				$( this ).find( 'li' ).each( function () {
					buttons.push( $( this ).data( 'button-id' ) );
				} );

				controlSettings[ controlSection ] = buttons;
			} );

			return controlSettings;
		},

		/**
		 * @param {string} zone Control zone for calendar. Either "top" or "bottom".
		 * @param {array} settings The array of settings generated by generateControlSettings
		 * @return {object} Object with left, center, and right properties
		 */
		prepareControl: function ( zone, settings ) {
			var sanitizeValue = function ( value ) {
				return value.toString().replace( /,?space,?/g, ' ' ).trim();
			};

			var zone = {
				left: sanitizeValue( settings[ 'controls-' + zone + '-left' ] ),
				center: sanitizeValue( settings[ 'controls-' + zone + '-center' ] ),
				right: sanitizeValue( settings[ 'controls-' + zone + '-right' ] ),
			};


			return zone;
		},

		/**
		 * Update the live preview calendar with the currently-configured controls
		 */
		updateLivePreview: function ( settings ) {
			Object.keys( window.gvCalendar ).forEach( function ( calendarId ) {
				var calendar = gvFullCalendar.getCalendar( calendarId );

				if ( !calendar ) {
					return;
				}
				calendar.instance.setOption( 'headerToolbar', gvCalendarAdmin.prepareControl( 'top', settings ) );
				calendar.instance.setOption( 'footerToolbar', gvCalendarAdmin.prepareControl( 'bottom', settings ) );
			} );
		},

		/**
		 * Allow modifying rendered calendar
		 *
		 * @param {object} calendar FullCalendar object
		 */
		handleRenderedCalendar: function ( calendar ) {
			if ( !calendar || !calendar.hasOwnProperty( 'instance' ) ) {
				return;
			}

			if ( calendar.instance.hasOwnProperty( 'el' ) && !$( calendar.instance.el ).hasClass( 'calendar-preview' ) ) {
				return;
			}

			var feed_id = parseInt( calendar.instance.el.dataset.feed_id, 10 );
			var calendar_id = calendar.instance.el.dataset.calendar_id;

			// If a new feed was created, refresh the page with the correct feed ID (GF 2.5+ properly sets feed ID URL parameter upon feed creation)
			if ( window.location.href.match( /fid=0/ ) && feed_id ) {
				window.location.replace( window.location.href.replace( /&(amp;|#038;)?fid=0/, '&$1fid=' + feed_id ) );
			}

			// Set locale if this is a new (unsaved) feed
			if ( !calendar.instance.getOption( 'locale' ) ) {
				var calendar_locale = $( 'select[name="_gaddon_setting_localization"]' ).val() || 'en';

				gvFullCalendar.changeLocale( calendar_locale, calendar_id );
			}

			// Conditionally display preview notice
			if ( calendar.extraOptions.calendar_preview_notice ) {
				jQuery( '.calendar-preview-notice' ).show().addClass( 'notice below-h2 notice-warning is-dismissible' ).html( '<p>' + calendar.extraOptions.calendar_preview_notice );
			}
		},

	};

	gvCalendarAdmin.initSettings();

	$( document ).on( 'ready', function () {
		new ClipboardJS( '.gk-calendar-shortcode input.code', {
			text: function ( trigger ) {
				return $( trigger ).val();
			}
		} );

		$('.gk-calendar-shortcode input.code').on('click', function (e) {
			e.preventDefault();
			var $el = $(this).closest('.gk-calendar-shortcode').find('.copied');
			$el.show();
			setTimeout(function () {
				$el.fadeOut();
			}, 1000);
		});

		$( '#_gform_setting_is_secure' ).on( 'change', function () {
			var $embedShortcodeEl = $( '.gk-calendar-shortcode > input' );
			var embedShortcode = $embedShortcodeEl.val();
			var secret = $embedShortcodeEl.data( 'secret' );

			if ( !embedShortcode ) {
				return;
			}

			if ( $( this ).is( ':checked' ) ) {
				embedShortcode = embedShortcode.replace( / \//, ` secret="${secret}" /` );
			} else {
				embedShortcode = embedShortcode.replace( / secret=[^\/]*\//, ' /' );
			}

			$embedShortcodeEl.val( embedShortcode );
		} );
	} );

}( jQuery ) );
