(function($) {

	wp_optimize.asset_preload = wp_optimize.asset_preload || {};

	// The backbone views
	var Views = {
		/**
		 * Main view
		 */
		app: Backbone.View.extend({
			initialize: function() {
				this.$no_items = this.$el.find('.nothing');
				this.$list = $('.asset-preload-list tbody');
				if ('function' === typeof URL) {
					this.home_url = new URL(wp_optimize_minify_premium.home_url);
				}
				this.listenTo(wp_optimize.asset_preload.items, 'add', this.add_item);
				this.listenTo(wp_optimize.asset_preload.items, 'remove', this.check_contents);
				this.render();
			},
			events: {
				'click .add-asset': 'on_add_asset_press'
			},
			render: function() {
				if (!wp_optimize.asset_preload.items.length) {
					this.$no_items.show();
				} else {
					this.$no_items.hide();
					wp_optimize.asset_preload.items.each(function(item) {
						this.add_item(item);
					}, this);
				}
			},
			check_contents: function() {
				if (!wp_optimize.asset_preload.items.length) {
					this.$no_items.show();
				} else {
					this.$no_items.hide();
				}

			},
			on_add_asset_press: function(e) {
				e.preventDefault();
				this.show_form('add', '.asset-preload-list tbody', new Backbone.Model({href:'', type:'', crossorigin:''}));
			},
			show_form: function(action, where, model) {
				var options = {
					action: action,
					where: where
				};
				if (model) options.model = model;
				if (this.form) this.form.remove();
				this.form = new Views.form(options);
				this.$el.find('.add-asset, .asset-edit button').hide();
				$(where).after(this.form.$el);
			},
			hide_form: function() {
				this.$el.find('.add-asset, .asset-edit button').show();
				this.form.remove();
			},
			add_item: function(item) {
				this.$no_items.hide();
				var v = new Views.item({model: item});
				this.$list.append(v.$el);
			}

		}),
		/**
		 * Form view
		 */
		form: Backbone.View.extend({
			tagName: 'tr',
			className: 'form',
			template: wp.template('wpo-asset-preload--form'),
			events: {
				'click .cancel': 'cancel',
				'click .add-item': 'add_item',
				'change #preload_href': 'detect_values',
				'keypress #preload_href': 'on_keypress'
			},
			initialize: function(options) {
				this.options = options;
				this.render();
				this.$href = this.$el.find('#preload_href');
				this.$type = this.$el.find('#preload_type');
				this.$crossorigin = this.$el.find('#preload_crossorigin');
				if (this.model && this.model.get('type')) {
					this.$type.val(this.model.get('type'));
				}
			},
			render: function() {
				this.$el.append(this.template(this.model.attributes));
				if ('edit' === this.options.action) {
					this.$el.find('.add-item').text(this.$el.find('.add-item').data('alt-label'));
				}
			},
			cancel: function() {
				wp_optimize.asset_preload.app.hide_form();
				$(this.options.where).trigger('cancelled-edit');
			},
			add_item: function() {
				if ('' == this.$href.val().trim()) return;
				if ('add' === this.options.action) {
					wp_optimize.asset_preload.items.add({
						href: this.$href.val(),
						type: this.$type.val(),
						crossorigin: this.$crossorigin.is(':checked')
					});
				} else {
					wp_optimize.asset_preload.items.remove(this.model);
					wp_optimize.asset_preload.items.add({
						href: this.$href.val(),
						type: this.$type.val(),
						crossorigin: this.$crossorigin.is(':checked')
					});
				}
				wp_optimize.asset_preload.app.hide_form();
				setTimeout(function() {
					$('#wpo_minify_settings_form .wp-optimize-save-minify-settings').trigger('click');
				}, 1200);
			},
			detect_values: function(e) {
				var url = this.$href.val();
				// Autodetect the type for the most common assets
				if (type = detect_asset_type(url)) {
					this.$type.val(type);
				}

				// Autodetect the crossorigin value
				if (wp_optimize.asset_preload.app.home_url) {
					var parsed_url = new URL(url, wp_optimize.asset_preload.app.home_url.origin);
					if (parsed_url.host != wp_optimize.asset_preload.app.home_url.host) {
						this.$crossorigin.prop('checked', true);
					}
				}

			},
			on_keypress: function(e) {
				if ('Enter' == e.code) {
					e.preventDefault();
					if (this.$href.val().length) {
						e.target.blur();
						this.add_item();
					}
				}
			}
		}),
		/**
		 * Single item view
		 */
		item: Backbone.View.extend({
			tagName: 'tr',
			template: wp.template('wpo-asset-preload--item'),
			events: {
				'click .wpo-asset--edit': 'edit',
				'click .wpo-asset--delete': 'delete_item',
				'cancelled-edit': 'cancel'
			},
			initialize: function() {
				this.render();
				this.listenTo(this.model, 'change', this.render);
				this.listenTo(this.model, 'destroy', this.remove);
			},
			render: function() {
				this.$el.removeClass('editing');
				this.$el.html(this.template(this.model.attributes));
			},
			edit: function() {
				this.$el.addClass('editing');
				wp_optimize.asset_preload.app.show_form('edit', this.$el, this.model);
			},
			delete_item: function() {
				// wp_optimize.asset_preload.items.remove(this.model);
				this.model.destroy();
				setTimeout(function() {
					$('#wpo_minify_settings_form .wp-optimize-save-minify-settings').trigger('click');
				}, 1200);
			},
			cancel: function() {
				this.$el.removeClass('editing');
			}
		})
	}

	/**
	 * Run when the collection changes
	 * (Updates the input)
	 *
	 * @param {object} model
	 * @param {array}  collection
	 */
	function on_collection_change(model, collection) {
		// Update the input field with every change
		$('#hpreload').val(JSON.stringify(collection));
		$('#hpreload').trigger('change');
	}

	/**
	 * Detect the type of asset (for the main types)
	 *
	 * @param {string} resource
	 */
	function detect_asset_type(resource) {
		switch (get_url_extension(resource)) {
			case 'js':
			case 'json':
				return 'script';
			case 'jpg':
			case 'jpeg':
			case 'png':
			case 'gif':
			case 'webp':
				return 'image';
			case 'css':
				return 'style';
			case 'eot':
			case 'ttf':
			case 'woff':
			case 'woff2':
				return 'font';
		}
		return false;
	}

	/**
	 * Cross-browser file name extension extraction
	 *
	 * @param {string} url
	 */
	function get_url_extension(url) {
		return url.split(/[#?]/)[0].split('.').pop().trim().toLowerCase();
	}

	// DOM ready
	$(function () {
		var raw_data = $('#hpreload').val();

		if (raw_data) {
			try {
				data = JSON.parse(raw_data);
			} catch(e) {
				data = [];
				console.log('There was an error parsing the data:', e, raw_data);
			}
		} else {
			data = [];
		}

		/**
		 * Store the items in a collection
		 */
		var Items = new Backbone.Collection(data);

		/**
		 * Add event hanglers on the collection
		 */
		Items.on('change', on_collection_change);
		Items.on('add', on_collection_change);
		Items.on('remove', on_collection_change);

		wp_optimize.asset_preload.raw_data = raw_data;
		wp_optimize.asset_preload.items = Items;

		/**
		 * Initialize the main view
		 */
		wp_optimize.asset_preload.app = new Views.app({
			el: $('.asset-preload-main')
		});
	});
})(jQuery);
