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

use SabaiApps\Directories\Application;
use SabaiApps\Directories\Component\Entity\Type\IEntity;

class PermalinkUrlHelper {

	public function help( Application $application, IEntity $entity, $fragment = '', $lang = null, array $params = array(), $altBundle = null ) {
		$url = (string) $application->Url(
			array(
				'route'    => $this->path( $application, $entity, $lang, $altBundle ),
				'params'   => $params,
				'fragment' => $fragment,
				'script'   => 'main',
			)
		);

		return $application->Filter( 'entity_permalink_url', $url, array( $entity, $fragment, $lang ) );
	}

	public function path( Application $application, IEntity $entity, $lang = null, $altBundle = null ) {
		if ( ! $bundle = $application->Entity_Bundle( $entity ) ) {
			return '';
		}

		if ( ! isset( $lang ) ) {
			$lang = $application->getPlatform()->getLanguageFor( $entity->getType(), $bundle->name, $entity->getId() );
		}

		if ( empty( $bundle->info['parent'] ) ) {
			if ( empty( $bundle->info['is_taxonomy'] ) ) {
				$permalink_type = $bundle->info['permalink_type'] ?? 'hierarchical';
				switch ( $permalink_type ) {
					case 'flat':
						$path = $bundle->getPath( false, $lang );
						break;
					case '114compat':
						$path = '/' . ( $bundle->info['permalink_slug_114'] ?? ( $bundle->group . '-' . $bundle->info['slug'] ) );
						break;
					default:
						$path = $bundle->getPath( true, $lang );
				}
			} elseif ( isset( $altBundle )
					&& ( $alt_bundle = $application->Entity_Bundle( $altBundle ) )
				) {

					$path = $alt_bundle->getPath( true, $lang );
			} else {
				$path = $bundle->getPath( true, $lang );
			}
			if ( ! isset( $permalink_path )
				&& ! empty( $bundle->info['permalink_path'] )
			) {
				$permalink_path = $bundle->info['permalink_path'];
			}
			if ( isset( $permalink_path ) ) {
				$path .= '/' . $permalink_path;
				if ( false !== strpos( $path, '%slug%' ) ) {
					$path = str_replace( '%slug%', $entity->getSlug(), $path );
				}
				if ( false !== strpos( $path, '%id%' ) ) {
					$path = str_replace( '%id%', $entity->getId(), $path );
				}
				if ( empty( $bundle->info['is_taxonomy'] ) ) {
					if ( strpos( $path, '%' ) !== false
						&& ! empty( $bundle->info['taxonomies'] )
					) {
						foreach ( array_keys( $bundle->info['taxonomies'] ) as $taxonomy_type ) {
							$tag = '%' . $taxonomy_type . '%';
							if ( strpos( $path, $tag ) === false ) {
								continue;
							}

							if ( $terms = $entity->getFieldValue( $taxonomy_type ) ) {
								$term = $this->_getPrimaryTerm( $application, $entity->getId(), $terms );
								$slug = '/' . $term->getSlug();
								if ( $parent_slugs = $term->getCustomProperty( 'parent_slugs' ) ) {
									$slug = '/' . implode( '/', $parent_slugs ) . $slug;
								}
							} else {
								$slug = '';
							}
							$path = str_replace( '/' . $tag, $slug, $path );
						}
					}
				} elseif ( strpos( $path, '%parent_term%' ) !== false ) {
					if ( ! $parent_slugs = $entity->getCustomProperty( 'parent_slugs' ) ) {
						$parent_slugs = array();
						if ( $parent_ids = $application->Entity_Types_impl( 'term' )->entityTypeParentEntityIds( $entity->getId(), $bundle->name ) ) {
							foreach ( $application->Entity_Entities( 'term', $parent_ids, false, true ) as $parent_id => $parent_entity ) {
								$parent_slugs[ $parent_id ] = $parent_entity->getSlug();
							}
						}
					}
						$path = str_replace( '/' . '%parent_term%', ( $parent_slugs ? '/' . implode( '/', $parent_slugs ) : '' ), $path );
				}
			} else {
				$path .= '/' . $entity->getSlug();
			}
		} else {
			$path = $bundle->getPath( true, $lang ) . '/' . $entity->getId() . '/' . $entity->getSlug();
		}
		if ( strlen( $path ) ) {
			$path = rtrim( $path, '/' );
			if ( $application->addUrlTrailingSlash() ) {
				$path .= '/';
			}
		}

		return $path;
	}

	protected function _getPrimaryTerm( Application $application, $postId, array $terms ) {
		$keys = array_keys( $terms );
		if ( count( $keys ) <= 1
			|| ( ! $primary_term = $application->Filter( 'entity_primary_term', null, array( $postId, $terms[ $keys[0] ]->getBundleName(), $terms ) ) )
		) {
			$primary_term = $terms[ $keys[0] ];
		}
		return $primary_term;
	}
}
