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

use SabaiApps\Directories\Application;
use SabaiApps\Directories\Component\Payment\Feature\IFeature;
use SabaiApps\Directories\Component\Payment\PaymentComponent;
use SabaiApps\Directories\Component\Payment\IPlan;
use SabaiApps\Directories\Component\Payment\Feature\IAddonFeature;
use SabaiApps\Directories\Exception;
use SabaiApps\Directories\Component\Entity\Type\IEntity;
use SabaiApps\Directories\Component\Entity\Model\Bundle;
use SabaiApps\Directories\Component\Form\Form;

class FeaturesHelper {

	private $_impls = array();

	public function help( Application $application, $useCache = true ) {
		if ( ! $useCache
			|| ( ! $features = $application->getPlatform()->getCache( 'payment_features' ) )
		) {
			$features = array();
			foreach ( $application->InstalledComponentsByInterface( 'Payment\IFeatures' ) as $component_name ) {
				if ( ! $application->isComponentLoaded( $component_name )
					|| ( ! $feature_names = $application->getComponent( $component_name )->paymentGetFeatureNames() )
				) {
					continue;
				}

				foreach ( $feature_names as $feature_name ) {
					if ( $feature = $application->getComponent( $component_name )->paymentGetFeature( $feature_name ) ) {
						if ( ! $weight = $feature->paymentFeatureInfo( 'weight' ) ) {
							$weight = 99;
						}
						$features[ $weight ][ $feature_name ] = $component_name;
					}
				}
			}
			if ( ! empty( $features ) ) {
				ksort( $features );
				$_features = array();
				foreach ( array_keys( $features ) as $weight ) {
					$_features += $features[ $weight ];
				}
				$features = $_features;
			}
			$application->getPlatform()->setCache( $features, 'payment_features' );
		}

		return $features;
	}

	/**
	 * Gets an implementation of IFeature interface for a given feature name
	 *
	 * @param Application $application
	 * @param string      $featureName
	 * @return IFeature
	 */
	public function impl( Application $application, $featureName, $returnFalse = false ) {
		if ( ! isset( $this->_impls[ $featureName ] ) ) {
			if ( ( ! $features = $this->help( $application ) )
				|| ! isset( $features[ $featureName ] )
				|| ! $application->isComponentLoaded( $features[ $featureName ] )
			) {
				if ( $returnFalse ) {
					return false;
				}
				throw new Exception\UnexpectedValueException( sprintf( 'Invalid feature: %s', $featureName ) );
			}
			$this->_impls[ $featureName ] = $application->getComponent( $features[ $featureName ] )->paymentGetFeature( $featureName );
		}

		return $this->_impls[ $featureName ];
	}

	public function form( Application $application, $bundle, $type = 'base', ?array $settings = null, array $parents = array(), ?array $typeSelector = null ) {
		$bundle = $application->Entity_Bundle( $bundle, '', true );
		$form   = array(
			'#tree'             => true,
			'#element_validate' => array(
				array( array( $this, '_onSubmitForm' ), array( $application, $bundle, is_array( $type ) ? null : $type, $typeSelector ) ),
			),
			'#weight'           => 99,
		);
		foreach ( (array) $type as $_type ) {
			$key = $bundle->type . '-' . $_type;
			if ( $_type === 'addon' ) {
				$method = 'paymentAddonFeatureSettingsForm';
			} else {
				$method = 'paymentFeatureSettingsForm';
				if ( $application->Entity_BundleTypeInfo( $bundle, 'levelable' )
					&& ( $levels = $application->Entity_Levels_options( $bundle ) )
				) {
					$form[ $key ]['level'] = array(
						'#title'  => __( 'Feature level', 'directories-pro' ),
						'#weight' => 1,
						'#class'  => 'drts-form-label-lg',
						'assign'  => array(
							'#title'         => __( 'Assign feature level', 'directories-pro' ),
							'#type'          => 'select',
							'#options'       => $levels + array( '' => __( '— Do not assign (customize features) —', 'directories-pro' ) ),
							'#horizontal'    => true,
							'#default_value' => isset( $settings ) ? ( isset( $settings['level'] ) ? $settings['level'] : '' ) : 'default',
							'#description'   => sprintf(
								__( 'Feature levels can be configured in Directories > %1$s > Content Types > %2$s > Edit > Feature Level Settings.', 'directories-pro' ),
								$bundle->getGroupLabel(),
								$bundle->getLabel( 'singular' )
							),
						),
					);
				}
			}
			foreach ( array_keys( $this->help( $application ) ) as $feature_name ) {
				if ( ! $feature = $this->impl( $application, $feature_name, true ) ) {
					continue;
				}

				if ( $_type === 'addon' ) {
					if ( ! $feature instanceof IAddonFeature
						|| ! $feature->paymentAddonFeatureSupports( $bundle )
					) {
						continue;
					}
				} elseif ( ! $feature->paymentFeatureSupports( $bundle, $_type ) ) {
					continue;
				}

				$feature_info     = $feature->paymentFeatureInfo();
				$feature_settings = isset( $settings['features'][ $feature_name ] ) ? $settings['features'][ $feature_name ] : array();
				if ( false === $feature_default_settings = $feature->paymentFeatureSettings( $bundle, $_type ) ) {
					$feature_default_settings = isset( $feature_info['default_settings'] ) ? (array) $feature_info['default_settings'] : array();
				}
				$params = array( $bundle, $feature_settings + $feature_default_settings );
				if ( $_type !== 'addon' ) {
					$params[] = $_type;
				}
				$params[]              = array_merge( $parents, array( $key, 'features', $feature_name ) );
				$feature_settings_form = call_user_func_array( array( $feature, $method ), $params );
				if ( ! $feature_settings_form ) {
					continue;
				}

				$form[ $key ]['features']['#weight']                  = 2;
				$form[ $key ]['features'][ $feature_name ]            = $feature_settings_form;
				$form[ $key ]['features'][ $feature_name ]['#weight'] = isset( $feature_info['weight'] ) ? $feature_info['weight'] : 10;
				$form[ $key ]['features'][ $feature_name ]['#title']  = $feature_info['label'];
				$form[ $key ]['features'][ $feature_name ]['#class']  = 'drts-form-label-lg';
				if ( isset( $form[ $key ]['level'] ) ) {
					if ( ! isset( $feature_info['entity_levelable'] )
						|| $feature_info['entity_levelable'] !== false
					) {
						$form[ $key ]['features'][ $feature_name ]['#states']['visible'][ sprintf( '[name="%s"]', $application->Form_Form_fieldName( array( $parents, $key, 'level', 'assign' ) ) ) ] = array( 'value' => '' );
					}
				}
			}
			if ( isset( $typeSelector ) ) {
				$form[ $key ]['#states'] = array(
					'visible' => array(
						sprintf( '[name="%s"]', $application->Form_Form_fieldName( $typeSelector ) ) => array( 'value' => $key ),
					),
				);
			}
		}
		return $form;
	}

	public function _onSubmitForm( Form $form, &$value, $element, Application $application, Bundle $bundle, $type, ?array $typeSelector = null ) {
		if ( ! isset( $type ) ) {
			if ( ! isset( $typeSelector ) ) {
				throw new Exception\UnexpectedValueException( 'Plan type selector is not set' );
			}
			if ( ! $type = $form->getValue( $typeSelector ) ) {
				throw new Exception\UnexpectedValueException( 'Plan type is not selected' );
			}
			$key  = $type;
			$type = explode( '-', $type );
			if ( ! isset( $type[1] ) ) {
				throw new Exception\UnexpectedValueException( 'Invalid plan type selected' );
			}
			$type = $type[1];
		} else {
			$key = $bundle->type . '-' . $type;
		}

		// Extract settings for both features enabled and disabled as separate arrays
		$features = array(
			'enabled'  => array(),
			'disabled' => array(),
		);
		$level    = $type === 'addon' || empty( $value[ $key ]['level']['assign'] ) ? null : $value[ $key ]['level']['assign'];
		foreach ( $value[ $key ]['features'] as $feature_name => $feature_settings ) {
			if ( ! $feature = $application->Payment_Features_impl( $feature_name, true ) ) {
				continue;
			}

			if ( $type === 'addon' ) {
				if ( ! $feature instanceof IAddonFeature ) {
					continue;
				}

				$_feature_settings = $feature->paymentAddonFeatureIsEnabled( $bundle, $feature_settings );
			} else {
				if ( $level && $feature->paymentFeatureInfo( 'entity_levelable' ) !== false ) {
					continue;
				}

				$_feature_settings = $feature->paymentFeatureIsEnabled( $bundle, $feature_settings );
			}
			if ( false !== $_feature_settings ) {
				$features['enabled'][ $feature_name ] = is_array( $_feature_settings ) ? $_feature_settings : $feature_settings;
			} else {
				$features['disabled'][ $feature_name ] = $feature_settings;
			}
		}
		$value['features'] = $features;
		if ( $application->Entity_BundleTypeInfo( $bundle, 'levelable' )
			&& $type !== 'addon'
		) {
			$value['level'] = $level;
		}

		unset( $value[ $key ], $value[ $bundle->type . '-base' ], $value[ $bundle->type . '-addon' ], $value[ $bundle->type . '-subscription' ] );
	}

	public function create( Application $application, IEntity $entity, IPlan $plan, $orderId ) {
		$application->Entity_Field_load( $entity );

		// Add features to feature group
		$all_feature_settings = array();
		$features             = $application->Payment_Plan_features( $plan );
		if ( $plan->paymentPlanType() !== 'addon' ) {
			if ( ! isset( $features['payment_plan'] ) ) {
				$features['payment_plan'] = array();
			}
		} else {
			unset( $features['payment_plan'] );
		}

		// Initialize feature meta
		$meta             = $this->_getMeta( $application, $entity, false );
		$meta[ $orderId ] = array(
			'order_id'  => $orderId,
			'plan_type' => $plan->paymentPlanType(),
			'timestamp' => time(),
			'active'    => false,
			'features'  => array(),
		);

		foreach ( $features as $feature_name => $feature_settings ) {
			if ( ! $application->Payment_Features_impl( $feature_name, true ) ) {
				continue;
			}

			$meta[ $orderId ]['features'][ $feature_name ] = array(
				'status'   => PaymentComponent::FEATURE_STATUS_PENDING,
				'settings' => array(),
			);

			$all_feature_settings[ $feature_name ] = $feature_settings;
		}

		// Notify features have been added
		$values_to_save = array();
		foreach ( $all_feature_settings as $feature_name => $feature_settings ) {
			$meta[ $orderId ]['features'][ $feature_name ]['settings'] = $application->Payment_Features_impl( $feature_name )
				->paymentFeatureOnAdded( $entity, $feature_settings, $plan, $values_to_save );
		}
		// Save entity and features
		if ( ! empty( $values_to_save ) ) {
			$application->Entity_Save( $entity, $values_to_save );
		}

		// Update entity meta
		$this->_setMeta( $application, $entity, $meta );

		return $meta[ $orderId ];
	}

	public function delete( Application $application, IEntity $entity, $orderId ) {
		$meta = $this->_getMeta( $application, $entity, false );
		if ( isset( $meta[ $orderId ] ) ) {
			unset( $meta[ $orderId ] );
			$this->_setMeta( $application, $entity, $meta );
		}
	}

	protected function _getMeta( Application $application, IEntity $entity, $orderId = null ) {
		$meta = $application->getPlatform()->getEntityMeta( $entity->getType(), $entity->getId(), 'payment_features' );
		if ( ! is_array( $meta ) ) {
			$meta = array();
		}

		if ( isset( $orderId ) ) {
			if ( $orderId === false ) {
				return $meta; // return all feature groups
			}

			if ( empty( $meta[ $orderId ] ) ) {
				throw new Exception\RuntimeException( 'No features found for order ID: ' . $orderId );
			}
		} else {
			// Get the latest active feature group
			foreach ( array_reverse( $meta, true ) as $order_id => $data ) {
				if ( ! empty( $data['active'] ) ) {
					$orderId = $order_id;
					break;
				}
			}
			if ( ! isset( $orderId ) ) {
				return array(); // no active feature group found
			}
		}
		return $meta[ $orderId ];
	}

	protected function _setMeta( Application $application, IEntity $entity, array $meta, $orderId = null ) {
		if ( isset( $orderId ) ) {
			$all_meta             = $this->_getMeta( $application, $entity, false );
			$all_meta[ $orderId ] = $meta;
			$meta                 = $all_meta;
		}
		$application->getPlatform()->setEntityMeta( $entity->getType(), $entity->getId(), 'payment_features', $meta );
	}

	protected function _getPaymentPlan( Application $application, $orderId ) {
		if ( ! $order = $application->getComponent( 'Payment' )->getPaymentComponent( true )->paymentGetOrderById( $orderId ) ) {
			$application->logWarning( 'Failed fetching order by order ID: ' . $orderId );
			return;
		}
		return $order->paymentOrderPlan();
	}

	/**
	 * @throws Exception\IException
	 */
	public function apply( Application $application, IEntity $entity, $orderId ) {
		if ( is_array( $orderId ) ) {
			$features_meta = $orderId;
			$orderId       = $orderId['order_id'];
		}

		if ( ! $plan = $this->_getPaymentPlan( $application, $orderId ) ) {
			return;
		}

		// Update entity status if not an add-on payment plan
		if ( $plan->paymentPlanType() !== 'addon' ) {
			$bundle     = $application->Entity_Bundle( $entity, '', true );
			$new_status = 'publish';
			if ( ! empty( $bundle->info['public'] )
				&& ! $application->HasPermission( 'entity_publish_' . $bundle->name, $application->Entity_Author( $entity ) )
			) {
				$new_status = 'pending';
			}
			$new_status = $application->Entity_Status( $entity->getType(), $new_status );
			if ( ! $entity->isPublished()
				&& ( $new_status !== $entity->getStatus() )
			) {
				$application->Entity_Save( $entity, array( 'status' => $new_status ) );
			}
			// Update translated posts
			foreach ( $application->Entity_Translations( $entity, false ) as $_entity ) {
				if ( ! $_entity->isPublished()
					&& ( $new_status !== $_entity->getStatus() )
				) {
					$application->Entity_Save( $_entity, array( 'status' => $new_status ) );
				}
			}
		}

		// Features are applied to claimed item (when claim approved), not to claim itself
		if ( $entity->getBundleType() === 'claiming_claim' ) {
			return;
		}

		// Init
		if ( ! isset( $features_meta ) ) {
			$features_meta = $this->_getMeta( $application, $entity, $orderId );
		}
		$features_updated = array();

		// Apply features
		$entity = $this->_applyFeatures( $application, $entity, $features_meta, $features_updated, $orderId, $plan->paymentPlanType() === 'addon' );

		if ( $plan->paymentPlanType() !== 'addon' ) {
			$meta = $this->_getMeta( $application, $entity, false );
			foreach ( array_keys( $meta ) as $existing_order_id ) {
				if ( $meta[ $existing_order_id ]['plan_type'] === 'addon' ) {
					continue;
				}

				if ( $existing_order_id === $orderId ) {
					$meta[ $existing_order_id ]           = $features_meta;
					$meta[ $existing_order_id ]['active'] = true;
				} else {
					$meta[ $existing_order_id ]['active'] = false;
				}
			}
			$this->_setMeta( $application, $entity, $meta );
		} else {
			// Update feature group entity meta
			$this->_setMeta( $application, $entity, $features_meta, $orderId );
		}

		// Notify
		if ( ! empty( $features_updated ) ) {
			// Notify that the status of one or more features have changed
			$application->Action( 'payment_features_status_change', array( $entity, $features_updated ) );
		}

		return $entity;
	}

	/**
	 * @throws Exception\IException
	 */
	public function unapply( Application $application, IEntity $entity, $orderId = null, array $values = array() ) {
		// Features are unapplied to claimed item (when claim rejected), not to claim itself
		if ( $entity->getBundleType() === 'claiming_claim' ) {
			return;
		}

		// Get feature group
		$features_meta = $this->_getMeta( $application, $entity, $orderId );
		if ( ! isset( $orderId ) ) {
			$orderId = $features_meta['order_id'];
		}
		// Get payment plan
		if ( ! $plan = $this->_getPaymentPlan( $application, $orderId ) ) {
			return;
		}

		$features_updated = array();
		// Unapply features
		$this->_unapplyFeatures( $application, $entity, $features_meta, $features_updated, $values, $orderId, $plan->paymentPlanType() === 'addon' );

		// Deactivate feature order
		if ( $plan->paymentPlanType() !== 'addon'
			&& isset( $orderId )
		) {
			$features_meta['active'] = false;
		}

		// Update feature group entity meta
		$this->_setMeta( $application, $entity, $features_meta, $orderId );

		// Notify
		if ( ! empty( $features_updated ) ) {
			// Notify that the status of one or more features have changed
			$application->Action( 'payment_features_status_change', array( $entity, $features_updated ) );
		}

		// Mark entity as draft if not an add-on payment plan and currently pending
		if ( $entity->isPending()
			&& $plan->paymentPlanType() !== 'addon'
			&& ! isset( $values['status'] )
		) {
			$values['status'] = $application->Entity_Status( $entity->getType(), 'draft' );
		}
		if ( ! empty( $values ) ) {
			$application->Entity_Save( $entity, $values );
			// Update translated posts
			foreach ( $application->Entity_Translations( $entity, false ) as $_entity ) {
				$application->Entity_Save( $_entity, $values );
			}
		}

		return $entity;
	}

	protected function _applyFeatures( Application $application, IEntity $entity, array &$featuresMeta, array &$featuresUpdated, $orderId, $isAddon = false ) {
		$values_to_save = array(
			'payment_plan' => array(
				'addon_features' => (array) $entity->getSingleFieldValue( 'payment_plan', 'addon_features' ),
			),
		);

		// Apply features in feature group
		if ( ! empty( $featuresMeta['features'] ) ) {
			foreach ( array_keys( $featuresMeta['features'] ) as $feature_name ) {
				if ( ( ! $ifeature = $application->Payment_Features_impl( $feature_name, true ) )
					|| $featuresMeta['features'][ $feature_name ]['status'] === PaymentComponent::FEATURE_STATUS_APPLIED
				) {
					continue;
				}

				switch ( $featuresMeta['features'][ $feature_name ]['status'] ) {
					case PaymentComponent::FEATURE_STATUS_UNAPPLIED:
					case PaymentComponent::FEATURE_STATUS_PENDING:
					case PaymentComponent::FEATURE_STATUS_FAILED_APPLY:
						if ( false !== $ifeature->paymentFeatureApply( $entity, $feature_name, $featuresMeta['features'][ $feature_name ]['settings'], $values_to_save, $orderId, $isAddon ) ) {
							$featuresMeta['features'][ $feature_name ]['status'] = PaymentComponent::FEATURE_STATUS_APPLIED;
							$featuresUpdated[ $feature_name ]                    = $featuresMeta['features'][ $feature_name ]['settings'];
						} else {
							$featuresMeta['features'][ $feature_name ]['status'] = PaymentComponent::FEATURE_STATUS_FAILED_APPLY;
						}
						break;
					default:
				}
			}
		}

		// Save entity and feature logs
		if ( ! empty( $values_to_save ) ) {
			$entity = $application->Entity_Save( $entity, $values_to_save );
		}

		return $entity;
	}

	protected function _unapplyFeatures( Application $application, IEntity $entity, array $featuresMeta, array &$featuresUpdated, array &$values, $orderId, $isAddon = false ) {
		if ( ! $remove_plan = isset( $values['payment_plan'] ) && empty( $values['payment_plan'] ) ) {
			$values['payment_plan']['addon_features'] = (array) $entity->getSingleFieldValue( 'payment_plan', 'addon_features' );
		}

		// Unapply each feature in feature group
		if ( ! empty( $featuresMeta['features'] ) ) {
			foreach ( array_keys( $featuresMeta['features'] ) as $feature_name ) {
				if ( $feature_name === 'payment_plan'
					&& ! $remove_plan
				) {
					continue;
				}

				if ( ! $ifeature = $application->Payment_Features_impl( $feature_name, true ) ) {
					continue;
				}

				switch ( $featuresMeta['features'][ $feature_name ]['status'] ) {
					case PaymentComponent::FEATURE_STATUS_APPLIED:
					case PaymentComponent::FEATURE_STATUS_FAILED_UNAPPLY:
						if ( false !== $ifeature->paymentFeatureUnapply( $entity, $feature_name, $featuresMeta['features'][ $feature_name ]['settings'], $values, $orderId, $isAddon ) ) {
							$featuresMeta['features'][ $feature_name ]['status'] = PaymentComponent::FEATURE_STATUS_UNAPPLIED;
							$featuresUpdated[]                                   = $featuresMeta['features'][ $feature_name ];
						} else {
							$featuresMeta['features'][ $feature_name ]['status'] = PaymentComponent::FEATURE_STATUS_FAILED_UNAPPLY;
						}
						break;
					case PaymentComponent::FEATURE_STATUS_PENDING:
						$featuresMeta['features'][ $feature_name ]['status'] = PaymentComponent::FEATURE_STATUS_UNAPPLIED;
						$featuresUpdated[ $feature_name ]                    = $featuresMeta['features'][ $feature_name ]['settings'];
						break;
					default:
				}
			}
		}
	}

	public function render( Application $application, array $features, Bundle $bundle, ?IPlan $plan = null ) {
		$ret = array();
		foreach ( $features as $feature_name => $feature_settings ) {
			if ( ( ! $feature = $application->Payment_Features_impl( $feature_name, true ) )
				|| ! $feature->paymentFeatureIsEnabled( $bundle, $feature_settings )
				|| ( ! $rendered = $feature->paymentFeatureRender( $bundle, $feature_settings, $plan ) )
			) {
				continue;
			}

			$ret[ $feature_name ] = $rendered;
		}

		if ( $ret = $application->Filter( 'payment_plan_features', $ret, array( $bundle, $plan ) ) ) {
			// Load default CSS files
			$application->getPlatform()->loadDefaultAssets( false, true );
		}

		return $ret;
	}

	public function applyAddonFeature( Application $application, IEntity $entity, $featureName, array $featureSettings, array &$values, $orderId, $isMultiple = false ) {
		if ( ! $entity->getSingleFieldValue( 'payment_plan', 'plan_id' ) ) {
			return; // needs a plan associated in order to apply add-ons
		}

		if ( isset( $values['payment_plan']['addon_features'][ $featureName ] ) ) {
			if ( $isMultiple ) {
				foreach ( array_keys( $featureSettings ) as $key ) {
					if ( ! isset( $values['payment_plan']['addon_features'][ $featureName ][ $key ] ) ) {
						continue;
					}

					$this->_doApplyAddonFeature( $application, $featureSettings[ $key ], $values['payment_plan']['addon_features'][ $featureName ][ $key ], $orderId );
				}
			} else {
				$this->_doApplyAddonFeature( $application, $featureSettings, $values['payment_plan']['addon_features'][ $featureName ], $orderId );
			}
		}
		$values['payment_plan']['addon_features'][ $featureName ] = $featureSettings;

		return true;
	}

	private function _doApplyAddonFeature( Application $application, &$featureSettings, array $value, $orderId ) {
		if ( ! empty( $value['num'] ) ) {
			if ( empty( $featureSettings['num'] ) ) {
				$featureSettings['num'] = 0;
			}
			$featureSettings['num'] += $value['num'];
		}
		if ( ! empty( $value['unlimited'] ) ) {
			$featureSettings['unlimited'] = true;
		} elseif ( ! empty( $featureSettings['unlimited'] ) ) {
				$featureSettings['unlimited_by'] = $orderId;
		}
	}

	public function unapplyAddonFeature( Application $application, IEntity $entity, $featureName, array $featureSettings, array &$values, $orderId, $isMultiple = false ) {
		if ( ! $entity->getSingleFieldValue( 'payment_plan', 'plan_id' ) ) {
			return; // needs a plan associated in order to apply add-ons
		}

		if ( isset( $values['payment_plan']['addon_features'][ $featureName ] ) ) {
			if ( $isMultiple ) {
				foreach ( array_keys( $featureSettings ) as $key ) {
					if ( ! isset( $values['payment_plan']['addon_features'][ $featureName ][ $key ] ) ) {
						continue;
					}

					$this->_doUnApplyAddonFeature( $application, $featureSettings[ $key ], $values['payment_plan']['addon_features'][ $featureName ][ $key ], $orderId );
				}
			} else {
				$this->_doUnApplyAddonFeature( $application, $featureSettings, $values['payment_plan']['addon_features'][ $featureName ], $orderId );
			}
		}

		return true;
	}

	private function _doUnApplyAddonFeature( Application $application, &$featureSettings, array $value, $orderId ) {
		if ( ! empty( $value['num'] )
			&& ! empty( $featureSettings['num'] )
		) {
			$value['num'] -= $featureSettings['num'];
			if ( $value['num'] < 0 ) {
				unset( $value['num'] );
			}
		}
		if ( ! empty( $value['unlimited'] )
			&& ! empty( $featureSettings['unlimited'] )
		) {
			if ( ! empty( $value['unlimited_by'] ) ) {
				if ( $value['unlimited_by'] == $orderId ) {
					unset( $value['unlimited'] );
				}
			} else {
				unset( $value['unlimited'] );
			}
		}
	}
}
