/**
 * AIEO Product Options — storefront picker. Live price + min/max enforcement +
 * add-to-cart gating. The resolve() here MIRRORS the PHP price resolver
 * (AIEO_Option_Groups_Pricing) so the on-page total matches the cart exactly;
 * the server re-resolves authoritatively at add-to-cart time.
 */
(function ($) {
	'use strict';

	var cfgGlobal = window.aieoOG || {};
	var i18n = cfgGlobal.i18n || {};

	function fmt(tpl, a, b) { return String(tpl || '').replace('%1$d', a).replace('%2$s', b).replace('%d', a).replace('%s', b); }
	function round(n) { return Math.round(n * 10000) / 10000; }

	function resolveOptionPrice(option, rules, assignmentId, selected) {
		var best = null, bestScore = -1;
		(rules || []).forEach(function (r) {
			var scope = parseInt(r.scope_assignment_id, 10) || 0;
			if (scope !== 0 && scope !== assignmentId) { return; }
			var wg = parseInt(r.when_group_id, 10) || 0;
			if (wg !== 0) {
				var wo = parseInt(r.when_option_id, 10) || 0;
				if (wo === 0 || !selected[wo]) { return; }
			}
			var score = (scope !== 0 ? 2 : 0) + (wg !== 0 ? 1 : 0);
			if (score > bestScore) { best = r; bestScore = score; }
		});
		return best !== null ? parseFloat(best.price_delta) : parseFloat(option.price);
	}

	function resolve(cfg, selected) {
		var optIndex = {}, groupOf = {}, groupById = {};
		cfg.groups.forEach(function (g) {
			groupById[g.id] = g;
			g.options.forEach(function (o) { optIndex[o.id] = o; groupOf[o.id] = g.id; });
		});
		var rules = cfg.rules || {};

		var resolved = {};
		Object.keys(selected).forEach(function (oid) {
			oid = parseInt(oid, 10);
			var o = optIndex[oid]; if (!o) { return; }
			var g = groupById[groupOf[oid]];
			resolved[oid] = resolveOptionPrice(o, rules[oid] || [], g ? g.assignment_id : 0, selected);
		});

		var total = 0, lines = [];
		cfg.groups.forEach(function (g) {
			var sel = g.options.filter(function (o) { return selected[o.id]; });
			if (!sel.length) { return; }
			var freeN = g.included_free || 0;
			var policy = g.free_policy === 'cheapest_free' ? 'cheapest_free' : 'expensive_free';
			var pool = sel.filter(function (o) { return !o.premium; });
			var freeSet = {};
			if (freeN > 0 && pool.length) {
				pool.sort(function (a, b) {
					var pa = resolved[a.id] || 0, pb = resolved[b.id] || 0;
					return policy === 'cheapest_free' ? (pa - pb) : (pb - pa);
				});
				pool.slice(0, freeN).forEach(function (o) { freeSet[o.id] = true; });
			}
			sel.forEach(function (o) {
				var rd = resolved[o.id] || 0;
				var isFree = !!freeSet[o.id];
				var charged = isFree ? 0 : rd;
				total += charged;
				lines.push({ option_id: o.id, label: o.label, charged_delta: charged, free: isFree });
			});
		});

		var errors = [];
		cfg.groups.forEach(function (g) {
			var n = g.options.filter(function (o) { return selected[o.id]; }).length;
			if (g.min > 0 && n < g.min) { errors.push(fmt(i18n.chooseMin, g.min, g.name)); }
			if (g.max > 0 && n > g.max) { errors.push(fmt(i18n.chooseMax, g.max, g.name)); }
		});

		return { total_delta: round(total), total: round(cfg.base_price + total), lines: lines, valid: errors.length === 0, errors: errors };
	}

	function money(cur, n) {
		return cur + (Math.round(n * 100) / 100).toFixed(2);
	}

	$(function () {
		$('.aieo-og').each(function () {
			var $w = $(this);
			var cfg;
			try { cfg = JSON.parse($w.attr('data-config')); } catch (e) { return; }
			if (!cfg || !cfg.groups) { return; }
			var $form = $w.closest('form.cart');
			var $btn = $form.find('.single_add_to_cart_button');

			function selectedSet() {
				var sel = {};
				$w.find('input[name="aieo_og_options[]"]:checked').each(function () { sel[parseInt(this.value, 10)] = true; });
				return sel;
			}

			function enforceMax(sel) {
				$w.find('.aieo-og-group').each(function () {
					var $g = $(this);
					if ($g.data('type') !== 'checkbox') { return; }
					var max = parseInt($g.data('max'), 10) || 0;
					if (max <= 0) { return; }
					var n = $g.find('input:checked').length;
					$g.find('input:not(:checked)').each(function () {
						if (!this.disabled || this._ogMaxLock) { this.disabled = (n >= max); this._ogMaxLock = (n >= max); }
					});
				});
			}

			function refresh() {
				var sel = selectedSet();
				var r = resolve(cfg, sel);
				$w.find('.aieo-og-total').text(money(cfg.currency, r.total));
				var $err = $w.find('.aieo-og-errors').empty();
				if (r.errors.length) { r.errors.forEach(function (e) { $('<div/>').text(e).appendTo($err); }); }
				if ($btn.length) {
					$btn.prop('disabled', !r.valid).toggleClass('disabled', !r.valid);
				}
				enforceMax(sel);
			}

			$w.on('change', 'input[name="aieo_og_options[]"]', refresh);
			refresh(); // initial (defaults + base price)
		});
	});

})(jQuery);
