<?php
namespace SabaiApps\Directories\Component\Entity\Helper;

use SabaiApps\Directories\Application;
use SabaiApps\Directories\Component\Entity\Type\FieldQuery;
use SabaiApps\Directories\Component\Field\Type\IQueryable;

class QueryHelper {

	public function help( Application $application, $entityType, $bundleName = null, array $queryFields = array(), $operator = null ) {
		$query = $application->Entity_Types_impl( $entityType )->entityTypeGetQuery( $bundleName, $operator );

		if ( isset( $bundleName )
			&& is_string( $bundleName )
			&& ! empty( $queryFields )
		) {
			$field_query = $query->getFieldQuery();
			foreach ( $queryFields as $field_name => $query_str ) {
				if ( ! is_int( $field_name ) ) {
					$this->_queryField( $application, $bundleName, $field_query, $field_name, $query_str );
				} elseif ( is_array( $query_str ) ) {
						// Grouped query
						$field_query->startCriteriaGroup( 'OR' );
					foreach ( $query_str as $_field_name => $_query_str ) {
						$this->_queryField( $application, $bundleName, $field_query, $_field_name, $_query_str );
					}
						$query->finishCriteriaGroup();
				}
			}
		}

		return $query;
	}

	protected function _queryField( Application $application, $bundleName, FieldQuery $query, $fieldName, $queryStr ) {
		if ( strpos( $fieldName, ',' ) !== false ) {
			$field_names = explode( ',', $fieldName );
			if ( ( $field = $application->Entity_Field( $bundleName, $field_names[0] ) )
				&& $field->getFieldType() === 'fieldset_fieldset'
				&& ( $settings = $field->getFieldSettings() )
				&& ! empty( $settings['bundle'] )
				&& ( $fieldset_bundle = $application->Entity_Bundle( $settings['bundle'] ) )
			) {
				$entity_type_props = $application->Entity_Types_impl( $fieldset_bundle->entitytype_name )->entityTypeInfo( 'properties' );
				$query->addTableIdColumn( $entity_type_props['parent']['column'] )->addBundleNameCriteria( $fieldset_bundle->name );
				$bundle    = $fieldset_bundle;
				$fieldName = $field_names[1];
			} else {
				$application->logError( sprintf( 'Invalid query field for %s: %s', $bundleName, $fieldName ) );
			}
		} elseif ( ! $bundle = $application->Entity_Bundle( $bundleName ) ) {
				$application->logError( sprintf( 'Invalid bundle for query field: %s', $bundleName ) );
				return;
		}

		if ( ( $field = $application->Entity_Field( $bundle, $fieldName ) )
			&& ( $field_type = $application->Field_Type( $field->getFieldType(), true ) )
			&& $field_type instanceof IQueryable
		) {
			$field_type->fieldQueryableQuery( $query, ( $property = $field->isPropertyField() ) ? $property : $fieldName, $queryStr, $bundle );
		} else {
			$application->logError( sprintf( 'Invalid query field for %s: %s', $bundle->name, $fieldName ) );
		}
	}
}
