<?php
/**
 * Postomatic Plugin - Product Handler class.
 *
 * PHP Version 5.6
 *
 * @package  Postomatic
 * @category Plugin
 * @license  GPL-2.0-or-later https://www.gnu.org/licenses/gpl-2.0.html
 * @link     https://buildomatics.com/postomatics
 * @since    1.0.0
 */

namespace Postomatic\Api;

/**
 * Product Handler class.
 *
 * This class handles the product-related functionality.
 *
 * @category Plugin
 * @license  GPL-2.0-or-later https://www.gnu.org/licenses/gpl-2.0.html
 * @link     https://buildomatics.com/postomatics
 * @since    1.0.0
 */
class Product_Handler {

	/**
	 * Constructor.
	 */
	public function __construct() {
		add_action( 'wp_ajax_postomatic_get_products', array( $this, 'get_products' ) );
	}

	/**
	 * Get products.
	 *
	 * This method returns the products.
	 *
	 * @return void
	 */
	public function get_products() {
		// Check nonce for security.
		$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
		if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'postomatic_admin_nonce' ) ) {
			wp_send_json_error( 'Invalid nonce', 403 );

			return;
		}

		// Check if user has permission.
		if ( ! current_user_can( 'edit_posts' ) ) {
			wp_send_json_error( 'Permission denied', 403 );

			return;
		}

		// Get search query if provided.
		$search_query = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : '';

		// Get page number for pagination.
		$page = isset( $_POST['page'] ) ? intval( $_POST['page'] ) : 1;

		// Get products with search and pagination.
		$products = $this->get_products_data( $search_query, $page );

		wp_send_json_success( $products );
	}

	/**
	 * Get product categories.
	 *
	 * @param  \WC_Product $product The product object.
	 * @return array       An array of product categories.
	 */
	private function get_product_categories( $product ) {
		$categories = array();
		$terms      = get_the_terms( $product->get_id(), 'product_cat' );

		if ( $terms && ! is_wp_error( $terms ) ) {
			foreach ( $terms as $term ) {
				$categories[] = $term->name;
			}
		}

		return $categories;
	}

	/**
	 * Get product tags.
	 *
	 * @param  \WC_Product $product The product object.
	 * @return array       An array of product tags.
	 */
	private function get_product_tags( $product ) {
		$tags  = array();
		$terms = get_the_terms( $product->get_id(), 'product_tag' );

		if ( $terms && ! is_wp_error( $terms ) ) {
			foreach ( $terms as $term ) {
				$tags[] = $term->name;
			}
		}

		return $tags;
	}

	/**
	 * Get product attributes.
	 *
	 * @param  \WC_Product $product The product object.
	 * @return array       An array of product attributes.
	 */
	private function get_product_attributes( $product ) {
		$attributes         = array();
		$product_attributes = $product->get_attributes();

		if ( ! empty( $product_attributes ) ) {
			foreach ( $product_attributes as $attribute_name => $attribute ) {
				$name   = wc_attribute_label( $attribute_name );
				$values = array();

				if ( $attribute->is_taxonomy() ) {
					$attribute_taxonomy = $attribute->get_taxonomy_object();
					$attribute_values   = wc_get_product_terms( $product->get_id(), $attribute->get_name(), array( 'fields' => 'all' ) );

					foreach ( $attribute_values as $attribute_value ) {
						$values[] = $attribute_value->name;
					}
				} else {
					$values = $attribute->get_options();
				}

				$attributes[ $name ] = implode( ', ', $values );
			}
		}

		return $attributes;
	}

	/**
	 * Get products data.
	 *
	 * @param  string $search_query Optional search query to filter products.
	 * @param  int    $page         Optional page number for pagination.
	 * @return array  An array of products.
	 */
	private function get_products_data( $search_query = '', $page = 1 ) {
		$products       = array();
		$per_page       = 20; // Number of products per page.
		$total_products = 0;
		$total_pages    = 1;

		// Check if WooCommerce is active.
		if ( function_exists( 'wc_get_products' ) ) {
			// Prepare query args.
			$args = array(
				'status' => 'publish',
				'limit'  => $per_page,
				'page'   => $page,
			);

			// Add search query if provided.
			if ( ! empty( $search_query ) ) {
				$args['s'] = $search_query;
			}

			// Get WooCommerce products.
			$wc_products = wc_get_products( $args );

			// Get total count for pagination.
			$total_products = wc_get_products(
				array_merge(
					$args,
					array(
						'limit'  => -1,
						'return' => 'ids',
					)
				)
			);
			$total_products = count( $total_products );
			$total_pages    = ceil( $total_products / $per_page );

			// Format products for the response.
			foreach ( $wc_products as $product ) {
				$product_id = $product->get_id();

				// Get all product images.
				$image_ids  = array();
				$image_urls = array();

				// Main image.
				$main_image_id = $product->get_image_id();
				if ( $main_image_id ) {
					$image_ids[]          = $main_image_id;
					$main_image_url       = wp_get_attachment_url( $main_image_id );
					$main_image_large     = wp_get_attachment_image_src( $main_image_id, 'large' );
					$main_image_large_url = $main_image_large ? $main_image_large[0] : '';
				} else {
					$main_image_url       = '';
					$main_image_large_url = '';
				}

				// Gallery images.
				$gallery_image_ids  = $product->get_gallery_image_ids();
				$article_image_ids  = array(); // Array for images that can be used in articles (excluding main image).
				$article_image_urls = array(); // Array for image URLs that can be used in articles.

				if ( ! empty( $gallery_image_ids ) ) {
					$image_ids         = array_merge( $image_ids, $gallery_image_ids );
					$article_image_ids = $gallery_image_ids; // Store gallery images for article use.

					foreach ( $gallery_image_ids as $gallery_image_id ) {
						$gallery_image_url = wp_get_attachment_url( $gallery_image_id );
						if ( $gallery_image_url ) {
							$image_urls[]         = $gallery_image_url;
							$article_image_urls[] = $gallery_image_url; // Store URL for article use.

							// Get large size for content body.
							$large_image = wp_get_attachment_image_src( $gallery_image_id, 'large' );
							if ( $large_image ) {
								$image_urls[]         = $large_image[0];
								$article_image_urls[] = $large_image[0]; // Store large URL for article use.
							}
						}
					}
				}

				// Get related products.
				$related_products = array();
				$related_ids      = wc_get_related_products( $product_id, 5 );

				foreach ( $related_ids as $related_id ) {
					$related_product = wc_get_product( $related_id );
					if ( $related_product ) {
						$related_products[] = array(
							'id'    => $related_id,
							'name'  => $related_product->get_name(),
							'url'   => get_permalink( $related_id ),
							'image' => wp_get_attachment_url( $related_product->get_image_id() ),
						);
					}
				}

				// Create product meta with all details.
				$product_meta = array(
					'id'                 => $product_id,
					'name'               => $product->get_name(),
					'sku'                => $product->get_sku() ? $product->get_sku() : '',
					'price'              => $product->get_price(),
					'regular_price'      => $product->get_regular_price(),
					'sale_price'         => $product->get_sale_price(),
					'price_html'         => $product->get_price_html(),
					'on_sale'            => $product->is_on_sale(),
					'stock_status'       => $product->get_stock_status(),
					'stock_quantity'     => $product->get_stock_quantity(),
					'short_description'  => $product->get_short_description(),
					'description'        => $product->get_description(),
					'permalink'          => get_permalink( $product_id ),
					'categories'         => $this->get_product_categories( $product ),
					'tags'               => $this->get_product_tags( $product ),
					'attributes'         => $this->get_product_attributes( $product ),
					'dimensions'         => array(
						'length' => $product->get_length(),
						'width'  => $product->get_width(),
						'height' => $product->get_height(),
					),
					'weight'             => $product->get_weight(),
					'average_rating'     => $product->get_average_rating(),
					'review_count'       => $product->get_review_count(),
					'image_ids'          => $image_ids,
					'image_urls'         => array_unique( $image_urls ),
					'article_image_ids'  => $article_image_ids, // Images for article use (excluding main image).
					'article_image_urls' => array_unique( $article_image_urls ), // Image URLs for article use.
					'main_image'         => $main_image_url,
					'main_image_large'   => $main_image_large_url,
					'related_products'   => $related_products,
				);

				// Add product to products array with basic info and full meta.
				$products[] = array(
					'id'           => $product_id,
					'name'         => $product->get_name(),
					'price'        => $product->get_price_html(),
					'description'  => $product->get_short_description(),
					'url'          => get_permalink( $product_id ),
					'image'        => $main_image_url,
					'product-meta' => $product_meta,
				);
			}
		} else {
			// Fallback to checking for a 'product' post type.
			$args = array(
				'post_type'      => 'product',
				'post_status'    => 'publish',
				'posts_per_page' => $per_page,
				'paged'          => $page,
			);

			// Add search query if provided.
			if ( ! empty( $search_query ) ) {
				$args['s'] = $search_query;
			}

			$products_query = new \WP_Query( $args );

			// Get pagination info.
			$total_products = $products_query->found_posts;
			$total_pages    = ceil( $total_products / $per_page );

			if ( $products_query->have_posts() ) {
				while ( $products_query->have_posts() ) {
					$products_query->the_post();
					$product_id = get_the_ID();

					// Get product images.
					$main_image_url       = get_the_post_thumbnail_url( $product_id, 'full' );
					$main_image_large_url = get_the_post_thumbnail_url( $product_id, 'large' );

					// Get all attached images.
					$image_urls         = array();
					$image_ids          = array();
					$article_image_ids  = array(); // Array for images that can be used in articles (excluding main image).
					$article_image_urls = array(); // Array for image URLs that can be used in articles.

					// Get the main image ID.
					$main_image_id = get_post_thumbnail_id( $product_id );

					$attachments = get_posts(
						array(
							'post_type'      => 'attachment',
							'posts_per_page' => -1,
							'post_parent'    => $product_id,
						)
					);

					if ( $attachments ) {
						foreach ( $attachments as $attachment ) {
							$image_ids[] = $attachment->ID;
							$image_url   = wp_get_attachment_url( $attachment->ID );

							// If this is not the main image, add it to article images.
							if ( $attachment->ID !== $main_image_id && $image_url ) {
								$article_image_ids[]  = $attachment->ID;
								$article_image_urls[] = $image_url;

								// Get large size for content body.
								$large_image = wp_get_attachment_image_src( $attachment->ID, 'large' );
								if ( $large_image ) {
									$article_image_urls[] = $large_image[0];
								}
							}

							if ( $image_url ) {
								$image_urls[] = $image_url;

								// Get large size for content body.
								$large_image = wp_get_attachment_image_src( $attachment->ID, 'large' );
								if ( $large_image ) {
									$image_urls[] = $large_image[0];
								}
							}
						}
					}

					// Get related products (simple implementation for custom product type).
					$related_products = array();
					$related_args     = array(
						'post_type'      => 'product',
						'posts_per_page' => 6, // Get more posts than needed to account for filtering.
						'orderby'        => 'rand',
					);

					$related_query = new \WP_Query( $related_args );
					if ( $related_query->have_posts() ) {
						$count = 0;
						while ( $related_query->have_posts() && $count < 5 ) {
							$related_query->the_post();
							$related_id = get_the_ID();

							// Skip the current product.
							if ( $related_id === $product_id ) {
								continue;
							}

							$related_products[] = array(
								'id'    => $related_id,
								'name'  => get_the_title(),
								'url'   => get_permalink(),
								'image' => get_the_post_thumbnail_url( $related_id, 'thumbnail' ),
							);
							++$count;
						}
						wp_reset_postdata();
					}

					// Create product meta with all available details.
					$product_meta = array(
						'id'                 => $product_id,
						'name'               => get_the_title(),
						'sku'                => get_post_meta( $product_id, '_sku', true ) ? get_post_meta( $product_id, '_sku', true ) : '',
						'price'              => get_post_meta( $product_id, '_price', true ) ? get_post_meta( $product_id, '_price', true ) : '',
						'regular_price'      => get_post_meta( $product_id, '_regular_price', true ) ? get_post_meta( $product_id, '_regular_price', true ) : '',
						'sale_price'         => get_post_meta( $product_id, '_sale_price', true ) ? get_post_meta( $product_id, '_sale_price', true ) : '',
						'price_html'         => '',
						'on_sale'            => get_post_meta( $product_id, '_sale_price', true ) ? 'yes' : 'no',
						'stock_status'       => get_post_meta( $product_id, '_stock_status', true ) ? get_post_meta( $product_id, '_stock_status', true ) : '',
						'stock_quantity'     => get_post_meta( $product_id, '_stock', true ) ? get_post_meta( $product_id, '_stock', true ) : '',
						'short_description'  => get_the_excerpt(),
						'description'        => get_the_content(),
						'permalink'          => get_permalink(),
						'categories'         => wp_get_post_terms( $product_id, 'product_cat', array( 'fields' => 'names' ) ),
						'tags'               => wp_get_post_terms( $product_id, 'product_tag', array( 'fields' => 'names' ) ),
						'attributes'         => array(),
						'dimensions'         => array(
							'length' => get_post_meta( $product_id, '_length', true ) ? get_post_meta( $product_id, '_length', true ) : '',
							'width'  => get_post_meta( $product_id, '_width', true ) ? get_post_meta( $product_id, '_width', true ) : '',
							'height' => get_post_meta( $product_id, '_height', true ) ? get_post_meta( $product_id, '_height', true ) : '',
						),
						'weight'             => get_post_meta( $product_id, '_weight', true ) ? get_post_meta( $product_id, '_weight', true ) : '',
						'average_rating'     => get_post_meta( $product_id, '_wc_average_rating', true ) ? get_post_meta( $product_id, '_wc_average_rating', true ) : '',
						'review_count'       => get_post_meta( $product_id, '_wc_review_count', true ) ? get_post_meta( $product_id, '_wc_review_count', true ) : '',
						'image_ids'          => $image_ids,
						'image_urls'         => array_unique( $image_urls ),
						'article_image_ids'  => $article_image_ids, // Images for article use (excluding main image).
						'article_image_urls' => array_unique( $article_image_urls ), // Image URLs for article use.
						'main_image'         => $main_image_url ? $main_image_url : '',
						'main_image_large'   => $main_image_large_url ? $main_image_large_url : '',
						'related_products'   => $related_products,
					);

					// Add product to products array with basic info and full meta.
					$products[] = array(
						'id'           => $product_id,
						'name'         => get_the_title(),
						'description'  => get_the_excerpt(),
						'url'          => get_permalink(),
						'image'        => $main_image_url ? $main_image_url : '',
						'product-meta' => $product_meta,
					);
				}
				wp_reset_postdata();
			}
		}

		// Return products with pagination info.
		return array(
			'products'   => $products,
			'pagination' => array(
				'total'        => $total_products,
				'per_page'     => $per_page,
				'current_page' => $page,
				'total_pages'  => $total_pages,
			),
		);
	}
}
