/* =======================================
   GLOBALS FOR EXPORT CENTRAL
   ======================================= */

import { Blocker } from '../../../../../../atum-stock-manager-for-woocommerce/assets/js/src/components/_blocker';
import EnhancedSelect from '../../../../../../atum-stock-manager-for-woocommerce/assets/js/src/components/_enhanced-select';
import ExportSettings from '../../config/_export-settings';
import { Entity } from "../../utils/_interfaces";
import MappedField from './_mapped-field';
import Progress from './_progress';
import SelectedField from './_selected-field';
import Summary from './_summary';
import Tooltip from '../../../../../../atum-stock-manager-for-woocommerce/assets/js/src/components/_tooltip';

export default class Globals {
	
	entities: Entity[] = [];
	mainEntity: Entity;
	subentities: Entity[] = [];
	selectedFields: JQuery[] = [];
	mappedFields: MappedField[] = [];
	templateId: number;
	
	$wrapper: JQuery;
	$contentWrapper: JQuery;
	$entitySection: JQuery;
	$selectionSection: JQuery;
	$summarySection: JQuery;
	$templateDataSection: JQuery;
	$importMappingSection: JQuery;
	$progress: JQuery;
	$nav: JQuery;
	$fieldSelectors: JQuery;
	$selectedFieldsWrapper: JQuery;
	$mappedFieldsWrapper: JQuery;
	$exportActions: JQuery;
	
	progress: Progress;
	summary: Summary;
	
	enhancedSelect: EnhancedSelect;
	tooltip: Tooltip;
	
	swal: any = window['swal'];
	isReadyToExport: boolean = false;
	currentTab: string;
	
	constructor(
		protected settings: ExportSettings
	) {
		
		this.initProps();
		
	}
	
	/**
	 * Initialize the global props
	 */
	initProps() {
		
		this.$wrapper = $('#atum-export');
		this.$nav = this.$wrapper.find('#export-menu');
		this.enhancedSelect = new EnhancedSelect();
		this.tooltip = new Tooltip(false);
		
		switch (this.currentTab) {
			
			case 'export-center':
				this.$contentWrapper = this.$wrapper.find('.export-content');
				this.$entitySection = this.$wrapper.find('#export-init');
				this.$selectionSection = this.$wrapper.find('#export-selection');
				this.$summarySection = this.$wrapper.find('#export-summary');
				this.$templateDataSection = this.$wrapper.find('#template-data');
				this.$progress = this.$wrapper.find('#export-progress');
				this.$fieldSelectors = this.$entitySection.find('.field-selectors');
				this.$selectedFieldsWrapper = this.$selectionSection.find('.selected-fields');
				this.$exportActions = this.$summarySection.find('.export-actions');
				
				this.templateId = this.$templateDataSection.data('id') || null;
				this.summary = new Summary(this.settings, this);
				
				break;
				
			case 'import-center':
				this.$importMappingSection = this.$wrapper.find('#import-mapping');
				this.$mappedFieldsWrapper = this.$importMappingSection.find('.mapped-fields');
				this.$exportActions = this.$importMappingSection.find('.export-actions');
				this.$progress = this.$wrapper.find('#export-progress');
				
				break;
				
			case 'getting-started':
				this.$contentWrapper = this.$wrapper.find('.getting-started');
				break;
				
			case 'templates':
				this.$contentWrapper = this.$wrapper.find('.templates-list');
				break;
		}
		
	}
	
	/**
	 * Load the entities from the data coming from the server
	 *
	 * @param {any} entityData
	 */
	loadEntities(entityData: any) {
		
		if (entityData.hasOwnProperty('subentities') && !$.isEmptyObject(entityData.subentities)) {
			
			for (const subentity in entityData.subentities) {
				this.subentities.push(entityData.subentities[subentity]);
				delete entityData.subentities[subentity];
			}
			
		}
		
		this.mainEntity = { ...entityData, isMain: true };
		this.entities = [ ...[ this.mainEntity ], ...this.subentities ];
		
		//console.log(this.entities);
		
	}
	
	/**
	 * Find an entity within the loaded entities knowing its name
	 *
	 * @param {string} entityName
	 *
	 * @return {Entity|null}
	 */
	findEntity(entityName: string): Entity|null {
		
		const foundEntity = this.entities.filter( (ent: Entity) => {
			return ent.name === entityName;
		});
		
		return foundEntity.length ? foundEntity[0] : null;
		
	}
	
	/**
	 * Hide/Show the export zone if it contains selected/mapped fields or not
	 */
	maybeShowDroppingZone() {
		
		const $droppingSection: JQuery = this.currentTab === 'export-center' ? this.$selectionSection : this.$importMappingSection,
		      $droppingZone: JQuery    = $droppingSection.find('.add-data-zone'),
		      $actionButtons: JQuery   = $droppingSection.find('.export-actions').find('button');
		
		if ( ( this.currentTab === 'export-center' && this.hasSelectedFields() ) || ( this.currentTab === 'import-center' && this.hasMappedFields() ) ) {
			$droppingZone.hide();
			$actionButtons.prop('disabled', false);
		}
		else {
			$droppingZone.show();
			$actionButtons.prop('disabled', true);
		}
		
	}
	
	/**
	 * As some switchers are being initialized before the field is added to the DOM,
	 * the switchery plugin is not setting the jack's position correclty, so we need
	 * a way to set the position once the field is finally added
	 *
	 * @param {JQuery} $checkbox
	 */
	fixSwitchers($checkbox: JQuery) {
		
		$checkbox.each( (index: number, elem: Element) => {
			
			const switcheryInstance: any = $(elem).data('switchery-instance');
			
			if (typeof switcheryInstance !== 'undefined') {
				switcheryInstance.setPosition();
			}
			
		});
		
	}
	
	/**
	 * Check whether the current template has any selected field
	 *
	 * @return {boolean}
	 */
	hasSelectedFields(): boolean {
		return this.$selectedFieldsWrapper.find('.selected-field').length !== 0;
	}
	
	/**
	 * Check whether the current template has any mapped field
	 *
	 * @return {boolean}
	 */
	hasMappedFields(): boolean {
		return this.$mappedFieldsWrapper.find('.mapped-field').length !== 0;
	}
	
	/**
	 * Rearrange the position select for all the fields
	 *
	 * @param {boolean} updatePositions
	 */
	rearrangePositionSelects(updatePositions: boolean = false) {
		
		this.$selectedFieldsWrapper.find('.selected-field').each( (index: number, elem: Element) => {
			
			const selectedField: SelectedField = $(elem).data('selected-field'),
			      positionIndex: number        = $(elem).index('.selected-field');
			
			selectedField.field.settings.position = positionIndex;
			selectedField.$fieldPosition.val(positionIndex).trigger('change.select2');
			
			if (updatePositions === true) {
				selectedField.adjustFieldPosition();
			}
			
			selectedField.rearrangePositionSelect();
			
		});
		
	}
	
	/**
	 * Check whether the current template has enough data to run the export
	 */
	maybeIsReadyToExport() {
	
		if (this.hasSelectedFields()) {
			this.isReadyToExport = true;
			this.$exportActions.find('.alert').show();
			this.$exportActions.find('#run-export').prop('disabled', false);
		}
		else {
			this.isReadyToExport = false;
			this.$exportActions.find('.alert').hide();
			this.$exportActions.find('#run-export').prop('disabled', true);
		}
	
	}
	
	/**
	 * Loop every selected field and build the data JSON to be saved in the template
	 *
	 * @return {any[]}
	 */
	getTemplateData(): any[] {
		
		let data: any[] = [];
		
		this.$selectedFieldsWrapper.find('.selected-field').each( (index: number, elem: Element) => {
			
			const $elem: JQuery                = $(elem),
			      selectedField: SelectedField = $elem.data('selected-field');
			
			data.push({
				name    : selectedField.field.name,
				entity  : selectedField.entity.name,
				group   : selectedField.field.group,
				type    : selectedField.field.type,
				settings: $elem.find('.selected-field--settings > input[type=hidden]').val() || '',
				filters : $elem.find('.selected-field--filters > input[type=hidden]').val() || '',
			});
			
		});
		
		return data;
	
	}
	
	/**
	 * Submit the settings' form and run an export
	 *
	 * @param {any} exportParams
	 */
	runExport(exportParams: any) {
		
		const data: any = {
			action: 'aep_run_export',
			token : this.settings.get('nonce'),
		};
		
		$.ajax({
			url       : window['ajaxurl'],
			dataType  : 'json',
			method    : 'post',
			data      : {...data, ...exportParams},
			beforeSend: () => Blocker.block(this.$contentWrapper),
			success   : (response: any) => {
				
				if (response.success === true) {
					
					this.swal({
						title            : this.settings.get('downloadReady'),
						html             : `<a class="atum-link" href="${ decodeURI(response.data) }" download>${ this.settings.get('download') }</a>`,
						type             : 'success',
						confirmButtonText: this.settings.get('ok'),
						allowOutsideClick: false,
					});
					
					// Move to the last step.
					this.progress.setStep(3);
					
				}
				else {
					
					this.swal({
						title            : this.settings.get('error'),
						text             : response.data,
						type             : 'error',
						confirmButtonText: this.settings.get('ok'),
						allowOutsideClick: false,
					});
					
				}
				
				Blocker.unblock(this.$contentWrapper)
				
			},
			error     : () => Blocker.unblock(this.$contentWrapper),
		});
		
	}
	
}