<?php
namespace SabaiApps\Directories\Component\Claiming\FieldType;

use SabaiApps\Directories\Component\Field\Type\AbstractValueType;
use SabaiApps\Directories\Component\Field\Type\IColumnable;
use SabaiApps\Directories\Component\Field\Type\IConditionable;
use SabaiApps\Directories\Component\Field\Type\IRestrictable;
use SabaiApps\Directories\Component\Field\IField;
use SabaiApps\Directories\Component\Entity\Type\IEntity;

class StatusFieldType extends AbstractValueType implements IColumnable, IRestrictable, IConditionable {

	protected function _fieldTypeInfo() {
		return array(
			'label'       => __( 'Claim Status', 'directories-pro' ),
			'admin_only'  => true,
			'schema_type' => 'string',
		);
	}

	public function fieldTypeOnSaveValues( IField $field, array $values, ?array $currentValues = null, array &$extraArgs = array() ) {
		if ( ! $this->_application->HasPermission( 'entity_delete_others_' . $field->Bundle->name ) ) {
			return;
		}

		return ( $ret = parent::fieldTypeOnSaveValues( $field, $values, $currentValues, $extraArgs ) ) ? $ret : null;
	}

	public function fieldColumnableInfo( IField $field ) {
		return array(
			'' => array(
				'label' => $field->getFieldLabel(),
			),
		);
	}

	public function fieldColumnableColumn( IField $field, IEntity $entity, $column = '' ) {
		$values   = $entity->getFieldValue( $field->getFieldName() );
		$status   = isset( $values[0] ) ? $values[0] : null;
		$statuses = $this->_application->Claiming_Statuses();
		if ( ! isset( $statuses[ $status ] ) ) {
			$label = __( 'Pending', 'directories-pro' );
			$color = 'warning';
		} else {
			$label = $statuses[ $status ]['label'];
			$color = $statuses[ $status ]['color'];
		}
		return '<span class="' . DRTS_BS_PREFIX . 'badge ' . DRTS_BS_PREFIX . 'bg-' . $color . '">' . $this->_application->H( $label ) . '</span>';
	}

	public function fieldRestrictableOptions( IField $field ) {
		$ret = array();
		foreach ( $this->_application->Claiming_Statuses() as $status => $status_info ) {
			$ret[ $status ] = $status_info['label'];
		}
		$ret['pending'] = __( 'Pending', 'directories-pro' );
		return array( 'status' => $ret );
	}

	public function fieldRestrictableRestrict( IField $field, $value, $name ) {
		return ( $value === 'pending' ) ? array( 'compare' => 'NULL' ) : array();
	}

	public function fieldConditionableInfo( IField $field, $isServerSide = false ) {
		return array(
			'' => array(
				'compare' => array( 'value', '!value' ),
				'tip'     => __( 'Enter "approved" or "rejected".', 'directories-pro' ),
			),
		);
	}

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

	public function fieldConditionableMatch( IField $field, array $rule, array $values, IEntity $entity ) {
		switch ( $rule['type'] ) {
			case 'value':
			case '!value':
				if ( empty( $values ) ) {
					return $rule['type'] === '!value';
				}

				foreach ( (array) $rule['value'] as $rule_value ) {
					foreach ( $values as $input ) {
						if ( is_array( $input ) ) {
							$input = $input[ isset( $this->_valueColumn ) ? $this->_valueColumn : 'value' ];
						}
						if ( $input == $rule_value ) {
							if ( $rule['type'] === '!value' ) {
								return false;
							}
							continue 2;
						}
					}
					// One of rules did not match
					if ( $rule['type'] === 'value' ) {
						return false;
					}
				}
				// All rules matched or did not match.
				return true;
			default:
				return false;
		}
	}
}
