<?php
namespace SabaiApps\Directories\Component\Location\PaymentFeature;

use SabaiApps\Directories\Component\Entity\Model\Bundle;
use SabaiApps\Directories\Component\Entity\Type\IEntity;
use SabaiApps\Directories\Component\Payment;

class LocationsPaymentFeature extends Payment\Feature\AbstractFeature implements Payment\Feature\IAddonFeature {

	protected function _paymentFeatureInfo() {
		return array(
			'label'            => __( 'Location Settings', 'directories-pro' ),
			'weight'           => 7,
			'default_settings' => array(
				'unlimited' => false,
				'num'       => 1,
			),
		);
	}

	public function paymentFeatureSupports( Bundle $bundle, $planType = 'base' ) {
		return ! empty( $bundle->info['location_enable'] );
	}

	public function paymentFeatureSettingsForm( Bundle $bundle, array $settings, $planType = 'base', array $parents = array() ) {
		if ( ! $location_bundle = $this->_application->Entity_Bundle( 'location_location', $bundle->group ) ) {
			return;
		}

		return array(
			'unlimited' => array(
				'#title'         => $this->_maxNumAllowedLabel( $location_bundle->getLabel() ),
				'#on_label'      => __( 'Unlimited', 'directories-pro' ),
				'#type'          => 'checkbox',
				'#switch'        => false,
				'#default_value' => ! empty( $settings['unlimited'] ),
				'#horizontal'    => true,
			),
			'num'       => array(
				'#type'          => 'slider',
				'#default_value' => isset( $settings['num'] ) ? $settings['num'] : 1,
				'#integer'       => true,
				'#min_value'     => 0,
				'#max_value'     => 50,
				'#states'        => array(
					'invisible' => array(
						sprintf( 'input[name="%s[unlimited][]"]', $this->_application->Form_Form_fieldName( $parents ) ) => array(
							'type'  => 'checked',
							'value' => true,
						),
					),
				),
				'#horizontal'    => true,
			),
		);
	}

	public function paymentFeatureApply( IEntity $entity, $featureName, array $featureSettings, array &$values, $orderId, $isAddon = false ) {
		if ( ! $isAddon ) {
			return;
		}

		return $this->_applyAddonFeature( $entity, $featureName, $featureSettings, $values, $orderId );
	}

	public function paymentFeatureUnapply( IEntity $entity, $featureName, array $featureSettings, array &$values, $orderId, $isAddon = false ) {
		if ( ! $isAddon ) {
			return;
		}

		return $this->_unapplyAddonFeature( $entity, $featureName, $featureSettings, $values, $orderId );
	}

	public function paymentFeatureOnEntityForm( Bundle $bundle, array $settings, array &$form, ?IEntity $entity = null, $isAdmin = false ) {
		if ( $isAdmin && $this->_application->IsAdministrator() ) {
			return; // do not restrict for administrators
		}

		if ( empty( $bundle->info['location_enable'] ) ) {
			return;
		}

		if ( ! isset( $form['location_address'][0] ) ) {
			return; // Field does not exist
		}

		if ( empty( $settings['unlimited'] ) ) {
			$limit = $settings['num'];

			if ( empty( $limit ) ) {
				// No locations allowed
				unset( $form['location_address'] );
				return;
			}

			if ( isset( $form['#entity_field_max_num_items']['location_address'] ) ) {
				if ( empty( $form['#entity_field_max_num_items']['location_address'] )
					|| $form['#entity_field_max_num_items']['location_address'] > $limit
				) {
					$form['#entity_field_max_num_items']['location_address'] = $limit;
				} else {
					return;
				}
			} else {
				$form['#entity_field_max_num_items']['location_address'] = $limit;
			}

			// Remove fields over limit
			$current_num = 0;
			foreach ( array_keys( $form['location_address'] ) as $key ) {
				if ( is_numeric( $key ) ) {
					++$current_num;
					if ( $current_num > $limit ) {
						// over limit
						unset( $form['location_address'][ $key ] );
					}
				}
			}
			if ( $limit > 1 ) {
				// Add add more button
				$form['location_address']['_add'] = array(
					'#type'       => 'addmore',
					'#next_index' => $current_num,
					'#max_num'    => $limit,
					'#hidden'     => $current_num >= $limit,
				);
			} else {
				// May already be added if max number of values for the field is > 1
				unset( $form['location_address']['_add'] );
			}
		} else {
			if ( ! isset( $form['#entity_field_max_num_items']['location_address'] ) ) {
				$form['#entity_field_max_num_items']['location_address'] = 0;
			} elseif ( $form['#entity_field_max_num_items']['location_address'] !== 0 ) {
					return;
			}

			$current_num = 0;
			foreach ( array_keys( $form['location_address'] ) as $key ) {
				if ( is_numeric( $key ) ) {
					++$current_num;
				}
			}
			// Add add more button
			$form['location_address']['_add'] = array(
				'#type'       => 'addmore',
				'#next_index' => $current_num,
			);
		}
	}

	public function paymentFeatureOnEntityFieldValues( IEntity $entity, Bundle $bundle, array $settings ) {
		if ( empty( $bundle->info['location_enable'] ) ) {
			return;
		}

		if ( ! empty( $settings['unlimited'] ) ) {
			return;
		}

		if ( ! isset( $settings['num'] ) ) {
			$max_num_allowed = 1;
		} else {
			$max_num_allowed = empty( $settings['num'] ) ? 0 : $settings['num'];
		}

		// Limit both taxonomy term and address fields
		foreach ( array( 'location_location', 'location_address' ) as $field_name ) {
			if ( ( ! $field_values = $entity->getFieldValue( $field_name ) )
				|| count( $field_values ) <= $max_num_allowed
			) {
				continue;
			}

			$entity->setFieldValue( $field_name, array_slice( $field_values, 0, $max_num_allowed ) );
		}
	}

	public function paymentFeatureRender( Bundle $bundle, array $settings, ?Payment\IPlan $plan = null ) {
		if ( ! $location_bundle = $this->_application->Entity_Bundle( 'location_location', $bundle->group ) ) {
			return;
		}

		if ( empty( $settings['unlimited'] ) ) {
			$label = sprintf( $this->_application->H( $location_bundle->getLabel( $settings['num'] > 1 ? 'count2' : 'count' ) ), '<em>' . $settings['num'] . '</em>' );
		} else {
			$label = sprintf( $this->_application->H( $location_bundle->getLabel( 'count2' ) ), '<em>' . $this->_application->H( __( 'Unlimited', 'directories-pro' ) ) . '</em>' );
		}
		return array(
			array(
				'icon'     => $this->_application->Entity_BundleTypeInfo( $location_bundle, 'icon' ),
				'html'     => $label,
				'settings' => $settings,
			),
		);
	}

	public function paymentAddonFeatureSupports( Bundle $bundle ) {
		return $this->paymentFeatureSupports( $bundle );
	}

	protected function _getAddonSettingsForm( Bundle $bundle, array $settings, array $parents = array(), $horizontal = true ) {
		if ( ! $location_bundle = $this->_application->Entity_Bundle( 'location_location', $bundle->group ) ) {
			return;
		}

		return array(
			'num' => array(
				'#title'         => $this->_additionalNumAllowedLabel( $location_bundle->getLabel() ),
				'#type'          => 'slider',
				'#default_value' => isset( $settings['num'] ) ? $settings['num'] : 0,
				'#integer'       => true,
				'#min_value'     => 0,
				'#max_value'     => 20,
				'#horizontal'    => $horizontal,
			),
		);
	}

	public function paymentAddonFeatureSettingsForm( Bundle $bundle, array $settings, array $parents = array() ) {
		return $this->_getAddonSettingsForm( $bundle, $settings, $parents );
	}

	public function paymentAddonFeatureExtraSettingsForm( Bundle $bundle, array $planFeatures, array $currentExtraFeatures, array $parents = array() ) {
		return $this->_getAddonSettingsForm( $bundle, $currentExtraFeatures, $parents, false );
	}

	public function paymentAddonFeatureIsEnabled( Bundle $bundle, array $settings ) {
		return ! empty( $settings['num'] ) && intval( $settings['num'] ) > 0;
	}

	public function paymentAddonFeatureIsOrderable( array $settings, array $currentFeatures ) {
		return $this->paymentAddonFeatureExtraIsOrderable( $currentFeatures );
	}

	public function paymentAddonFeatureExtraIsOrderable( array $planFeatures ) {
		return empty( $planFeatures[ $this->_name ]['unlimited'] );
	}

	public function paymentAddonFeatureExtraApply( $feature, $extra ) {
		if ( empty( $feature['unlimited'] )
			&& ! empty( $extra['num'] )
		) {
			$feature['num'] += $extra['num'];
		}
		return $feature;
	}
}
