<?php
/**
 * RemoveTaxonomyBase
 *
 * @package CommonFrameworkPlugin
 */

namespace CommonFrameworkPlugin;

use WP_CLI;

/**
 * Handles the removal of taxonomy base and custom post type rewrite rules.
 */
class RemoveTaxonomyBase extends \CommonFrameworkPlugin\Module {

	/**
	 * Determines if the module can register.
	 *
	 * @return bool True if the module can register.
	 */
	public function can_register() {
		return true;
	}

	/**
	 * Registers the necessary hooks for the module.
	 *
	 * @return void
	 */
	public function register() {
		add_action( 'init', [ $this, 'main' ], 11 );
	}

	/**
	 * Main function to handle rewrite rule modifications for custom post types and taxonomies.
	 *
	 * @return void
	 */
	public function main() {
		global $wp_rewrite;

		$args = array(
			'public'   => true,
			'_builtin' => false,
		);

		$post_types = get_post_types( $args );

		if ( ! empty( $post_types ) ) {
			foreach ( $post_types as $post_type ) {
				add_filter( $post_type . '_rewrite_rules', [ $this, 'remove_post_type_filter' ] );
			}
		}

		$taxonomies = [ 'product-category' ];

		if ( ! empty( $taxonomies ) ) {
			$global_tax = '';
			foreach ( $taxonomies as $taxonomy ) {
				$global_tax = $taxonomy;

				$blog_prefix = '';

				$wp_rewrite->extra_permastructs[ $taxonomy ]['struct'] = $blog_prefix . '%' . $taxonomy . '%';

				add_filter( $taxonomy . '_rewrite_rules', [ $this, 'rewrite_taxonomy_filter' ] );
				add_action( 'created_' . $taxonomy, 'flush_rewrite_rules' );
				add_action( 'edited_' . $taxonomy, 'flush_rewrite_rules' );
				add_action( 'delete_' . $taxonomy, 'flush_rewrite_rules' );
			}
		}

		if ( ! empty( $taxonomies ) && ! empty( $global_tax ) ) {
			add_filter( $taxonomy . '_rewrite_rules', [ $this, 'insert_post_type_filter' ] );
		}

		add_filter( 'rewrite_rules_array', [ $this, 'remove_post_type_base_filter' ] );
	}

	/**
	 * Removes post type base rewrite rules.
	 *
	 * @param array $post_type_rewrite The rewrite rules for the post type.
	 * @return array Modified rewrite rules.
	 */
	public function remove_post_type_filter( $post_type_rewrite ) {
		$count = 0;
		$value_we_need = '';

		foreach ( $post_type_rewrite as $one_value ) {
			++$count;
			if ( 6 === $count ) {
				$value_we_need = $one_value;
			}
		}

		preg_match( '/\x{003F}(.*?)=/', $value_we_need, $post_type_arr );
		$post_type = $post_type_arr[1];

		$taxonomies = [ 'product-category' ];

		foreach ( $taxonomies as $taxonomy ) {
			$terms = get_terms( $taxonomy ); // Removed deprecated second parameter
			foreach ( $terms as $term ) {
				$post_type_object = get_post_type_object( $post_type );
				if ( $post_type_object->rewrite && $post_type_object->rewrite['slug'] === $term->slug ) {
					$post_type_rewrite = array();
				}
			}
		}

		return $post_type_rewrite;
	}

	/**
	 * Rewrites taxonomy filter rules.
	 *
	 * @param array $term_rewrite The taxonomy rewrite rules.
	 * @return array Modified taxonomy rewrite rules.
	 */
	public function rewrite_taxonomy_filter( $term_rewrite ) {
		$taxonomy_name = '';

		foreach ( $term_rewrite as $one_value ) {
			preg_match( '#index.php.(?!attachment)(.*?)=.matches#', $one_value, $taxonomy_arr );

			if ( ! empty( $taxonomy_arr[1] ) ) {
				$taxonomy_name = $taxonomy_arr[1];
			}
		}

		if ( ! empty( $taxonomy_name ) ) {
			$args = array(
				'public'    => true,
				'show_ui'   => true,
			);

			$taxonomies = get_taxonomies( $args );

			foreach ( $taxonomies as $tax ) {
				$tax_obj = get_taxonomy( $tax );

				if ( $taxonomy_name === $tax_obj->query_var ) {
					$taxonomy = $tax;
				}
			}

			$term_rewrite = array();
			$terms = get_terms( $taxonomy ); // Removed deprecated second parameter

			$get_taxonomy = get_taxonomy( $taxonomy );
			$hierarchical = $get_taxonomy->rewrite['hierarchical'];

			$blog_prefix = '';

			foreach ( $terms as $term ) {
				$term_nicename = $term->slug;

				if ( 0 !== $term->parent && $hierarchical ) {
					$term_nicename = $this->get_term_parents2( $term->parent, $taxonomy, false, '/', true ) . $term_nicename;
				}

				$term_rewrite[ $blog_prefix . '(' . $term_nicename . ')/(?:feed/)?(feed|rdf|rss|rss2|atom)/?$' ] = 'index.php?' . $taxonomy_name . '=$matches[1]&feed=$matches[2]';
				$term_rewrite[ $blog_prefix . '(' . $term_nicename . ')/page/?([0-9]{1,})/?$' ] = 'index.php?' . $taxonomy_name . '=$matches[1]&paged=$matches[2]';
				$term_rewrite[ $blog_prefix . '(' . $term_nicename . ')/?$' ] = 'index.php?' . $taxonomy_name . '=$matches[1]';
			}
		}

		return $term_rewrite;
	}

	/**
	 * Inserts post type filter into the rewrite rules.
	 *
	 * @param array $rewrite_rules The existing rewrite rules.
	 * @return array Modified rewrite rules.
	 */
	public function insert_post_type_filter( $rewrite_rules ) {
		$args = array(
			'public'   => true,
			'_builtin' => false,
		);

		$taxonomies = [ 'product-category' ];
		$post_types = get_post_types( $args );

		foreach ( $taxonomies as $taxonomy ) {
			$terms = get_terms( $taxonomy ); // Removed deprecated second parameter
			foreach ( $terms as $term ) {
				$term_slug = $term->slug;
				foreach ( $post_types as $post_type ) {
					$post_type_object = get_post_type_object( $post_type );
					$post_type_object_slug = $post_type_object->rewrite['slug'] ?? '';

					if ( $post_type_object_slug === $term_slug ) {
						$rewrite_rules[ $post_type_object_slug . '/[^/]+/attachment/([^/]+)/?$' ] = 'index.php?attachment=$matches[1]';
						$rewrite_rules[ $post_type_object_slug . '/[^/]+/attachment/([^/]+)/trackback/?$' ] = 'index.php?attachment=$matches[1]&tb=1';
						$rewrite_rules[ $post_type_object_slug . '/[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' ] = 'index.php?attachment=$matches[1]&feed=$matches[2]';
						$rewrite_rules[ $post_type_object_slug . '/([^/]+)/trackback/?$' ] = 'index.php?' . $post_type . '=$matches[1]&tb=1';
						$rewrite_rules[ $post_type_object_slug . '/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' ] = 'index.php?' . $post_type . '=$matches[1]&feed=$matches[2]';
						$rewrite_rules[ $post_type_object_slug . '/([^/]+)/(feed|rdf|rss|rss2|atom)/?$' ] = 'index.php?' . $post_type . '=$matches[1]&feed=$matches[2]';
						$rewrite_rules[ $post_type_object_slug . '/([^/]+)/page/?([0-9]{1,})/?$' ] = 'index.php?' . $post_type . '=$matches[1]&paged=$matches[2]';
					}
				}
			}
		}

		return $rewrite_rules;
	}

	/**
	 * Removes the base filter for post type rewrites.
	 *
	 * @param array $rewrite_rules The existing rewrite rules.
	 * @return array Modified rewrite rules.
	 */
	public function remove_post_type_base_filter( $rewrite_rules ) {
		$args = array(
			'public'   => true,
			'_builtin' => false,
		);

		$taxonomies = [ 'product-category' ];
		$post_types = get_post_types( $args );

		if ( ! empty( $taxonomies ) ) {
			foreach ( $taxonomies as $taxonomy ) {
				$terms = get_terms( $taxonomy ); // Removed deprecated second parameter
				foreach ( $terms as $term ) {
					$term_slug = $term->slug;

					if ( ! empty( $post_types ) ) {
						foreach ( $post_types as $post_type ) {
							$post_type_object = get_post_type_object( $post_type );
							$post_type_object_slug = $post_type_object->rewrite['slug'] ?? '';

							if ( $post_type_object_slug === $term_slug ) {
								unset( $rewrite_rules[ $post_type_object_slug . '/?$' ] );
								unset( $rewrite_rules[ $post_type_object_slug . '/feed/(feed|rdf|rss|rss2|atom)/?$' ] );
								unset( $rewrite_rules[ $post_type_object_slug . '/(feed|rdf|rss|rss2|atom)/?$' ] );
								unset( $rewrite_rules[ $post_type_object_slug . '/page/([0-9]{1,})/?$' ] );
							}
						}
					}
				}
			}
		}

		return $rewrite_rules;
	}

	/**
	 * Retrieves the hierarchical structure of taxonomy terms.
	 *
	 * @param int    $id        The term ID.
	 * @param string $taxonomy  The taxonomy name.
	 * @param bool   $link      Whether to include term links.
	 * @param string $separator The separator between term names.
	 * @param bool   $nicename  Whether to use the term slug instead of the name.
	 * @param array  $deprecated Deprecated argument.
	 * @return string The term hierarchy as a string.
	 */
	public function get_term_parents2( $id, $taxonomy, $link = false, $separator = '/', $nicename = false, $deprecated = array() ) {
		$term = get_term( $id, $taxonomy );

		$chain = '';

		$parents = get_ancestors( $id, $taxonomy );
		array_unshift( $parents, $id );

		foreach ( array_reverse( $parents ) as $term_id ) {
			$term = get_term( $term_id, $taxonomy );

			$name = ( $nicename ) ? $term->slug : $term->name;
			if ( $link ) {
				$chain .= '<a href="' . get_term_link( $term->slug, $taxonomy ) . '" title="' . esc_attr( sprintf( __( 'View all posts in %s' ), $term->name ) ) . '">' . $name . '</a>' . $separator;
			} else {
				$chain .= $name . $separator;
			}
		}

		return $chain;
	}
}
