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

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

class BooleanType extends AbstractValueType implements ISchemable, IQueryable, IHumanReadable, IConditionable, ISortable, IWpRestApi, IColumnable, IComparable {

	use ComparableStringTrait;

	protected function _fieldTypeInfo() {
		return array(
			'label'            => __( 'ON/OFF', 'directories-pro' ),
			'default_widget'   => 'checkbox',
			'default_settings' => array(),
			'icon'             => 'fas fa-toggle-on',
			'schema_type'      => 'string',
		);
	}

	public function fieldTypeOnSaveValues( IField $field, array $values, ?array $currentValues = null, array &$extraArgs = array() ) {
		$ret = array();
		foreach ( $values as $weight => $value ) {
			$ret[][ $this->_valueColumn ] = is_array( $value ) ? (bool) $value[ $this->_valueColumn ] : (bool) $value;
		}

		return $ret;
	}

	public function fieldSchemaProperties( IField $field ) {
		return array( 'acceptsReservations' );
	}

	public function fieldSchemaRenderProperty( IField $field, $property, IEntity $entity ) {
		$value = $entity->getSingleFieldValue( $field->getFieldName() );
		if ( null === $value ) {
			return;
		}

		return (bool) $value ? 'True' : 'False';
	}

	public function fieldQueryableInfo( IField $field, $inAdmin = false ) {
		return array(
			'example' => __( '1 or 0', 'directories-pro' ),
			'tip'     => __( 'Enter 1 for true (checked), 0 for false (unchecked).', 'directories-pro' ),
		);
	}

	public function fieldQueryableQuery( Query $query, $fieldName, $paramStr, Bundle $bundle ) {
		if ( (bool) $paramStr ) {
			$query->fieldIs( $fieldName, 1 );
		} else {
			$query->startCriteriaGroup( 'OR' )
				->fieldIs( $fieldName, 0 )
				->fieldIsNull( $fieldName )
				->finishCriteriaGroup();
		}
	}

	public function fieldHumanReadableText( IField $field, IEntity $entity, $separator = null, $key = null ) {
		return (bool) $entity->getSingleFieldValue( $field->getFieldName() ) === true ? __( 'Yes', 'directories-pro' ) : __( 'No', 'directories-pro' );
	}

	public function fieldConditionableInfo( IField $field, $isServerSide = false ) {
		return array(
			'' => array(
				'compare' => array( 'empty', 'filled' ),
			),
		);
	}

	public function fieldConditionableRule( IField $field, $compare, $value = null, $name = '' ) {
		switch ( $compare ) {
			case 'empty':
				return array(
					'type'  => 'checked',
					'value' => false,
				);
			case 'filled':
				return array(
					'type'  => 'unchecked',
					'value' => false,
				);
			default:
				return;
		}
	}

	public function fieldConditionableMatch( IField $field, array $rule, array $values, IEntity $entity ) {
		switch ( $rule['type'] ) {
			case 'checked':
			case 'unchecked':
				if ( isset( $values[0] ) ) {
					$value = is_array( $values[0] ) ? $values[0][ $this->_valueColumn ] : $values[0];
				} else {
					$value = null;
				}
				return $rule['type'] === 'unchecked' ? empty( $value ) === $rule['value'] : ! empty( $value ) === $rule['value'];
			default:
				return false;
		}
	}

	public function fieldSortableOptions( IField $field ) {
		return array(
			array(),
		);
	}

	public function fieldSortableSort( Query $query, $fieldName, ?array $args = null ) {
		$query->sortByField( $fieldName, 'DESC' );
	}

	public function fieldWpRestApiSchema( IField $field ) {
		return array( 'type' => 'boolean' );
	}

	public function fieldWpRestApiGetValue( IField $field, IEntity $entity, $request ) {
		return (bool) $entity->getSingleFieldValue( $field->getFieldName() );
	}

	public function fieldColumnableInfo( IField $field ) {
		if ( ! $field->isCustomField() ) {
			return;
		}

		return array(
			'' => array(
				'label'        => $field->getFieldLabel(),
				'sortby'       => 'value',
				'hidden'       => true,
				'render_empty' => true,
			),
		);
	}

	public function fieldColumnableColumn( IField $field, $value, $column = '' ) {
		return isset( $value[0] ) && (bool) $value[0] === true ? __( 'Yes', 'directories-pro' ) : __( 'No', 'directories-pro' );
	}
}
