(function ($) {
	'use strict';

	var cfg = window.wpdudeDcAdmin || {};
	var i18n = cfg.i18n || {};
	var maxOptions = cfg.maxOptions || 5;

	function toggleTypeFields() {
		var isOptions = $('#wpdude_dc_product_type').val() === 'options';
		$('.wpdude-dc-standard-fields').prop('hidden', isOptions);
		$('#wpdude-dc-options-wrap').prop('hidden', !isOptions);
		$('#wpdude-dc-options-standard-note').prop('hidden', isOptions);
	}

	function toggleShipping() {
		var isFlat = $('#wpdude_dc_shipping_type').val() === 'flat';
		$('.wpdude-dc-shipping-amount').prop('hidden', !isFlat);
	}

	function updateCurrencyLabels() {
		var code = ($('#wpdude_dc_currency').val() || '').toString().toUpperCase();
		$('.wpdude-dc-currency-code').text(code);
	}

	function syncGalleryInput() {
		var ids = [];
		$('.wpdude-dc-gallery-list li').each(function () {
			ids.push($(this).data('id'));
		});
		$('#wpdude_dc_gallery_ids').val(ids.join(','));
	}

	function escapeHtml(str) {
		return $('<div/>').text(str == null ? '' : String(str)).html();
	}

	function nextOptionIndex() {
		var max = -1;
		$('#wpdude-dc-option-defs .wpdude-dc-option-row').each(function () {
			var idx = parseInt($(this).attr('data-option-index'), 10);
			if (!isNaN(idx) && idx > max) {
				max = idx;
			}
		});
		return max + 1;
	}

	function expandValueLabels(raw) {
		return String(raw || '')
			.split(',')
			.map(function (part) {
				return $.trim(part);
			})
			.filter(Boolean);
	}

	function valueRowHtml(optIndex, value) {
		return (
			'<li class="wpdude-dc-option-value-row">' +
			'<input type="text" name="wpdude_dc_option_value[' +
			optIndex +
			'][]" value="' +
			escapeHtml(value || '') +
			'" class="regular-text wpdude-dc-option-value-label" placeholder="' +
			escapeHtml(i18n.valuePlaceholder || 'e.g. S, M, L') +
			'" /> ' +
			'<button type="button" class="button-link-delete wpdude-dc-remove-value">' +
			(i18n.remove || 'Remove') +
			'</button>' +
			'</li>'
		);
	}

	function optionRowHtml() {
		var optIndex = nextOptionIndex();
		return (
			'<div class="wpdude-dc-option-row" data-option-index="' +
			optIndex +
			'">' +
			'<p><label><strong>' +
			(i18n.optionName || 'Option name') +
			'</strong></label><br />' +
			'<input type="text" name="wpdude_dc_option_name[' +
			optIndex +
			']" value="" class="regular-text wpdude-dc-option-name" placeholder="' +
			escapeHtml(i18n.namePlaceholder || 'e.g. Size') +
			'" /></p>' +
			'<p><strong>' +
			(i18n.values || 'Values') +
			'</strong> <span class="description">— one row per value, or type S, M, L in one row</span></p>' +
			'<ul class="wpdude-dc-option-values">' +
			valueRowHtml(optIndex, '') +
			'</ul>' +
			'<p><button type="button" class="button wpdude-dc-add-value">' +
			(i18n.addValue || 'Add value') +
			'</button> ' +
			'<button type="button" class="button-link-delete wpdude-dc-remove-option">Remove option</button></p>' +
			'<hr /></div>'
		);
	}

	function expandCommaSeparatedValueRows() {
		$('#wpdude-dc-option-defs .wpdude-dc-option-row').each(function () {
			var $option = $(this);
			var optIndex = $option.attr('data-option-index');
			var $list = $option.find('.wpdude-dc-option-values');
			var labels = [];
			var seen = {};

			$list.find('.wpdude-dc-option-value-row').each(function () {
				expandValueLabels($(this).find('.wpdude-dc-option-value-label').val()).forEach(function (label) {
					var key = label.toLowerCase();
					if (seen[key]) {
						return;
					}
					seen[key] = true;
					labels.push(label);
				});
			});

			if (!labels.length) {
				return;
			}

			$list.empty();
			labels.forEach(function (label) {
				$list.append(valueRowHtml(optIndex, label));
			});
		});
	}

	function parseOptions() {
		var options = [];
		$('#wpdude-dc-option-defs .wpdude-dc-option-row').each(function () {
			var $row = $(this);
			var name = $.trim($row.find('.wpdude-dc-option-name').val() || '');
			if (!name) {
				return;
			}
			var values = [];
			var seen = {};
			$row.find('.wpdude-dc-option-value-row').each(function () {
				expandValueLabels($(this).find('.wpdude-dc-option-value-label').val()).forEach(function (label) {
					var key = label.toLowerCase();
					if (seen[key]) {
						return;
					}
					seen[key] = true;
					values.push(label);
				});
			});
			if (!values.length) {
				return;
			}
			options.push({ name: name, values: values });
		});
		return options.slice(0, maxOptions);
	}

	function cartesian(options) {
		var combos = [{}];
		options.forEach(function (opt) {
			var next = [];
			combos.forEach(function (combo) {
				opt.values.forEach(function (value) {
					var row = $.extend({}, combo);
					row[opt.name] = value;
					next.push(row);
				});
			});
			combos = next;
		});
		return options.length ? combos : [];
	}

	function combinationKey(opts) {
		var keys = Object.keys(opts).sort(function (a, b) {
			return a.toLowerCase().localeCompare(b.toLowerCase());
		});
		return keys
			.map(function (k) {
				return k.toLowerCase() + '=' + String(opts[k]).toLowerCase();
			})
			.join('|');
	}

	function existingCombinationMap() {
		var map = {};
		$('#wpdude-dc-combinations-body tr').each(function () {
			var $tr = $(this);
			if ($tr.hasClass('wpdude-dc-no-combinations')) {
				return;
			}
			var key = $tr.find('input[name^="wpdude_dc_combo_key"]').val();
			if (!key) {
				return;
			}
			map[key] = {
				sku: $tr.find('input[name^="wpdude_dc_combo_sku"]').val() || '',
				price: $tr.find('input[name^="wpdude_dc_combo_price"]').val() || '',
				sale: $tr.find('input[name^="wpdude_dc_combo_sale_price"]').val() || '',
				stock: $tr.find('input[name^="wpdude_dc_combo_stock"]').val() || '0',
				image: $tr.find('.wpdude-dc-combo-image-id').val() || '0',
				preview: $tr.find('.wpdude-dc-combo-image-preview').html()
			};
		});
		return map;
	}

	function combinationRows() {
		return $('#wpdude-dc-combinations-body tr').not('.wpdude-dc-no-combinations');
	}

	function getMasters() {
		return {
			price: $.trim($('#wpdude_dc_combo_default_price').val() || ''),
			sale: $.trim($('#wpdude_dc_combo_default_sale').val() || ''),
			stock: $.trim($('#wpdude_dc_combo_default_stock').val() || ''),
			skuPrefix: $.trim($('#wpdude_dc_combo_sku_prefix').val() || '')
		};
	}

	function samePriceEnabled() {
		return $('#wpdude_dc_same_price_all').is(':checked');
	}

	function sameStockEnabled() {
		return $('#wpdude_dc_same_stock_all').is(':checked');
	}

	function applyPriceSaleToRows(fillEmptyOnly) {
		var masters = getMasters();
		combinationRows().each(function () {
			var $tr = $(this);
			var $price = $tr.find('input[name^="wpdude_dc_combo_price"]');
			var $sale = $tr.find('input[name^="wpdude_dc_combo_sale_price"]');
			if (!fillEmptyOnly || !$.trim($price.val() || '')) {
				$price.val(masters.price);
			}
			if (!fillEmptyOnly || !$.trim($sale.val() || '')) {
				$sale.val(masters.sale);
			}
		});
	}

	function applyStockToRows(fillEmptyOnly) {
		var masters = getMasters();
		var stock = masters.stock !== '' ? masters.stock : '0';
		combinationRows().each(function () {
			var $stock = $(this).find('input[name^="wpdude_dc_combo_stock"]');
			var current = $.trim($stock.val() || '');
			if (fillEmptyOnly && current !== '') {
				return;
			}
			$stock.val(stock);
		});
	}

	function applyMastersToAll() {
		applyPriceSaleToRows(false);
		applyStockToRows(false);
	}

	function fillEmptyMasters() {
		applyPriceSaleToRows(true);
		applyStockToRows(true);
	}

	function mirrorSamePrice() {
		if (!samePriceEnabled()) {
			return;
		}
		applyPriceSaleToRows(false);
	}

	function mirrorSameStock() {
		if (!sameStockEnabled()) {
			return;
		}
		applyStockToRows(false);
	}

	function sanitizeSkuPart(raw) {
		return String(raw || '')
			.trim()
			.toUpperCase()
			.replace(/[^A-Z0-9]+/g, '-')
			.replace(/^-+|-+$/g, '');
	}

	function buildComboSku(prefix, optionDefs, opts) {
		var parts = [];
		var p = sanitizeSkuPart(prefix);
		if (p) {
			parts.push(p);
		}
		optionDefs.forEach(function (opt) {
			var part = sanitizeSkuPart(opts[opt.name] || '');
			if (part) {
				parts.push(part);
			}
		});
		return parts.join('-');
	}

	function parseComboOptionsFromRow($tr) {
		var opts = {};
		$tr.find('input[name^="wpdude_dc_combo_opt"]').each(function () {
			var name = $(this).attr('name') || '';
			var match = name.match(/wpdude_dc_combo_opt\[\d+\]\[(.+)\]$/);
			if (match) {
				opts[match[1]] = $(this).val() || '';
			}
		});
		return opts;
	}

	function generateSkus(overwrite) {
		var masters = getMasters();
		if (!masters.skuPrefix) {
			window.alert(i18n.needSkuPrefix || 'Enter a SKU prefix first.');
			return;
		}
		var $rows = combinationRows();
		if (!$rows.length) {
			window.alert(i18n.needCombinations || 'Generate combinations first.');
			return;
		}
		var optionDefs = parseOptions();
		$rows.each(function () {
			var $tr = $(this);
			var $sku = $tr.find('input[name^="wpdude_dc_combo_sku"]');
			var current = $.trim($sku.val() || '');
			if (!overwrite && current) {
				return;
			}
			var opts = parseComboOptionsFromRow($tr);
			$sku.val(buildComboSku(masters.skuPrefix, optionDefs, opts));
		});
	}

	function openComboImageFrame($cell) {
		var frame = wp.media({
			title: i18n.selectImage || 'Select combination image',
			button: { text: i18n.useImage || 'Use image' },
			multiple: false
		});
		frame.on('select', function () {
			var attachment = frame.state().get('selection').first().toJSON();
			var url =
				(attachment.sizes && attachment.sizes.thumbnail && attachment.sizes.thumbnail.url) ||
				attachment.url;
			$cell.find('.wpdude-dc-combo-image-id').val(attachment.id);
			$cell.find('.wpdude-dc-combo-image-preview').html('<img src="' + url + '" alt="" />');
		});
		frame.open();
	}

	function renderCombinationRows(combos, existing, optionDefs) {
		var $tbody = $('#wpdude-dc-combinations-body');
		var masters = getMasters();
		$tbody.empty();
		if (!combos.length) {
			$tbody.append(
				'<tr class="wpdude-dc-no-combinations"><td colspan="6">No combinations yet. Add options and click Generate combinations.</td></tr>'
			);
			return;
		}
		combos.forEach(function (opts, i) {
			var key = combinationKey(opts);
			var prev = existing[key] || {};
			var hadPrev = !!existing[key];
			var labelParts = [];
			Object.keys(opts).forEach(function (name) {
				labelParts.push(name + ': ' + opts[name]);
			});
			var hiddenOpts = Object.keys(opts)
				.map(function (name) {
					return (
						'<input type="hidden" name="wpdude_dc_combo_opt[' +
						i +
						'][' +
						escapeHtml(name) +
						']" value="' +
						escapeHtml(opts[name]) +
						'" />'
					);
				})
				.join('');
			var preview = prev.preview || i18n.noImage || 'No image';
			var price = hadPrev && prev.price ? prev.price : masters.price || '';
			var sale = hadPrev && prev.sale ? prev.sale : masters.sale || '';
			var stock = hadPrev ? prev.stock || '0' : masters.stock !== '' ? masters.stock : '0';
			var sku = prev.sku || '';
			if (!sku && masters.skuPrefix) {
				sku = buildComboSku(masters.skuPrefix, optionDefs, opts);
			}
			$tbody.append(
				'<tr>' +
					'<td><strong>' +
					escapeHtml(labelParts.join(' / ')) +
					'</strong>' +
					'<input type="hidden" name="wpdude_dc_combo_key[' +
					i +
					']" value="' +
					escapeHtml(key) +
					'" />' +
					hiddenOpts +
					'</td>' +
					'<td><input type="text" name="wpdude_dc_combo_sku[' +
					i +
					']" value="' +
					escapeHtml(sku) +
					'" class="regular-text" /></td>' +
					'<td><input type="text" name="wpdude_dc_combo_price[' +
					i +
					']" value="' +
					escapeHtml(price) +
					'" class="small-text" placeholder="10.00" /></td>' +
					'<td><input type="text" name="wpdude_dc_combo_sale_price[' +
					i +
					']" value="' +
					escapeHtml(sale) +
					'" class="small-text" /></td>' +
					'<td><input type="number" name="wpdude_dc_combo_stock[' +
					i +
					']" value="' +
					escapeHtml(stock) +
					'" class="small-text" min="0" step="1" /></td>' +
					'<td class="wpdude-dc-combo-image-cell">' +
					'<input type="hidden" name="wpdude_dc_combo_image[' +
					i +
					']" value="' +
					escapeHtml(String(prev.image || '0')) +
					'" class="wpdude-dc-combo-image-id" />' +
					'<span class="wpdude-dc-combo-image-preview">' +
					preview +
					'</span> ' +
					'<button type="button" class="button wpdude-dc-combo-image-select">' +
					(i18n.select || 'Select') +
					'</button> ' +
					'<button type="button" class="button-link wpdude-dc-combo-image-clear">' +
					(i18n.clear || 'Clear') +
					'</button>' +
					'</td>' +
					'</tr>'
			);
		});

		if (samePriceEnabled()) {
			applyPriceSaleToRows(false);
		}
		if (sameStockEnabled()) {
			applyStockToRows(false);
		}
	}

	$(function () {
		toggleTypeFields();
		toggleShipping();
		updateCurrencyLabels();

		$('#wpdude_dc_product_type').on('change', toggleTypeFields);
		$('#wpdude_dc_shipping_type').on('change', toggleShipping);
		$('#wpdude_dc_currency').on('change', updateCurrencyLabels);

		$('#wpdude_dc_gallery_add').on('click', function (e) {
			e.preventDefault();
			var frame = wp.media({
				title: i18n.selectImages || 'Select gallery images',
				button: { text: i18n.useImages || 'Use images' },
				multiple: true
			});
			frame.on('select', function () {
				var selection = frame.state().get('selection');
				selection.each(function (attachment) {
					attachment = attachment.toJSON();
					if ($('.wpdude-dc-gallery-list li[data-id="' + attachment.id + '"]').length) {
						return;
					}
					var url =
						(attachment.sizes && attachment.sizes.thumbnail && attachment.sizes.thumbnail.url) ||
						attachment.url;
					$('.wpdude-dc-gallery-list').append(
						'<li data-id="' +
							attachment.id +
							'"><img src="' +
							url +
							'" alt="" /><button type="button" class="button-link wpdude-dc-gallery-remove" aria-label="Remove">&times;</button></li>'
					);
				});
				syncGalleryInput();
			});
			frame.open();
		});

		$(document).on('click', '.wpdude-dc-gallery-remove', function (e) {
			e.preventDefault();
			$(this).closest('li').remove();
			syncGalleryInput();
		});

		$('#wpdude_dc_add_option').on('click', function (e) {
			e.preventDefault();
			var count = $('#wpdude-dc-option-defs .wpdude-dc-option-row').length;
			if (count >= maxOptions) {
				window.alert(i18n.optionLimit || 'Maximum of 5 options.');
				return;
			}
			$('#wpdude-dc-option-defs').append(optionRowHtml());
		});

		$(document).on('click', '.wpdude-dc-remove-option', function (e) {
			e.preventDefault();
			var $rows = $('#wpdude-dc-option-defs .wpdude-dc-option-row');
			if ($rows.length <= 1) {
				$rows.find('.wpdude-dc-option-name, .wpdude-dc-option-value-label').val('');
				return;
			}
			$(this).closest('.wpdude-dc-option-row').remove();
		});

		$(document).on('click', '.wpdude-dc-add-value', function (e) {
			e.preventDefault();
			var $option = $(this).closest('.wpdude-dc-option-row');
			var optIndex = $option.attr('data-option-index');
			$option.find('.wpdude-dc-option-values').append(valueRowHtml(optIndex, ''));
		});

		$(document).on('click', '.wpdude-dc-remove-value', function (e) {
			e.preventDefault();
			var $list = $(this).closest('.wpdude-dc-option-values');
			var $rows = $list.find('.wpdude-dc-option-value-row');
			if ($rows.length <= 1) {
				$rows.find('.wpdude-dc-option-value-label').val('');
				return;
			}
			$(this).closest('.wpdude-dc-option-value-row').remove();
		});

		$(document).on('click', '.wpdude-dc-combo-image-select', function (e) {
			e.preventDefault();
			openComboImageFrame($(this).closest('.wpdude-dc-combo-image-cell'));
		});

		$(document).on('click', '.wpdude-dc-combo-image-clear', function (e) {
			e.preventDefault();
			var $cell = $(this).closest('.wpdude-dc-combo-image-cell');
			$cell.find('.wpdude-dc-combo-image-id').val('0');
			$cell.find('.wpdude-dc-combo-image-preview').text(i18n.noImage || 'No image');
		});

		$('#wpdude_dc_same_price_all').on('change', function () {
			if ($(this).is(':checked')) {
				mirrorSamePrice();
			}
		});

		$('#wpdude_dc_same_stock_all').on('change', function () {
			if ($(this).is(':checked')) {
				mirrorSameStock();
			}
		});

		$('#wpdude_dc_combo_default_price, #wpdude_dc_combo_default_sale').on('input change', function () {
			mirrorSamePrice();
		});

		$('#wpdude_dc_combo_default_stock').on('input change', function () {
			mirrorSameStock();
		});

		$('#wpdude_dc_combo_apply_all').on('click', function (e) {
			e.preventDefault();
			if (!combinationRows().length) {
				window.alert(i18n.needCombinations || 'Generate combinations first.');
				return;
			}
			applyMastersToAll();
		});

		$('#wpdude_dc_combo_fill_empty').on('click', function (e) {
			e.preventDefault();
			if (!combinationRows().length) {
				window.alert(i18n.needCombinations || 'Generate combinations first.');
				return;
			}
			fillEmptyMasters();
		});

		$('#wpdude_dc_combo_generate_skus').on('click', function (e) {
			e.preventDefault();
			generateSkus($('#wpdude_dc_combo_sku_overwrite').is(':checked'));
		});

		$('#wpdude_dc_generate_combinations').on('click', function (e) {
			e.preventDefault();
			expandCommaSeparatedValueRows();
			var options = parseOptions();
			if (!options.length) {
				window.alert(i18n.needOptions || 'Add at least one option with values first.');
				return;
			}
			var existing = existingCombinationMap();
			var combos = cartesian(options);
			var $tbody = $('#wpdude-dc-combinations-body');
			if (!$tbody.length) {
				return;
			}
			renderCombinationRows(combos, existing, options);
		});
	});
})(jQuery);
