<?php
/**
 * WooCommerce helper class.
 *
 * @package Altify_AI
 */

if (!defined('ABSPATH')) {
	exit;
}

/**
 * Handles WooCommerce detection and image gathering.
 */
class Altify_AI_WooCommerce {
	/**
	 * Logger instance.
	 *
	 * @var Altify_AI_Logger
	 */
	private $logger;

	/**
	 * Constructor.
	 *
	 * @param Altify_AI_Logger $logger Logger.
	 */
	public function __construct($logger) {
		$this->logger = $logger;
	}

	/**
	 * Check if WooCommerce is active.
	 *
	 * @return bool
	 */
	public function is_active() {
		return class_exists('WooCommerce');
	}

	/**
	 * Check if WooCommerce feature is enabled in settings.
	 *
	 * @return bool
	 */
	public function is_enabled() {
		$enabled = altify_ai_bool(altify_ai_get_setting('enable_woo_support', 1));
		return $this->is_active() && (bool) $enabled;
	}

	/**
	 * Get context from first matching product that uses this image.
	 *
	 * @param int $attachment_id Attachment ID.
	 *
	 * @return array
	 */
	public function get_product_context_for_attachment($attachment_id) {
		$attachment_id = absint($attachment_id);
		if (!$attachment_id || !$this->is_active()) {
			return array();
		}

		$product_id = $this->find_product_by_featured_image($attachment_id);
		if (!$product_id) {
			$product_id = $this->find_product_by_gallery_image($attachment_id);
		}

		if (!$product_id) {
			return array();
		}

		$context = $this->get_product_context($product_id);
		if (empty($context['product_name'])) {
			return array();
		}

		return $context;
	}

	/**
	 * Get paged product IDs.
	 *
	 * @param int    $offset          Offset.
	 * @param int    $limit           Limit.
	 * @param string $category_slug   Optional product category slug.
	 * @param string $date_from       Optional date from.
	 * @param string $date_to         Optional date to.
	 *
	 * @return array
	 */
	public function get_product_batch($offset, $limit, $category_slug = '', $date_from = '', $date_to = '') {
		$offset        = max(0, absint($offset));
		$limit         = max(1, absint($limit));
		$category_slug = sanitize_title((string) $category_slug);

		$args = array(
			'post_type'              => 'product',
			'post_status'            => array('publish'),
			'posts_per_page'         => $limit,
			'offset'                 => $offset,
			'fields'                 => 'ids',
			'orderby'                => 'ID',
			'order'                  => 'ASC',
			'ignore_sticky_posts'    => true,
			'update_post_meta_cache' => false,
			'update_post_term_cache' => false,
			'no_found_rows'          => false,
		);

		if ('' !== $category_slug) {
			// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- Optional admin-side product category filter for WooCommerce bulk generation.
			$args['tax_query'] = array(
				array(
					'taxonomy' => 'product_cat',
					'field'    => 'slug',
					'terms'    => array($category_slug),
				),
			);
		}

		$date_query = altify_ai_get_date_query($date_from, $date_to);
		if (!empty($date_query)) {
			$args['date_query'] = $date_query;
		}

		$query = new WP_Query($args);
		$ids   = !empty($query->posts) ? array_map('absint', $query->posts) : array();
		$total = isset($query->found_posts) ? absint($query->found_posts) : 0;

		$next_offset = $offset + count($ids);
		$done        = (0 === count($ids)) || ($next_offset >= $total);

		wp_reset_postdata();

		return array(
			'product_ids'  => $ids,
			'total'        => $total,
			'next_offset'  => $next_offset,
			'done'         => $done,
			'current_page' => $offset,
		);
	}

	/**
	 * Collect unique product images for provided product IDs.
	 *
	 * @param array  $product_ids Product IDs.
	 * @param string $mode        missing|all.
	 *
	 * @return array
	 */
	public function get_images_for_products($product_ids, $mode = 'missing') {
		$product_ids = is_array($product_ids) ? array_map('absint', $product_ids) : array();
		$mode        = ('all' === $mode) ? 'all' : 'missing';

		if (empty($product_ids)) {
			return array();
		}

		$items = array();
		$seen  = array();

		foreach ($product_ids as $product_id) {
			if (!$product_id) {
				continue;
			}

			$context = $this->get_product_context($product_id);

			$image_ids = array();
			$thumb_id  = absint(get_post_thumbnail_id($product_id));
			if ($thumb_id) {
				$image_ids[] = $thumb_id;
			}

			$gallery_csv = get_post_meta($product_id, '_product_image_gallery', true);
			if (is_string($gallery_csv) && '' !== trim($gallery_csv)) {
				$gallery_ids = array_map('absint', explode(',', $gallery_csv));
				$gallery_ids = array_filter($gallery_ids);
				$image_ids   = array_merge($image_ids, $gallery_ids);
			}

			$image_ids = array_values(array_unique(array_map('absint', $image_ids)));

			foreach ($image_ids as $attachment_id) {
				if (!$attachment_id || isset($seen[$attachment_id])) {
					continue;
				}

				if (!altify_ai_is_image_attachment($attachment_id)) {
					continue;
				}

				if ('missing' === $mode) {
					$existing_alt = trim((string) get_post_meta($attachment_id, '_wp_attachment_image_alt', true));
					if ('' !== $existing_alt) {
						continue;
					}
				}

				$items[] = array(
					'attachment_id'      => $attachment_id,
					'product_id'         => $product_id,
					'product_name'       => !empty($context['product_name']) ? $context['product_name'] : '',
					'product_categories' => !empty($context['product_categories']) ? $context['product_categories'] : '',
				);

				$seen[$attachment_id] = true;
			}
		}

		return $items;
	}

	/**
	 * Get product categories for dropdown.
	 *
	 * @return array
	 */
	public function get_product_categories() {
		if (!$this->is_active()) {
			return array();
		}

		$terms = get_terms(
			array(
				'taxonomy'   => 'product_cat',
				'hide_empty' => false,
			)
		);

		if (is_wp_error($terms) || !is_array($terms)) {
			return array();
		}

		return $terms;
	}

	/**
	 * Find product by featured image.
	 *
	 * @param int $attachment_id Attachment ID.
	 *
	 * @return int
	 */
	private function find_product_by_featured_image($attachment_id) {
		$product_ids = get_posts(
			array(
				'post_type'              => 'product',
				'post_status'            => array('publish'),
				'posts_per_page'         => 1,
					'fields'                 => 'ids',
					'ignore_sticky_posts'    => true,
					'update_post_meta_cache' => false,
					'update_post_term_cache' => false,
					// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Needed to locate products by featured image attachment ID.
					'meta_key'               => '_thumbnail_id',
					// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- Needed to locate products by featured image attachment ID.
					'meta_value'             => absint($attachment_id),
				)
			);

		return !empty($product_ids[0]) ? absint($product_ids[0]) : 0;
	}

	/**
	 * Find product by image gallery.
	 *
	 * @param int $attachment_id Attachment ID.
	 *
	 * @return int
	 */
	private function find_product_by_gallery_image($attachment_id) {
		$attachment_id = absint($attachment_id);

		$product_ids = get_posts(
			array(
				'post_type'              => 'product',
				'post_status'            => array('publish'),
				'posts_per_page'         => 25,
					'fields'                 => 'ids',
					'ignore_sticky_posts'    => true,
					'update_post_meta_cache' => false,
					'update_post_term_cache' => false,
					// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Needed to locate products by gallery attachment IDs.
					'meta_key'               => '_product_image_gallery',
					// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- Needed to locate products by gallery attachment IDs.
					'meta_value'             => (string) $attachment_id,
					'meta_compare'           => 'LIKE',
				)
		);

		if (empty($product_ids)) {
			return 0;
		}

		foreach ($product_ids as $product_id) {
			$gallery_csv = (string) get_post_meta($product_id, '_product_image_gallery', true);
			$gallery_ids = array_map('absint', explode(',', $gallery_csv));
			$gallery_ids = array_filter($gallery_ids);
			if (in_array($attachment_id, $gallery_ids, true)) {
				return absint($product_id);
			}
		}

		return 0;
	}

	/**
	 * Build product context.
	 *
	 * @param int $product_id Product ID.
	 *
	 * @return array
	 */
	private function get_product_context($product_id) {
		$product_id = absint($product_id);
		if (!$product_id) {
			return array();
		}

		$product_name = sanitize_text_field((string) get_the_title($product_id));
		$categories   = array();

		$terms = get_the_terms($product_id, 'product_cat');
		if (is_array($terms)) {
			foreach ($terms as $term) {
				if (!empty($term->name)) {
					$categories[] = sanitize_text_field((string) $term->name);
				}
			}
		}

		return array(
			'product_name'       => $product_name,
			'product_categories' => array_values(array_unique(array_filter($categories))),
		);
	}
}
