/**
 * Custom Fields conditional logic on edit screens.
 */
(function ($) {
	'use strict';

	function parseConditional($field) {
		var raw = $field.attr('data-cf-conditional');
		if (!raw) {
			return null;
		}
		try {
			return JSON.parse(raw);
		} catch (e) {
			return null;
		}
	}

	function fieldValue($box, fieldKey) {
		var $target = $box.find('[data-cf-field-key="' + fieldKey + '"]');
		if (!$target.length) {
			return '';
		}
		var $input = $target.find('input, select, textarea').filter(':not([type="hidden"])').first();
		if (!$input.length) {
			return '';
		}
		if ($input.is(':checkbox')) {
			return $input.is(':checked') ? '1' : '0';
		}
		if ($input.is('select[multiple]')) {
			return ($input.val() || []).join(',');
		}
		return $input.val() || '';
	}

	function compare(actual, operator, expected) {
		var a = parseFloat(actual);
		var b = parseFloat(expected);
		var numeric = !isNaN(a) && !isNaN(b);

		switch (operator) {
			case '!=':
				return actual !== expected;
			case '>':
				return numeric && a > b;
			case '>=':
				return numeric && a >= b;
			case '<':
				return numeric && a < b;
			case '<=':
				return numeric && a <= b;
			case 'contains':
				return expected !== '' && actual.indexOf(expected) !== -1;
			case 'not_contains':
				return expected === '' || actual.indexOf(expected) === -1;
			case 'empty':
				return actual === '' || actual === '0';
			case 'not_empty':
				return actual !== '' && actual !== '0';
			case '==':
			default:
				return actual === expected;
		}
	}

	function matchesConditional(conditional, values) {
		if (!conditional || !conditional.enabled || !conditional.rules || !conditional.rules.length) {
			return true;
		}
		var results = conditional.rules.map(function (rule) {
			return compare(values[rule.field] || '', rule.operator || '==', rule.value || '');
		});
		return conditional.match === 'any'
			? results.indexOf(true) !== -1
			: results.indexOf(false) === -1;
	}

	function refreshBox($box) {
		var values = {};
		$box.find('[data-cf-field-key]').each(function () {
			var key = $(this).attr('data-cf-field-key');
			if (key) {
				values[key] = fieldValue($box, key);
			}
		});

		$box.find('[data-cf-field-key]').each(function () {
			var $field = $(this);
			var conditional = parseConditional($field);
			var visible = matchesConditional(conditional, values);
			$field.toggle(visible);
		});
	}

	$(function () {
		$('.cf-meta-box').each(function () {
			var $box = $(this);
			refreshBox($box);
			$box.on(
				'change input',
				'input, select, textarea',
				function () {
					refreshBox($box);
				}
			);
		});
	});
})(jQuery);
