<?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\Field\Type\ILinkable;

class LinkHelper {

	public function help( Application $application, IEntity $entity, array $settings, $label, array $options = array(), array $attr = array() ) {
		switch ( $settings['link_type'] ) {
			case 'current':
				$fragment = isset( $settings['link_fragment'] ) ? $settings['link_fragment'] : '';
				$url      = $application->Entity_PermalinkUrl( $entity, $fragment );
				break;
			case 'parent':
				if ( ! $parent = $application->Entity_ParentEntity( $entity ) ) {
					return $label;
				}

				$fragment = isset( $settings['link_fragment'] ) ? $settings['link_fragment'] : '';
				$url      = $application->Entity_PermalinkUrl( $parent, $fragment );
				break;
			case 'url':
				$url = $application->Entity_Tokens_replace(
					$settings['link_url'],
					$entity,
					true,
					array(
						'escape' => false,
						'encode' => true,
					)
				);
				break;
			case 'field':
				if ( empty( $settings['link_field'] )
					|| ( ! $link_field = $application->Entity_Field( $entity, $settings['link_field'] ) )
					|| ( ! $link_field_type = $application->Field_Type( $link_field->getFieldType(), true ) )
					|| ! $link_field_type instanceof ILinkable
					|| ( ! $url = $link_field_type->fieldLinkableUrl( $link_field, $entity ) )
				) {
					return $label;
				}

				if ( isset( $settings['link_field_qstr'] ) && strlen( $settings['link_field_qstr'] ) ) {
					$separator = strpos( $url, '?' ) === false ? '?' : '&';
					$url      .= $separator . $settings['link_field_qstr'];
				}
				break;
			default:
				return $label;
		}
		if ( ! empty( $settings['link_target'] ) ) {
			$attr['target'] = $settings['link_target'];
		}
		if ( ! empty( $settings['link_rel'] ) ) {
			$attr['rel'] = implode( ' ', $settings['link_rel'] );
		}

		return $application->LinkTo( $label, array( 'script_url' => (string) $url ), $options, $attr );
	}

	public function settingsForm( Application $application, Bundle $bundle, array $settings, array $parents = array(), $weight = 0, $horizontal = true ) {
		$ret = array(
			'link_type'     => array(
				'#type'          => 'select',
				'#options'       => array(
					''        => __( 'Do not link', 'directories-pro' ),
					'current' => __( 'Link to current content URL', 'directories-pro' ),
					'url'     => __( 'Link to external URL', 'directories-pro' ),
				),
				'#title'         => __( 'Link type', 'directories-pro' ),
				'#horizontal'    => $horizontal,
				'#default_value' => isset( $settings['link_type'] ) ? $settings['link_type'] : null,
				'#weight'        => $weight + 1,
			),
			'link_fragment' => array(
				'#title'         => __( 'URL fragment identifier', 'directories-pro' ),
				'#description'   => __( 'Add a fragment identifier to the link URL in order to link to a specific section of the page.', 'directories-pro' ),
				'#type'          => 'textfield',
				'#field_prefix'  => '#',
				'#default_value' => isset( $settings['link_fragment'] ) ? $settings['link_fragment'] : null,
				'#horizontal'    => $horizontal,
				'#states'        => array(
					'visible' => array(
						$link_type_selector = sprintf( 'select[name="%s[link_type]"]', $application->Form_Form_fieldName( $parents ) ) => array( 'value' => 'current' ),
					),
				),
				'#weight'        => $weight + 3,
			),
			'link_url'      => array(
				'#type'                  => 'url',
				'#placeholder'           => 'https://',
				'#default_value'         => isset( $settings['link_url'] ) ? $settings['link_url'] : null,
				'#horizontal'            => $horizontal,
				'#states'                => array(
					'visible' => array(
						$link_type_selector => array(
							'type'  => 'one',
							'value' => array( 'url' ),
						),
					),
				),
				'#description'           => $application->System_Util_availableTags(
					$application->Entity_Tokens(
						$bundle,
						true,
						array(
							'site'           => true,
							'current_user'   => true,
							'auto_increment' => true,
						)
					)
				),
				'#description_no_escape' => true,
				'#max_length'            => 0,
				'#weight'                => $weight + 2,
			),
			'link_target'   => array(
				'#title'         => __( 'Open link in', 'directories-pro' ),
				'#type'          => 'select',
				'#options'       => $this->_getLinkTargetOptions(),
				'#default_value' => isset( $settings['link_target'] ) ? $settings['link_target'] : null,
				'#horizontal'    => $horizontal,
				'#weight'        => $weight + 10,
				'#states'        => array(
					'invisible' => array(
						$link_type_selector => array( 'value' => '' ),
					),
				),
			),
			'link_rel'      => array(
				'#title'         => __( 'Link "rel" attribute', 'directories-pro' ),
				'#type'          => 'checkboxes',
				'#options'       => $this->_getLinkRelAttrOptions(),
				'#default_value' => isset( $settings['link_rel'] ) ? $settings['link_rel'] : null,
				'#horizontal'    => $horizontal,
				'#states'        => array(
					'visible' => array(
						$link_type_selector => array(
							'type'  => 'one',
							'value' => array( 'url' ),
						),
					),
				),
				'#weight'        => $weight + 11,
			),
		);
		if ( ! empty( $bundle->info['parent'] )
			|| ! empty( $bundle->info['parent_field'] )
		) {
			$ret['link_type']['#options']['parent'] = __( 'Link to parent page', 'directories-pro' );
		}

		if ( $linkable_fields = $application->Entity_Field_options(
			$bundle,
			array(
				'interface'       => 'Field\Type\ILinkable',
				'return_disabled' => true,
			)
		) ) {
			$ret['link_type']['#options']['field']                                   = __( 'Link to URL of another field', 'directories-pro' );
			$ret['link_rel']['#states']['visible'][ $link_type_selector ]['value'][] = 'field';
			$ret['link_field']      = array(
				'#type'             => 'select',
				'#default_value'    => isset( $settings['link_field'] ) ? $settings['link_field'] : null,
				'#options'          => $linkable_fields[0],
				'#options_disabled' => $linkable_fields[1],
				'#required'         => function ( $form ) use ( $parents ) {
					return in_array( $form->getValue( array_merge( $parents, array( 'link_type' ) ) ), array( 'field' ) ); },
				'#states'           => array(
					'visible' => array(
						$link_type_selector => array( 'value' => 'field' ),
					),
				),
				'#weight'           => $weight + 2,
				'#horizontal'       => $horizontal,
			);
			$ret['link_field_qstr'] = array(
				'#type'          => 'textfield',
				'#default_value' => isset( $settings['link_field_qstr'] ) ? $settings['link_field_qstr'] : null,
				'#field_prefix'  => __( 'Additional query string', 'directories-pro' ),
				'#placeholder'   => 'a=1&b=2&c=3',
				'#states'        => array(
					'visible' => array(
						$link_type_selector => array( 'value' => 'field' ),
					),
				),
				'#weight'        => $weight + 2,
				'#horizontal'    => $horizontal,
			);
		}

		return $ret;
	}

	protected function _getLinkTargetOptions() {
		return array(
			''       => __( 'Current window', 'directories-pro' ),
			'_blank' => __( 'New window', 'directories-pro' ),
		);
	}

	protected function _getLinkRelAttrOptions() {
		return array(
			'nofollow'  => __( 'Add "nofollow"', 'directories-pro' ),
			'external'  => __( 'Add "external"', 'directories-pro' ),
			'ugc'       => __( 'Add "ugc"', 'directories-pro' ),
			'sponsored' => __( 'Add "sponsored"', 'directories-pro' ),
		);
	}
}
