<?php
/**
 * Resolves product brand names from WooCommerce core and common fallbacks.
 *
 * @package PhoenixWP\PriceLabels
 */

declare(strict_types=1);

namespace PhoenixWP\PriceLabels\Labels;

use WC_Product;

defined( 'ABSPATH' ) || exit;

/**
 * Reads brand labels from native WooCommerce Brands taxonomy.
 */
final class Product_Brand_Resolver {

	/**
	 * Returns the primary brand name for a product or variation.
	 *
	 * @param WC_Product $product Product or variation.
	 */
	public static function resolve( WC_Product $product ): string {
		$product_id = $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id();

		if ( $product_id <= 0 ) {
			return '';
		}

		if ( taxonomy_exists( 'product_brand' ) ) {
			$brand = self::resolve_from_taxonomy( $product_id, 'product_brand' );

			if ( '' !== $brand ) {
				return self::filter_brand( $brand, $product );
			}
		}

		$taxonomies = array();

		/**
		 * Filters taxonomies checked for product brand names.
		 *
		 * @param string[]   $taxonomies Taxonomy slugs in priority order.
		 * @param WC_Product $product    Source product.
		 */
		$taxonomies = (array) apply_filters( 'phoenix_wp_price_labels_brand_taxonomies', $taxonomies, $product );

		foreach ( $taxonomies as $taxonomy ) {
			$taxonomy = sanitize_key( (string) $taxonomy );

			if ( '' === $taxonomy || ! taxonomy_exists( $taxonomy ) ) {
				continue;
			}

			$brand = self::resolve_from_taxonomy( $product_id, $taxonomy );

			if ( '' !== $brand ) {
				return self::filter_brand( $brand, $product );
			}
		}

		$brand = self::resolve_from_attribute( $product );

		return self::filter_brand( $brand, $product );
	}

	/**
	 * @param string     $brand   Plain brand text.
	 * @param WC_Product $product Source product.
	 */
	private static function filter_brand( string $brand, WC_Product $product ): string {
		$brand = trim( wp_strip_all_tags( $brand ) );

		/**
		 * Filters resolved brand text for price labels.
		 *
		 * @param string     $brand   Brand name.
		 * @param WC_Product $product Source product.
		 */
		return (string) apply_filters( 'phoenix_wp_price_labels_brand', $brand, $product );
	}

	private static function resolve_from_taxonomy( int $product_id, string $taxonomy ): string {
		$terms = get_the_terms( $product_id, $taxonomy );

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

		$names = array();

		foreach ( $terms as $term ) {
			if ( $term instanceof \WP_Term && '' !== $term->name ) {
				$names[] = $term->name;
			}
		}

		return implode( ', ', $names );
	}

	private static function resolve_from_attribute( WC_Product $product ): string {
		$attributes = array( 'pa_brand', 'brand' );

		/**
		 * Filters product attribute slugs checked for brand fallback.
		 *
		 * @param string[]   $attributes Attribute slugs.
		 * @param WC_Product $product    Source product.
		 */
		$attributes = (array) apply_filters( 'phoenix_wp_price_labels_brand_attributes', $attributes, $product );

		foreach ( $attributes as $attribute ) {
			$value = $product->get_attribute( (string) $attribute );
			$value = trim( wp_strip_all_tags( $value ) );

			if ( '' !== $value ) {
				return $value;
			}
		}

		if ( ! $product->is_type( 'variation' ) ) {
			return '';
		}

		$parent = wc_get_product( $product->get_parent_id() );

		if ( ! $parent instanceof WC_Product ) {
			return '';
		}

		foreach ( $attributes as $attribute ) {
			$value = $parent->get_attribute( (string) $attribute );
			$value = trim( wp_strip_all_tags( $value ) );

			if ( '' !== $value ) {
				return $value;
			}
		}

		return '';
	}
}
