/* =======================================
   IMPORT CENTER
   ======================================= */

import { Blocker } from '../../../../../../atum-stock-manager-for-woocommerce/assets/js/src/components/_blocker';
import CustomInputFile from '../customInputFile';
import { Entity, Field } from '../../utils/_interfaces';
import ExportSettings from '../../config/_export-settings';
import Globals from './_globals';
import MappedField from './_mapped-field';
import Progress from './_progress';
import { Switcher } from '../../../../../../atum-stock-manager-for-woocommerce/assets/js/src/components/_switcher';
import AddMappingColumn from './_add-mapping-column';

export default class ImportCenter {
	
	$elem: JQuery = null;
	$form: JQuery = null;
	remoteFilePath: string = '';
	$mappingTableTmpl: string;
	
	constructor(
		private settings: ExportSettings,
		private globals: Globals
	) {
		
		this.$elem = this.globals.$wrapper.find('#import-settings');
		this.$form = this.$elem.find('form');
		this.$mappingTableTmpl = this.globals.$importMappingSection.find('#mapping-table-tmpl').html();
		this.globals.progress = new Progress(this.globals);
		
		// Add switchers
		Switcher.doSwitchers('.js-switch', {}, this.$elem);
		
		// Add select2.
		this.globals.enhancedSelect.doSelect2(this.$elem.find('.atum-select2'));
		
		// Custom input file.
		new CustomInputFile(this.$form.find('input[type=file]'), this.settings);
		
		// Init "Add mapping column" component.
		new AddMappingColumn(this.globals, this.settings);
		
		this.bindEvents();
		
	}
	
	bindEvents() {
	
		this.$form
			
			// Check all the required fields before enabling the submit button.
			.on('change', ':input[required]', () => {
		
				// Check that are the required fields have a value.
				const $emptyFields: JQuery = this.$form.find(':input[required]').filter( (index: number, elem: Element) => {
					return $(elem).val() === '';
				});
				
				this.$form.find('#load_file').prop('disabled', $emptyFields.length !== 0);
			
			})
		
			// Submit the form via Ajax.
			.on('submit', (evt: JQueryEventObject) => {
				
				evt.preventDefault();
				
				if (this.globals.hasMappedFields()) {
					
					this.globals.swal({
						title            : this.settings.get('areYouSure'),
						text             : this.settings.get('replaceMapped'),
						type             : 'warning',
						showCancelButton : true,
						reverseButtons   : true,
						confirmButtonText: this.settings.get('continue'),
						cancelButtonText : this.settings.get('cancel'),
					})
					.then( () => {
						this.globals.$mappedFieldsWrapper.find('.mapping-table').remove();
						this.globals.maybeShowDroppingZone();
						this.loadFile();
					})
					.catch( this.globals.swal.noop );
					
				}
				else {
					this.loadFile();
				}
				
			});
	
	}
	
	/**
	 * Load the file and prepare the mapping fields
	 */
	loadFile() {
		
		let formData = new FormData( (<HTMLFormElement>this.$form.get(0)) );
		
		// Send the form data as it were submitted normally.
		$.ajax({
			url        : `${ window['ajaxurl'] }?action=aep_load_import_file&token=${ this.settings.get('nonce') }`,
			type       : 'post',
			dataType   : 'json',
			data       : formData,
			cache      : false,
			contentType: false,
			processData: false,
			beforeSend : () => Blocker.block(this.$elem),
			success    : (response: any) => {
				
				if (response.success === false) {
					
					this.globals.swal({
						title            : this.settings.get('error'),
						text             : response.data,
						type             : 'error',
						confirmButtonText: this.settings.get('ok'),
						allowOutsideClick: false
					});
					
				}
				else {
					this.remoteFilePath = response.data.file_path || '';
					this.globals.loadEntities(response.data.entity);
					this.addMappedFields(response.data.file_data, response.data.template);
					this.globals.progress.setStep(2);
				}
				
				Blocker.unblock(this.$elem);
			},
			error: () => Blocker.unblock(this.$elem),
		});
	
	}
	
	/**
	 * Add the mapped fields to the mapping section
	 *
	 * @param {any[]} fileData
	 * @param {any[]} templateData
	 */
	addMappedFields(fileData: any[], templateData: any[]) {
		
		this.globals.mappedFields = [];
	
		if (!fileData.length || !templateData.length) {
			
			this.globals.swal({
				title            : this.settings.get('error'),
				text             : this.settings.get( !fileData.length ? 'invalidFileData' : 'invalidTemplateData' ),
				type             : 'error',
				confirmButtonText: this.settings.get('ok'),
				allowOutsideClick: false
			});
			
			return;
			
		}
		
		this.globals.$mappedFieldsWrapper.append(this.$mappingTableTmpl);
		
		const fileColumns: string[] = [];
		
		// Prepare the file columns dropdown.
		for (const column in fileData[0]) {
			fileColumns.push(column);
		}
		
		// Add all the template fields to the mapping section.
		templateData.forEach( (field: any) => {
			
			// Find the field's entity.
			const entity: Entity = this.globals.findEntity(field.entity);
			
			if (!entity) {
				return;
			}
			
			// Find the field object within the entity.
			const meta: any[]         = entity.meta || [],
			      fieldFound: Field[] = [...entity.fields, ...meta].filter( (entityfield: Field) => {
				      return entityfield.name === field.name && entityfield.group === field.group;
			      });
			
			if (!fieldFound.length) {
				return;
			}
			
			const mappedField: MappedField = new MappedField(fieldFound[0], entity, fileColumns, this.globals, this.settings);
			this.globals.mappedFields.push(mappedField);
			this.globals.$mappedFieldsWrapper.find('.mapping-table tbody').append(mappedField.$elem);
			
		});
		
		this.globals.maybeShowDroppingZone();
	
	}
	
}
