<?php
namespace SabaiApps\Directories\Component\Field\Type;

use SabaiApps\Directories\Component\Field\IField;
use SabaiApps\Directories\Component\Entity\Type\IEntity;

trait ConditionableRangeTrait {

	public function fieldConditionableInfo( IField $field, $isServerSide = false ) {
		return array(
			'' => array(
				'compare' => $isServerSide ? array( '<value', '>value', '*value', '!*value', '<>value', 'empty', 'filled' ) : array( '<value', '>value', '<>value' ),
				'tip'     => __( 'Enter a single numeric value or multiple numeric values separated with a comma.', 'directories-pro' ),
				'example' => '10,25',
			),
		);
	}

	public function fieldConditionableRule( IField $field, $compare, $value = null, $name = '' ) {
		switch ( $compare ) {
			case '<value':
			case '>value':
			case '*value':
			case '!*value':
				if ( false === $value = $this->_getConditionableRuleValue( $value ) ) {
					return;
				}

				return array(
					'type'  => $compare,
					'value' => $value,
				);
			case '<>value':
				if ( ! strpos( $value, ',' )
					|| ( ! $values = explode( ',', $value ) )
					|| ( false === $value[0] = $this->_getConditionableRuleValue( $values[0] ) )
					|| ( false === $value[1] = $this->_getConditionableRuleValue( $values[1] ) )
				) {
					return;
				}

				return array(
					'type'  => $compare,
					'value' => $values[0] . ',' . $values[1],
				);
			case 'empty':
				return array(
					'type'  => 'filled',
					'value' => false,
				);
			case 'filled':
				return array(
					'type'  => 'empty',
					'value' => false,
				);
			default:
		}
	}

	public function fieldConditionableMatch( IField $field, array $rule, array $values, IEntity $entity ) {
		switch ( $rule['type'] ) {
			case '<value':
			case '>value':
			case '*value':
				if ( ! empty( $values ) ) {
					foreach ( $values as $input ) {
						foreach ( (array) $rule['value'] as $rule_value ) {
							switch ( $rule['type'] ) {
								case '<value':
									if ( $input['max'] < $rule_value ) {
										return true;
									}
									break;
								case '>value':
									if ( $input['min'] > $rule_value ) {
										return true;
									}
									break;
								case '*value':
									if ( $input['min'] <= $rule_value && $rule_value <= $input['max'] ) {
										return true;
									}
									break;
							}
						}
					}
				}
				return false;
			case '!*value':
				if ( ! empty( $values ) ) {
					foreach ( $values as $input ) {
						foreach ( (array) $rule['value'] as $rule_value ) {
							if ( $input['min'] <= $rule_value && $rule_value <= $input['max'] ) {
								return false;
							}
						}
					}
				}
				return true;
			case '<>value':
				if ( ! empty( $values ) ) {
					foreach ( $values as $input ) {
						foreach ( (array) $rule['value'] as $rule_value ) {
							if ( ! strpos( $rule_value, ',' )
								|| ( ! $rule_value = explode( ',', $rule_value ) )
								|| count( $rule_value ) < 2
							) {
								continue;
							}

							if ( $input['min'] >= $rule_value[0]
								&& $input['max'] <= $rule_value[1]
							) {
								return true;
							}
						}
					}
				}
				return false;
			case 'empty':
				return empty( $values ) === $rule['value'];
			case 'filled':
				return ! empty( $values ) === $rule['value'];
			default:
				return false;
		}
	}

	/**
	 * @return mixed|false
	 */
	abstract protected function _getConditionableRuleValue( $value );
}
