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

use SabaiApps\Directories\Component\Entity\Type\IEntity;
use SabaiApps\Directories\Component\Entity\Model\Bundle;
use SabaiApps\Directories\Component\Field\IField;
use SabaiApps\Directories\Component\Field\Query;

abstract class AbstractValueType extends AbstractType implements ICopiable, IQueryable {

	protected $_valueColumn = 'value';

	public function fieldTypeOnSaveValues( IField $field, array $values, ?array $currentValues = null, array &$extraArgs = array() ) {
		$settings = (array) $field->getFieldSettings();
		$ret      = array();
		foreach ( $values as $key => $value ) {
			if ( is_array( $value ) ) {
				if ( empty( $value ) ) {
					continue;
				}

				if ( ! isset( $value[ $this->_valueColumn ] ) ) {
					$value[ $this->_valueColumn ] = $this->_toScalarValue( $field, $value, $settings, $key );
				}

				$_value = $this->_onSaveValue( $field, (string) $value[ $this->_valueColumn ], $settings, $key );
				if ( is_null( $_value ) || strlen( $_value ) === 0 ) {
					continue;
				}

				$value[ $this->_valueColumn ] = $_value;
				$ret[]                        = $value;
			} else {
				$value = $this->_onSaveValue( $field, $value, $settings, $key );
				if ( is_null( $value ) || strlen( $value ) === 0 ) {
					continue;
				}

				$ret[][ $this->_valueColumn ] = $value;
			}
		}

		return $ret;
	}

	protected function _toScalarValue( IField $field, array $value, array $settings, $key ) {}

	protected function _onSaveValue( IField $field, $value, array $settings, $key ) {
		$value = (string) $value;
		return strlen( $value ) === 0 ? null : $value;
	}

	public function fieldTypeOnLoadValues( IField $field, array &$values, IEntity $entity, array $allValues ) {
		$settings = (array) $field->getFieldSettings();
		foreach ( $values as $key => $value ) {
			$values[ $key ] = $this->_onLoadValue( $field, $value[ $this->_valueColumn ], $settings );
		}
	}

	protected function _onLoadValue( IField $field, $value, array $settings ) {
		return $value;
	}

	public function fieldTypeIsModified( IField $field, $valueToSave, $currentLoadedValue ) {
		$new = array();
		foreach ( $valueToSave as $value ) {
			$new[] = $value[ $this->_valueColumn ];
		}
		return $currentLoadedValue !== $new;
	}

	public function fieldCopyValues( IField $field, array $values, array &$allValue, $lang = null ) {
		return $values;
	}

	public function fieldQueryableInfo( IField $field, $inAdmin = false ) {
		return array(
			'example' => __( '1 or 0', 'directories-pro' ),
			'tip'     => __( 'Enter 1 for items that have at least one value for this field, or 0 if none.', 'directories-pro' ),
		);
	}

	public function fieldQueryableQuery( Query $query, $fieldName, $paramStr, Bundle $bundle ) {
		if ( (bool) $paramStr ) {
			$query->fieldIsNotNull( $fieldName, $this->_valueColumn );
		} else {
			$query->fieldIsNull( $fieldName, $this->_valueColumn );
		}
	}
}
