/**
 * Script for syncing in WP-admin.
 *
 * @package northmill-online-shared
 */

/* global northmill_online_shared_admin_sync */
jQuery( document ).ready(
	function () {
		new NMF_Ajax_Syncer();
	}
);


class NMF_Ajax_Syncer {
	constructor() {
		this.btn_force_sync         = jQuery( "#mf_sync_now" );
		this.btn_resume_sync        = jQuery( "#mf_sync_resume" );
		this.input_auto_resume_sync = jQuery( "#mf_sync_auto_resume" );
		this.textareaStatus         = jQuery( "#mf_sync_status" );
		this.get_all_data_checkbox  = jQuery( '#nmf_get_all_data' );
		this.nonce                  = this.btn_force_sync.data( "nonce" );
		this.current_request        = {};
		this.get_all_data           = true;

		this.reset_sync_status();

		// Bindings.
		this.start_sync                   = this.start_sync.bind( this );
		this.handle_sync_request_response = this.handle_sync_request_response.bind( this );
		this.handle_ajax_error            = this.handle_ajax_error.bind( this );
		this.handle_sync_error            = this.handle_sync_error.bind( this );
		this.attempt_resume_sync          = this.attempt_resume_sync.bind( this );
		this.run_tool                     = this.run_tool.bind( this );
		this.tool_ajax_success            = this.tool_ajax_success.bind( this );
		this.tool_ajax_error              = this.tool_ajax_error.bind( this );

		// Events.
		this.btn_force_sync.click( this.start_sync );
		this.btn_resume_sync.click( this.attempt_resume_sync );
		jQuery( '.nms-admin-sync-tool' ).click( this.run_tool );

		jQuery( '.nmf-ajax-sync-filter' ).click(
			function ( event ) {
				if ( event.ctrlKey ) {
					event.preventDefault();
					if ( ! jQuery( this ).is( ':checked' ) ) {
						jQuery( '.nmf-ajax-sync-filter' ).not( this ).prop( 'checked', false );
					} else {
						jQuery( '.nmf-ajax-sync-filter' ).not( this ).prop( 'checked', true );
					}
				}
			}
		);
	}

	reset_sync_status() {
		this.current_request = {
			'action': 0,
		}
	}

	start_sync(e) {
		e.preventDefault();
		this.toggle_button( 0 );
		this.textareaStatus.show();
		this.get_all_data = this.get_all_data_checkbox.is( ':checked' );
		this.get_all_data_checkbox.attr( 'disabled', 'disabled' );

		this.sync_ajax_request();
	}

	sync_ajax_requests_completed() {
		this.reset_sync_status();
		alert( northmill_online_shared_admin_sync.sync_completed );
		this.toggle_button( 1 );
		this.get_all_data_checkbox.removeAttr( 'disabled' );
	}

	/**
	 * Ajax request.
	 *
	 * @param add_started_text Whether to add the started text to the textarea.
	 * @param account Number of the Hub account to sync.
	 * @param page Number of the page to sync.
	 */
	sync_ajax_request(
		add_started_text = true,
		account = 0,
		page = 0
	) {
		const _this           = this;
		const action_name     = northmill_online_shared_admin_sync.ajax_sync_actions[ this.current_request.action ].action;
		const nonce           = northmill_online_shared_admin_sync.ajax_sync_actions[ this.current_request.action ].nonce;
		const nonce_query_arg = northmill_online_shared_admin_sync.ajax_sync_actions[ this.current_request.action ].nonce_query_arg;
		const $enabled_input  = jQuery( '#enabled_' + this.current_request.action );

		this.current_request.action_name      = action_name;
		this.current_request.add_started_text = add_started_text;
		this.current_request.account          = account;
		this.current_request.page             = page;

		if ( add_started_text ) {
			this.update_sync_status( 'started', action_name );
		}

		if ( $enabled_input.length && ! $enabled_input.is( ':checked' ) ) {
			this.update_sync_status( 'skipped', action_name );
			_this.run_next_sync_action();
			return false;
		}

		const data = {
			action: action_name,
			page: page,
			account: account,
			page_size: jQuery( '#mf_sync_per_page' ).val(),
			get_all_data: this.get_all_data,
		};

		data[ nonce_query_arg ] = nonce;

		this.ajax_request(
			data,
			_this.handle_sync_request_response,
			_this.handle_sync_error,
			300000
		);
	}

	run_next_sync_action() {
		this.current_request.action++;

		if ( this.current_request.action < northmill_online_shared_admin_sync.ajax_sync_actions.length ) {
			this.sync_ajax_request();
		} else {
			this.sync_ajax_requests_completed();
		}
	}

	run_tool( event ) {
		const $btn = jQuery( event.currentTarget );
		$btn.attr( 'disabled', 'disabled' );
		this.textareaStatus.show();

		const tool_id   = $btn.data( 'id' );
		const ajax_data = northmill_online_shared_admin_sync.tools[ tool_id ];

		const action          = ajax_data.action;
		const nonce           = ajax_data.nonce;
		const nonce_query_arg = ajax_data.nonce_query_arg;

		const data = {};

		data[ 'action' ]        = action;
		data[ nonce_query_arg ] = nonce;
		this.update_sync_status( 'action_started', ajax_data.title, false );

		this.ajax_request( data, this.tool_ajax_success, this.tool_ajax_error );
	}

	tool_ajax_success( response ) {
		if ( 'undefined' !== typeof response.success && response.success ) {
			let message = '';
			if ( 'undefined' !== typeof response.data ) {
				message = 'undefined' !== typeof response.data.message ? response.data.message : response.data;
			}
			this.update_sync_status( 'action_completed', '', message );
		} else {
			let message = '';
			if ( 'undefined' !== typeof response.data && 'undefined' !== typeof response.data[0] ) {
				message = 'undefined' !== typeof response.data[0] && 'undefined' !== typeof response.data[0].message ? response.data[0].message : response.data;
			}
			this.update_sync_status( 'action_failed', '', message );
		}
	}

	tool_ajax_error( jqXHR, textStatus, errorThrown ) {
		console.log( jqXHR, textStatus, errorThrown );
		const message = textStatus + ( 'string' === typeof errorThrown ? ': ' + errorThrown : '' );
		this.update_sync_status( 'action_failed', '', message );
	}

	ajax_request(
		data,
		success_callback,
		error_callback = this.handle_ajax_error,
		timeout = 10000
	) {
		jQuery.ajax(
			{
				type: "post",
				dataType: "json",
				timeout: timeout,
				url: ajaxurl,
				data: data,
				success: success_callback,
				error: error_callback
			}
		);
	}

	handle_ajax_error( response ) {
		console.log( response );
		this.update_sync_status( 'error' );
	}

	handle_sync_request_response( response ) {
		const _this = this;

		if ( 'undefined' !== typeof response.success && response.success ) {
			if ( response.data.skipped ) {
				_this.update_sync_status( 'skipped', this.current_request.action_name );
				_this.run_next_sync_action();
			} else if ( response.data.cleaned ) {
				_this.update_sync_status( 'cleaned', this.current_request.action_name );
				_this.run_next_sync_action();
			} else {

				if ( response.data.total_pages > ( response.data.page + 1 ) ) { // There are pages left for sync.
					_this.update_sync_status( 'processed', this.current_request.action_name, response.data );
					_this.sync_ajax_request( false, this.current_request.account, response.data.page + 1 );

				} else if ( response.data.has_cleaner ) { // Syncer has a cleaner.
					_this.update_sync_status( 'processed', this.current_request.action_name, response.data );
					_this.sync_ajax_request( false, this.current_request.account, 'cleaner' );

				} else if ( response.data.total_accounts > ( this.current_request.account + 1 ) ) { // There are accounts left for sync.
					_this.update_sync_status( 'processed', this.current_request.action_name, response.data );
					_this.sync_ajax_request( false, this.current_request.account + 1, 0 );

				} else { // Sync is completed, got to next.
					_this.update_sync_status( 'processed', this.current_request.action_name, response.data );
					_this.update_sync_status( 'completed', this.current_request.action_name, response.data );
					_this.run_next_sync_action();
				}
			}
		} else {
			_this.handle_sync_error( response );
		}
	}

	/**
	 * Reattempt last ajax request.
	 */
	attempt_resume_sync() {
		this.btn_resume_sync.hide();
		this.sync_ajax_request(
			this.current_request.add_started_text,
			this.current_request.account,
			this.current_request.page
		);
	}

	handle_sync_error() {
		if ( this.input_auto_resume_sync.is( ':checked' ) ) {
			this.update_sync_status( 'error_resume' );
			this.attempt_resume_sync();
		} else {
			this.update_sync_status( 'error' );
			this.btn_resume_sync.show();
		}
	}

	update_sync_status( action, action_name = '', data = [] ) {
		let message = '';

		if ( 'started' === action ) {
			message += northmill_online_shared_admin_sync.sync_start_processing_sync + ' ' + this.get_readable_current_action_name( action_name );
		} else if ( 'completed' === action ) {
			message += northmill_online_shared_admin_sync.sync_completed_processing + ' ' + this.get_readable_current_action_name( action_name ) + "\n";
		} else if ( 'processed' === action ) {
			message += northmill_online_shared_admin_sync.sync_processed + ' ' + ( data.page + 1 ) + '/' + data.total_pages + ' ' +
				northmill_online_shared_admin_sync.sync_processed_for_account + ' ' + ( data.account + 1 ) + '/' + data.total_accounts;
		} else if ( 'skipped' === action ) {
			message += northmill_online_shared_admin_sync.sync_skipped_processing + ' ' + this.get_readable_current_action_name( action_name ) + "\n";
		} else if ( 'cleaned' === action ) {
			message += northmill_online_shared_admin_sync.sync_cleaned + ' ' + this.get_readable_current_action_name( action_name ) + "\n";
		} else if ( 'error' === action ) {
			message += northmill_online_shared_admin_sync.sync_error + "\n";
		} else if ( 'error_resume' === action ) {
			message += northmill_online_shared_admin_sync.sync_error_resume + "\n";
		} else if ( 'action_started' === action ) {
			message += northmill_online_shared_admin_sync.action_started + ' ' + action_name + "\n";
			if ( data ) {
				message += data + "\n";
			}
		} else if ( 'action_completed' === action ) {
			message += northmill_online_shared_admin_sync.action_completed + "\n";
			if ( data ) {
				message += data + "\n";
			}
		} else if ( 'action_failed' === action ) {
			message += northmill_online_shared_admin_sync.action_failed + "\n";
			if ( data ) {
				message += data + "\n";
			}
		}

		this.textareaStatus.append( message + "\n" );

		this.textareaStatus.animate(
			{
				scrollTop:this.textareaStatus[0].scrollHeight - this.textareaStatus.height()
			},
			10
		);
	}

	get_readable_current_action_name() {
		return northmill_online_shared_admin_sync.ajax_sync_actions[ this.current_request.action ].title;
	}

	toggle_button( state ) {
		if (state) {
			this.btn_force_sync.removeAttr( 'disabled' );
		} else {
			this.btn_force_sync.attr( 'disabled', 'disabled' );
		}
	}
}
