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

use SabaiApps\Directories\Application;
use SabaiApps\Directories\Component\Entity\Model\Bundle;
use SabaiApps\Directories\Exception;

class QueryHelper {

	public function help( Application $application, Bundle $bundle, $view = null ) {
		if ( is_array( $view ) ) {
			$view     += array(
				'mode'       => 'list',
				'name'       => '',
				'is_default' => false,
				'settings'   => array(),
			);
			$view_mode = $application->View_Modes_impl( $view['mode'], $bundle );
		} else {
			$view_model = $application->getModel( 'View', 'View' )->bundleName_is( $bundle->name );
			if ( ! isset( $view ) ) {
				$view_model->default_is( 1 );
			} elseif ( is_string( $view ) ) {
				$view_model->name_is( $view );
			} else {
				throw new Exception\RuntimeException( 'Invalid view specified for bundle: ' . $bundle->name );
			}
			if ( ! $view = $view_model->fetchOne() ) {
				throw new Exception\RuntimeException( 'Invalid view specified for bundle: ' . $bundle->name );
			}
			$view_mode = $application->View_Modes_impl( $view->mode, $bundle );
			$view      = array(
				'mode'       => $view->mode,
				'name'       => $view->name,
				'is_default' => $view->isDefault(),
				'settings'   => $view->data['settings'] + $view_mode->viewModeInfo( 'default_settings' ),
			);
		}

		$query = $application->Entity_Query( $bundle->entitytype_name, $bundle->name, empty( $view['settings']['query']['fields'] ) ? array() : $view['settings']['query']['fields'] );
		if ( empty( $bundle->info['is_taxonomy'] ) ) {
			if ( ! empty( $bundle->info['public'] ) ) {
				if ( empty( $view['settings']['query']['status'] )
					|| ! empty( $view['settings']['query']['user_id'] ) // do not allow custom status if viewing other user's entities
				) {
					// No status specified, fetch published entities
					$query->fieldIs( 'status', $application->Entity_Status( $bundle->entitytype_name, 'publish' ) );
					if ( ! empty( $view['settings']['query']['user_id'] ) ) {
						$query->fieldIs( 'author', $view['settings']['query']['user_id'] );
					}
				} else {
					$statuses = array();
					foreach ( $view['settings']['query']['status'] as $status ) {
						$statuses[ $status ] = $application->Entity_Status( $bundle->entitytype_name, $status );
					}
					if ( empty( $view['settings']['query']['status_others'] ) ) {
						$query->fieldIs( 'author', $application->getUser()->id )
							->fieldIsIn( 'status', $statuses );
					} else {
						$statuses_other = array();
						foreach ( $view['settings']['query']['status_others'] as $status ) {
							$statuses_other[ $status ] = $application->Entity_Status( $bundle->entitytype_name, $status );
						}
						$query->startCriteriaGroup( 'OR' )
							->startCriteriaGroup( 'AND' )
							->fieldIs( 'author', $application->getUser()->id )
							->fieldIsIn( 'status', $statuses )
							->finishCriteriaGroup()
							->startCriteriaGroup( 'AND' )
							->fieldIsNot( 'author', $application->getUser()->id )
							->fieldIsIn( 'status', $statuses_other )
							->finishCriteriaGroup()
							->finishCriteriaGroup();
					}
				}
			} else {
				if ( isset( $view['settings']['query']['user_id'] ) ) {
					if ( ! empty( $view['settings']['query']['user_id'] ) ) {
						$query->fieldIs( 'author', $view['settings']['query']['user_id'] );
					}
				} else {
					$query->fieldIs( 'author', $application->getUser()->id );
				}

				if ( empty( $view['settings']['query']['status'] ) ) {
					$query->fieldIs( 'status', $application->Entity_Status( $bundle->entitytype_name, 'publish' ) );
				} else {
					$statuses = array();
					foreach ( $view['settings']['query']['status'] as $status ) {
						$statuses[ $status ] = $application->Entity_Status( $bundle->entitytype_name, $status );
					}
					$query->fieldIsIn( 'status', $statuses );
				}
			}
		}

		$view_mode->viewModeOnQuery( $bundle, $query, $view['settings'] );

		return $application->Filter( 'view_query', $query, array( $bundle, $view['mode'], $view['name'], $view['settings'], $view['is_default'] ) );
	}
}
