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

use SabaiApps\Directories\Application;
use SabaiApps\Directories\Component\Entity\Model\Bundle;
use SabaiApps\Directories\Component\Entity\Type\IEntity;
use SabaiApps\Directories\Component\Form\Form;

class LevelsHelper {

	public function defaultLevel( Application $application, $bundle ) {
		$bundle = $application->Entity_Bundle( $bundle, '', true );
		if ( ! isset( $bundle->info['entity_levels']['default'] ) ) {
			$info = $bundle->info;
			if ( isset( $info['payment_default_features'] ) ) { // For compat with v1.3.x which are using payment features
				$features = (array) $info['payment_default_features'];
				if ( ! empty( $features ) ) {
					foreach ( array(
						'payment_fields'         => 'entity_fields',
						'payment_taxonomy_terms' => 'entity_taxonomy_terms',
					) as $name => $replace ) {
						if ( isset( $features[ $name ] ) ) {
							$features[ $replace ] = $features[ $name ];
							unset( $features[ $name ] );
						}
					}
				}
				unset( $info['payment_default_features'] );
			} else {
				$features = array();
			}
			$info['entity_levels']['default'] = array(
				'label'    => __( 'Default', 'directories-pro' ),
				'features' => $features,
			);
			$bundle->setInfo( $info )->commit();
		}
		return $bundle->info['entity_levels']['default'];
	}

	/**
	 * @param Application           $application
	 * @param Bundle|string|IEntity $bundle
	 * @param string                $level
	 * @return array
	 */
	public function features( Application $application, $bundle, $level = null ) {
		if ( ! $bundle instanceof Bundle
			&& ( ! $bundle = $application->Entity_Bundle( $bundle ) )
		) {
			return array();
		}

		if ( isset( $level )
			&& isset( $bundle->info['entity_levels'][ $level ] )
		) {
			$features = $bundle->info['entity_levels'][ $level ]['features'];
		} else {
			$features = $this->defaultLevel( $application, $bundle )['features'];
		}
		return empty( $features['enabled'] ) ? array() : $features['enabled'];
	}

	public function options( Application $application, Bundle $bundle, $includeDefault = true ) {
		$options = array();
		if ( ! empty( $bundle->info['entity_levels'] ) ) {
			foreach ( array_keys( $bundle->info['entity_levels'] ) as $level_name ) {
				$options[ $level_name ] = $bundle->info['entity_levels'][ $level_name ]['label'];
			}
		}
		if ( $includeDefault ) {
			if ( ! isset( $levels['default'] ) ) {
				$options = array( 'default' => __( 'Default', 'directories-pro' ) ) + $options;
			}
			if ( (int) $includeDefault > 1 ) {
				// Move default to last
				unset( $options['default'] );
				$options['default'] = __( 'Default', 'directories-pro' );
			}
		} else {
			unset( $options['default'] );
		}
		return $options;
	}

	public function settingsForm( Application $application, Bundle $bundle ) {
		$application->getPlatform()->loadJqueryUiJs( array( 'sortable' ) )->addJsFile(
			'entity-admin-feature-levels.min.js',
			'drts-entity-admin-feature-levels',
			'drts',
			'directories-pro'
		);
		$application->Form_Scripts( array( 'latinise', 'slider' ) );
		$add_path    = '/directories/' . $bundle->group . '/content_types/' . $bundle->name . '/add_level';
		$edit_link   = '<span class="' . DRTS_BS_PREFIX . 'btn ' . DRTS_BS_PREFIX . 'btn-sm ' . DRTS_BS_PREFIX . 'btn-outline-secondary drts-directorypro-edit-feature-level"><i class="fas fa-cog fa-fw"></i></span>';
		$delete_link = '<span class="' . DRTS_BS_PREFIX . 'btn ' . DRTS_BS_PREFIX . 'btn-sm ' . DRTS_BS_PREFIX . 'btn-outline-danger drts-directorypro-delete-feature-level"><i class="fas fa-trash fa-fw"></i></span>';
		foreach ( $application->Entity_Levels_options( $bundle ) as $level_name => $level_label ) {
			$links = array( $edit_link );
			if ( $level_name !== 'default' ) {
				$links[] = $delete_link;
			}
			$levels[ $level_name ] = array(
				'name'  => '<span class="">' . $level_name . '</span>',
				'label' => $level_label,
				'links' => implode( PHP_EOL, $links ),
			);
		}

		return array(
			'entity_levels' => array(
				'#title'            => __( 'Feature levels', 'directories-pro' ),
				'#horizontal'       => true,
				'#states'           => array(
					'visible' => array(
						'input[name="entity_level"]' => array(
							'type'  => 'checked',
							'value' => true,
						),
					),
				),
				'#tree'             => true,
				'#element_validate' => array(
					function ( Form $form, &$value, $element ) use ( $bundle ) {
							$levels = empty( $bundle->info['entity_levels'] ) ? array() : $bundle->info['entity_levels'];
						foreach ( array_keys( $levels ) as $level_name ) {
							if ( ! isset( $value[0][ $level_name ] ) ) {
								if ( $level_name !== 'default' ) {
									unset( $levels[ $level_name ] );
								}
							} else {
								$levels[ $level_name ]['label'] = $value[0][ $level_name ]['label'];
							}
						}
							// Sort as submitted
							$levels_sorted = array();
						foreach ( array_keys( $value[0] ) as $level_name ) {
							$levels_sorted[ $level_name ] = $levels[ $level_name ];
						}
						if ( ! isset( $levels_sorted['default'] ) ) {
							$levels_sorted['default'] = array(
								'label'    => __( 'Default', 'directories-pro' ),
								'features' => array(),
							);
						}
							// Move default level to top
							$value = array( 'default' => $levels_sorted['default'] ) + $levels_sorted;
					},
				),
				0                   => array(
					'#type'              => 'grid',
					'#size'              => 'sm',
					'#class'             => 'drts-data-table',
					'#id'                => '__FORM_ID__-entity-levels',
					'#js_ready'          => 'DRTS.Entity.adminFeatureLevels("#__FORM_ID__-entity-levels", {
                        adminUrl: "' . (string) $application->Url( $add_path, array( 'field_id' => '__FORM_ID__-entity-levels' ), '', '&' ) . '"
                    });',
					'#element_validate'  => array(
						function ( Form $form, &$value, $element ) {
							foreach ( array_keys( $value ) as $level_name ) {
								if ( ! isset( $_POST['entity_levels'][0][ $level_name ] ) ) {
									// was removed
									unset( $value[ $level_name ] );
									continue;
								}
								foreach ( array( 'label' ) as $key ) {
									if ( empty( $value[ $level_name ][ $key ] )
										|| ! strlen( $value[ $level_name ][ $key ] = trim( $value[ $level_name ][ $key ] ) )
									) {
										$form->setError( sprintf( 'Label for feature level (%s) may not be empty.', $level_name ), $element );
										return;
									}
								}
							}
						},
					),
					'label'              => array(
						'#type'  => 'textfield',
						'#title' => __( 'Label', 'directories-pro' ),
					),
					'name'               => array(
						'#type'  => 'markup',
						'#title' => _x( 'Name', 'feature level name', 'directories-pro' ),
					),
					'links'              => array(
						'#type'  => 'markup',
						'#title' => '',
					),
					'#column_attributes' => array(
						'label' => array( 'style' => 'width:50%;' ),
						'name'  => array( 'style' => 'width:30%;' ),
						'links' => array( 'style' => 'width:20%;' ),
					),
					'#row_attributes'    => array(
						'@all' => array(
							'links' => array(
								'style' => 'text-align:' . $application->getPlatform()->isRtl() ? 'left;' : 'right;',
							),
						),
					),
					'#default_value'     => $levels,
					'#default_markup'    => $levels,
				),
				'_add'              => array(
					'#type'   => 'markup',
					'#markup' => $application->LinkTo(
						'<i class="fas fa-plus fa-fw"></i> ' . $application->H( __( 'Add Feature Level', 'directories-pro' ) ),
						$application->Url( $add_path, array( 'field_id' => '__FORM_ID__-entity-levels' ) ),
						array(
							'container' => 'modal',
							'modalSize' => 'xl',
							'no_escape' => true,
						),
						array( 'class' => DRTS_BS_PREFIX . 'btn ' . DRTS_BS_PREFIX . 'btn-sm ' . DRTS_BS_PREFIX . 'btn-outline-secondary ' . DRTS_BS_PREFIX . 'mt-2' )
					),
				),
			),
		);
	}

	public function hasFeature( Application $application, IEntity $entity, $featureName ) {
		$features = $this->featuresByEntity( $application, $entity );
		return array_key_exists( $featureName, $features ) ? $features[ $featureName ] : false;
	}

	public function featuresByEntity( Application $application, IEntity $entity ) {
		if ( ! $application->Entity_BundleTypeInfo( $entity->getBundleType(), 'levelable' ) ) {
			return array();
		}

		if ( ! isset( $entity->data['entity_level_features'] ) ) {
			if ( $level = $application->Filter( 'entity_level', $entity->getSingleFieldValue( 'entity_level' ), array( $entity ) ) ) {
				$features = $this->features( $application, $entity, $level );
			} elseif ( null === $features = $application->Filter( 'entity_level_features', null, array( $entity ) ) ) {
					// No features, get default level features
					$features = $this->features( $application, $entity );
			}
			$entity->data['entity_level_features'] = $features;
		}
		return $entity->data['entity_level_features'];
	}
}
