(function (global) {
	'use strict';

	// If the self-contained WordPress SDK is already loaded and functional, preserve and augment it
	if (global.WordPressSDK && typeof global.WordPressSDK.preview === 'function' && typeof global.WordPressSDK.generate === 'function') {
		if (typeof global.WordPressSDK.render !== 'function') {
			global.WordPressSDK.render = global.WordPressSDK.generate;
		}

		var nativeGenerate = global.WordPressSDK.generate;
		global.WordPressSDK.generate = function (args) {
			var format = (args && args.format) || (args && args.options && args.options.format) || 'pdf';
			var filename = (args && args.filename) || (args && args.options && args.options.filename) || 'document';
			var shouldDownload = !args || (args.download !== false && (!args.options || args.options.download !== false));

			// Suppress the native SDK's own auto-download (download:false) so we
			// control the filename+extension ourselves. We then fire exactly one
			// blob-based download below — no duplicate, correct filename every time.
			return nativeGenerate.call(global.WordPressSDK, Object.assign({}, args, {
				download: false,
				options: Object.assign({}, args ? args.options : {}, { download: false, filename: filename, format: format })
			})).then(function (result) {
				if (shouldDownload && result && result.blob && typeof global.document !== 'undefined') {
					var ext = format === 'png' ? 'png' : 'pdf';
					var safeName = filename;
					if (safeName.slice(-1 * (ext.length + 1)).toLowerCase() !== '.' + ext) {
						safeName += '.' + ext;
					}
					var url = global.URL.createObjectURL(result.blob);
					var link = global.document.createElement('a');
					link.href = url;
					link.download = safeName;
					global.document.body.appendChild(link);
					link.click();
					link.remove();
					global.URL.revokeObjectURL(url);
				}
				return result;
			});
		};

		if (!global.WordPressSDK.getBrowserSDK) {
			global.WordPressSDK.getBrowserSDK = function () {
				return global.BrowserSDK || (global.WordPressSDK && global.WordPressSDK.BrowserSDK) || null;
			};
		}
		return;
	}

	function getBrowserSDK() {
		var namespace = global.BrowserSDK;

		if (!namespace) {
			return null;
		}

		if (typeof namespace === 'function') {
			return namespace;
		}

		return namespace.BrowserSDK || namespace.default || null;
	}

	function normalizeTemplate(options) {
		return options.template_data || options.template || options.templateData || null;
	}

	function createLocalSdk(template) {
		var BrowserSDK = getBrowserSDK();

		if (!BrowserSDK) {
			throw new Error('100Prints BrowserSDK is not available.');
		}

		var sdk = new BrowserSDK({
			key: 'wordpress-local-template'
		});

		if (template) {
			sdk.fetchTemplateData = function () {
				return Promise.resolve(template);
			};
		}

		return sdk;
	}

	function withTemplateId(options, template) {
		var next = Object.assign({}, options);
		var renderOptions = next.options || {};

		if (!next.templateId) {
			next.templateId = template && template.id ? template.id : 'wordpress-local-template';
		}

		if (renderOptions.format && !next.format) {
			next.format = renderOptions.format;
		}

		if (renderOptions.quality && !next.quality) {
			next.quality = renderOptions.quality;
		}

		if (renderOptions.side && !next.side) {
			next.side = renderOptions.side;
		}

		delete next.template;
		delete next.template_data;
		delete next.templateData;
		delete next.options;

		return next;
	}

	function downloadBlob(blob, filename, mimeType) {
		var extension = mimeType === 'image/png' ? 'png' : 'pdf';
		var safeName = filename || 'document';

		if (safeName.slice(-1 * (extension.length + 1)).toLowerCase() !== '.' + extension) {
			safeName += '.' + extension;
		}

		var url = global.URL.createObjectURL(blob);
		var link = global.document.createElement('a');

		link.href = url;
		link.download = safeName;
		global.document.body.appendChild(link);
		link.click();
		link.remove();
		global.URL.revokeObjectURL(url);
	}

	global.WordPressSDK = {
		preview: function (options) {
			var template = normalizeTemplate(options);
			var sdk = createLocalSdk(template);

			return sdk.preview(withTemplateId(options, template));
		},

		render: function (options) {
			var template = normalizeTemplate(options);
			var sdk = createLocalSdk(template);

			return sdk.render(withTemplateId(options, template));
		},

		generate: function (options) {
			var template = normalizeTemplate(options);
			var sdk = createLocalSdk(template);

			return sdk.render(withTemplateId(options, template)).then(function (result) {
				downloadBlob(result.blob, options.filename, result.mimeType);
				return result;
			});
		},

		getBrowserSDK: getBrowserSDK
	};
})(window);
