<?php

namespace Brandy\Niches\Import;

/**
 * Removes previously imported demo content (posts, products, terms, menus) for
 * a niche.
 */
class SampleDataCleaner {

	/**
	 * Selected niche import data.
	 *
	 * @var array
	 */
	private $selected_niche;

	public function __construct( $selected_niche ) {
		$this->selected_niche = $selected_niche;
	}

	public function clean() {

		/**
		 * Cleaning posts
		 */
		$demo_posts_query = new \WP_Query(
			array(
				'posts_per_page' => -1,
				'fields'         => 'ids',
				'meta_query' => [
					'relation' => 'OR',
					[
						'key'     => '_brandy_demo',
						'value'   => 'yes',
						'compare' => '=',
					],
				],
			)
		);

		$post_demo_cats = [];
		$post_demo_tags = [];
		if ( $demo_posts_query->have_posts() ) {
			foreach ( $demo_posts_query->get_posts() as $post_id ) {
				$tag_ids = wp_get_post_terms( $post_id, 'post_tag', [
					'fields' => 'ids',
				] );
				$category_ids = wp_get_post_terms( $post_id, 'category', [
					'fields' => 'ids',
				] );
				$post_demo_cats = array_merge( $post_demo_cats, $category_ids );
				$post_demo_tags = array_merge( $post_demo_tags, $tag_ids );
				wp_delete_post( $post_id, true );
			}
		}

		// Legacy demo terms from older imports were slugged with a 'brandy-' prefix.
		$post_demo_tags = array_merge( $post_demo_tags, $this->get_legacy_brandy_term_ids( 'post_tag' ) );
		$post_demo_cats = array_merge( $post_demo_cats, $this->get_legacy_brandy_term_ids( 'category' ) );

		$demo_product_query = new \WP_Query( array(
			'posts_per_page' => -1,
			'meta_query' => [
				'relation' => 'OR',
				[
					'key'     => '_brandy_demo',
					'value'   => 'yes',
					'compare' => '=',
				],
			],
			'post_type'      => array( 'product', 'product_variation' ),
			'orderby'        => 'title,',
			)
		);
		$product_demo_cats = [];
		$product_demo_tags = [];

		if ( $demo_product_query->have_posts() ) {
			foreach ( $demo_product_query->get_posts() as $product_id ) {
				$demo_product = \wc_get_product( $product_id );

				if ( ! $demo_product ) {
					continue;
				}

				$product_demo_cats = array_merge( $product_demo_cats, $demo_product->get_category_ids() );
				$product_demo_tags = array_merge( $product_demo_tags, $demo_product->get_tag_ids() );
				$this->delete_product_with_variations( $demo_product );
			}
		}

		// Legacy 'brandy-' product tags also flag demo products that must be removed.
		$product_demo_legacy_tags = get_terms(
			array(
				'taxonomy' => 'product_tag',
				'search'   => 'brandy-',
				'fields'   => 'ids',
			)
		);

		if ( !is_wp_error( $product_demo_legacy_tags ) && is_array( $product_demo_legacy_tags ) ) {
			$product_demo_tags = array_merge( $product_demo_tags, $product_demo_legacy_tags );

			$demo_product_legacy_query = new \WP_Query( array(
				'posts_per_page' => -1,
				'tax_query'      => array(
				'relation' => 'AND',
					array(
						'taxonomy' => 'product_tag',
						'field'    => 'id',
						'terms'    => $product_demo_legacy_tags,
					),
				),
				'post_type'      => array( 'product', 'product_variation' ),
				'orderby'        => 'title,',
				)
			);

			if ( $demo_product_legacy_query->have_posts() ) {
				$this->delete_demo_products_by_ids( $demo_product_legacy_query->get_posts() );
			}

		}

		$product_demo_cats = array_merge( $product_demo_cats, $this->get_legacy_brandy_term_ids( 'product_cat' ) );

		$this->delete_unused_terms( $product_demo_cats, 'product_cat' );
		$this->delete_unused_terms( $product_demo_tags, 'product_tag' );
		$this->delete_unused_terms( $post_demo_cats, 'category' );
		$this->delete_unused_terms( $post_demo_tags, 'post_tag' );

		/** Clean menus */
		if ( empty( $this->selected_niche ) ) {
			return;
		}
		$menus = $this->selected_niche['sample_menus'];
		foreach ( $menus as $menu ) {
			$menu_exists = wp_get_nav_menu_object( $menu['name'] );
			if ( $menu_exists ) {
				wp_delete_nav_menu( $menu_exists );
			}
		}

		do_action( 'brandy_after_clean_sample_data', $this->selected_niche['id'] );

	}

	/**
	 * Return IDs of legacy demo terms (slug prefixed with 'brandy-') in a taxonomy.
	 * Returns an empty array on error or unexpected result.
	 *
	 * @param string $taxonomy Taxonomy slug.
	 * @return array
	 */
	private function get_legacy_brandy_term_ids( $taxonomy ) {
		$term_ids = get_terms(
			array(
				'taxonomy' => $taxonomy,
				'search'   => 'brandy-',
				'fields'   => 'ids',
			)
		);

		return ( ! is_wp_error( $term_ids ) && is_array( $term_ids ) ) ? $term_ids : array();
	}

	/**
	 * Delete each term that has no remaining attached content (count is empty).
	 *
	 * @param array  $term_ids Term IDs to consider.
	 * @param string $taxonomy Taxonomy slug.
	 * @return void
	 */
	private function delete_unused_terms( $term_ids, $taxonomy ) {
		if ( ! is_array( $term_ids ) ) {
			return;
		}

		foreach ( array_unique( $term_ids ) as $term_id ) {
			$demo_term = get_term_by( 'id', $term_id, $taxonomy );
			if ( empty( $demo_term->count ) ) {
				wp_delete_term( $term_id, $taxonomy );
			}
		}
	}

	/**
	 * Force-delete a product and, for variable products, all of its variations.
	 *
	 * @param \WC_Product|false $demo_product Product object from wc_get_product().
	 * @return void
	 */
	private function delete_product_with_variations( $demo_product ) {
		if ( ! $demo_product ) {
			return;
		}

		// Delete all variations if it's a variable product
		if ( $demo_product->is_type( 'variable' ) ) {
			$variations = $demo_product->get_children();
			foreach ( $variations as $variation_id ) {
				$variation = \wc_get_product( $variation_id );
				if ( $variation ) {
					$variation->delete( true );
				}
			}
		}

		$demo_product->delete( true );
	}

	/**
	 * Resolve and force-delete demo products (with variations) from a list of
	 * product IDs or post objects.
	 *
	 * @param array $product_ids Product IDs or post objects.
	 * @return void
	 */
	private function delete_demo_products_by_ids( $product_ids ) {
		foreach ( $product_ids as $product_id ) {
			$demo_product = \wc_get_product( $product_id );
			$this->delete_product_with_variations( $demo_product );
		}
	}
}
