(function($) {
	'use strict';

	const cfg = window.wppsMediaReplace || {};
	const ajaxUrl = cfg.ajaxUrl || '';
	const nonce = cfg.nonce || '';
	const strings = cfg.strings || {};

	let currentAttachmentId = 0;
	let compatibleExtensions = [];
	let currentFile = null;

	function formatBytes(bytes) {
		if (bytes === 0) {
			return '0 B';
		}
		const k = 1024;
		const sizes = ['B', 'KB', 'MB', 'GB'];
		const i = Math.floor(Math.log(bytes) / Math.log(k));
		return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
	}

	function showModal() {
		$('#wpps-replace-media-modal')
			.addClass('is-open')
			.show()
			.attr('aria-hidden', 'false');
		$('body').addClass('modal-open');
	}

	function hideModal() {
		$('#wpps-replace-media-modal')
			.removeClass('is-open')
			.hide()
			.attr('aria-hidden', 'true');
		$('body').removeClass('modal-open');
		resetModal();
	}

	function resetModal() {
		currentAttachmentId = 0;
		currentFile = null;
		$('#wpps-replace-file-input').val('');
		$('#wpps-replace-submit').prop('disabled', true);
		$('#wpps-replace-file-label').text(strings.chooseFile || 'Choose file');
		$('#wpps-replace-current-info').hide();
		$('#wpps-replace-progress').hide();
		$('#wpps-replace-result').hide();
	}

	function loadAttachmentInfo(attachmentId) {
		$.post(ajaxUrl, {
			action: 'wpps_media_replace_info',
			nonce: nonce,
			attachment_id: attachmentId
		}).done(function(res) {
			if (!res.success || !res.data) {
				return;
			}

			const d = res.data;
			currentAttachmentId = d.attachment_id;
			compatibleExtensions = d.compatible && d.compatible.extensions ? d.compatible.extensions : [];

			$('#wpps-replace-current-info').show();
			$('#wpps-replace-filename').text(d.filename || '');

			if (d.preview_url) {
				if (d.preview_url.indexOf('/wp-includes/images/media/') !== -1 || d.preview_url.indexOf('media/default.png') !== -1) {
					$('#wpps-replace-preview-img').hide();
					$('#wpps-replace-preview-icon').css('backgroundImage', 'url("' + d.preview_url + '")').show();
				} else {
					$('#wpps-replace-preview-img').attr('src', d.preview_url).show();
					$('#wpps-replace-preview-icon').hide();
				}
			}

			const metaParts = [];
			if (d.mime) {
				metaParts.push(d.mime);
			}
			if (d.size) {
				metaParts.push(formatBytes(d.size));
			}
			if (d.width && d.height) {
				metaParts.push(d.width + ' × ' + d.height);
			}
			$('#wpps-replace-meta').text(metaParts.join(' · '));

			const label = d.compatible && d.compatible.label ? d.compatible.label : '';
			$('#wpps-replace-type-hint').text(label ? (strings.uploadNewFile || 'Upload new file') + ': ' + label : '');

			if (compatibleExtensions.length) {
				$('#wpps-replace-file-input').attr('accept', compatibleExtensions.map(function(ext) {
					return '.' + ext;
				}).join(','));
			} else {
				$('#wpps-replace-file-input').removeAttr('accept');
			}
		}).fail(function() {
			alert(strings.error || 'An error occurred.');
		});
	}

	function resolveAttachmentId($scope) {
		const $root = $scope && $scope.length ? $scope : $('.edit-attachment-frame:visible, .media-modal:visible').first();

		if ($root.length) {
			const $input = $root.find('input[type="hidden"][id^="attachments-"]').first();
			if ($input.length) {
				const match = $input.attr('id').match(/attachments-(\d+)-/);
				if (match) {
					return parseInt(match[1], 10);
				}
			}
		}

		const urlMatch = window.location.search.match(/[?&]item=(\d+)/);
		if (urlMatch) {
			return parseInt(urlMatch[1], 10);
		}

		if (window.wp && wp.media && wp.media.frames && wp.media.frames.edit && wp.media.frames.edit.model) {
			return wp.media.frames.edit.model.get('id');
		}

		if (window.wp && wp.media && wp.media.frame) {
			const selection = wp.media.frame.state().get('selection');
			if (selection && selection.first()) {
				return selection.first().get('id');
			}
		}

		return 0;
	}

	function injectReplaceControls($scope, attachmentId) {
		const $root = $scope && $scope.length ? $scope : $('.edit-attachment-frame:visible, .media-modal:visible').first();
		if (!$root.length) {
			return;
		}

		const id = attachmentId || resolveAttachmentId($root);
		if (!id) {
			return;
		}

		const label = strings.replaceMedia || 'Replace Media';
		const escapedLabel = $('<div>').text(label).html();

		$root.find('.wpps-replace-media-grid-actions').remove();
		$root.find('.attachment-info .actions .wpps-replace-media-trigger').remove();

		const $editActions = $root.find('.attachment-actions').first();
		if (!$editActions.length) {
			return;
		}

		$editActions.find('.wpps-replace-media-trigger').remove();
		$editActions.append(
			'<button type="button" class="button wpps-replace-media-trigger" data-attachment-id="' + id + '">' + escapedLabel + '</button>'
		);
	}

	function scheduleInject($scope, attachmentId) {
		window.setTimeout(function() {
			injectReplaceControls($scope, attachmentId);
		}, 0);
		window.setTimeout(function() {
			injectReplaceControls($scope, attachmentId);
		}, 150);
	}

	function extendMediaViewRender(ViewClass, callback) {
		if (!ViewClass) {
			return ViewClass;
		}

		return ViewClass.extend({
			render: function() {
				const result = ViewClass.prototype.render.apply(this, arguments);
				callback.call(this, this.$el);
				return result;
			}
		});
	}

	function initMediaGridIntegration() {
		if (!$('#wp-media-grid').length || !window.wp || !wp.media) {
			return;
		}

		function onViewRender($el) {
			const attachmentId = this.model ? this.model.get('id') : 0;
			scheduleInject($el, attachmentId);
		}

		if (wp.media.view.Attachment && wp.media.view.Attachment.Details && wp.media.view.Attachment.Details.TwoColumn) {
			wp.media.view.Attachment.Details.TwoColumn = extendMediaViewRender(
				wp.media.view.Attachment.Details.TwoColumn,
				onViewRender
			);
		}

		if (wp.media.view.AttachmentCompat) {
			wp.media.view.AttachmentCompat = extendMediaViewRender(
				wp.media.view.AttachmentCompat,
				onViewRender
			);
		}

		$(document).on('click', '#wp-media-grid .attachment, .edit-attachment-frame .edit-attachment', function() {
			scheduleInject();
		});

		if (wp.media.frame) {
			wp.media.frame.on('edit:attachment', function() {
				scheduleInject();
			});
		}

		scheduleInject();
	}

	$(document).on('click', '.wpps-replace-media-trigger', function(e) {
		e.preventDefault();
		const attachmentId = $(this).data('attachment-id');
		if (!attachmentId) {
			return;
		}

		resetModal();
		loadAttachmentInfo(attachmentId);
		showModal();
	});

	$(document).on('click', '#wpps-replace-cancel, .wpps-replace-media-modal-backdrop', function(e) {
		e.preventDefault();
		hideModal();
	});

	$(document).on('change', '#wpps-replace-file-input', function() {
		const input = this;
		const file = input.files && input.files[0];
		if (file) {
			const ext = (file.name.split('.').pop() || '').toLowerCase();
			if (compatibleExtensions.length && compatibleExtensions.indexOf(ext) === -1) {
				alert(strings.invalidFileType || 'The selected file type is not compatible with the original.');
				input.value = '';
				currentFile = null;
				$('#wpps-replace-submit').prop('disabled', true);
				return;
			}
			currentFile = file;
			$('#wpps-replace-file-label').text(file.name);
			$('#wpps-replace-submit').prop('disabled', false);
		} else {
			currentFile = null;
			$('#wpps-replace-file-label').text(strings.chooseFile || 'Choose file');
			$('#wpps-replace-submit').prop('disabled', true);
		}
	});

	$(document).on('click', '#wpps-replace-submit', function() {
		if (!currentFile || !currentAttachmentId) {
			alert(strings.selectFile || 'Please select a file.');
			return;
		}

		const submitBtn = $('#wpps-replace-submit');
		const progressDiv = $('#wpps-replace-progress');
		const progressBar = $('#wpps-replace-progress-bar');
		const progressText = $('#wpps-replace-progress-text');
		const resultDiv = $('#wpps-replace-result');

		submitBtn.prop('disabled', true);
		progressDiv.show();
		progressBar.attr('value', 0);
		progressText.text(strings.uploading || 'Uploading...');

		const formData = new FormData();
		formData.append('action', 'wpps_media_replace');
		formData.append('nonce', nonce);
		formData.append('attachment_id', currentAttachmentId);
		formData.append('keep_filename', $('#wpps-replace-keep-filename').is(':checked') ? '1' : '0');
		formData.append('keep_date', $('#wpps-replace-keep-date').is(':checked') ? '1' : '0');
		formData.append('keep_backup', $('#wpps-replace-keep-backup').is(':checked') ? '1' : '0');
		formData.append('file', currentFile);

		$.ajax({
			url: ajaxUrl,
			type: 'POST',
			data: formData,
			processData: false,
			contentType: false,
			xhr: function() {
				const xhr = new window.XMLHttpRequest();
				if (xhr.upload) {
					xhr.upload.addEventListener('progress', function(evt) {
						if (evt.lengthComputable) {
							progressBar.attr('value', Math.round((evt.loaded / evt.total) * 90));
						} else {
							progressBar.attr('value', 50);
						}
					}, false);
				}
				return xhr;
			}
		}).done(function(res) {
			progressBar.attr('value', 100);
			progressText.text(strings.processing || 'Processing...');

			if (res.success) {
				progressText.text(strings.success || 'Replacement complete. Reloading...');
				resultDiv.removeClass('error').addClass('success').text(strings.success || 'Replacement complete.').show();
				window.setTimeout(function() {
					window.location.reload();
				}, 800);
			} else {
				progressDiv.hide();
				resultDiv.removeClass('success').addClass('error').text(res.data && res.data.message ? res.data.message : strings.error).show();
				submitBtn.prop('disabled', false);
			}
		}).fail(function(xhr) {
			progressDiv.hide();
			let msg = strings.error || 'An error occurred.';
			if (xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) {
				msg = xhr.responseJSON.data.message;
			}
			resultDiv.removeClass('success').addClass('error').text(msg).show();
			submitBtn.prop('disabled', false);
		});
	});

	$(document).on('keydown', function(e) {
		if (e.key === 'Escape' && $('#wpps-replace-media-modal').hasClass('is-open')) {
			hideModal();
		}
	});

	initMediaGridIntegration();
})(jQuery);
