<?php
/**
 * Resolves Grundpreis from the shared Germanized/German Market meta schema.
 *
 * @package PhoenixWP\PriceLabels
 */

declare(strict_types=1);

namespace PhoenixWP\PriceLabels\Compliance\Providers;

use PhoenixWP\PriceLabels\Compliance\Unit_Price_Provider_Interface;
use PhoenixWP\PriceLabels\Compliance\Unit_Price_Text;
use WC_Product;

defined( 'ABSPATH' ) || exit;

/**
 * Reads _unit, _unit_base, _unit_product, _unit_price without plugin classes.
 */
final class Pangv_Meta_Provider implements Unit_Price_Provider_Interface {

	public function get_id(): string {
		return 'pangv_meta';
	}

	public function resolve( WC_Product $product ): ?string {
		$unit = $this->resolve_unit_label( $product );

		if ( '' === $unit ) {
			return null;
		}

		$unit_price = $this->read_float_meta( $product, '_unit_price' );

		if ( $unit_price <= 0 && $product->is_on_sale() ) {
			$unit_price = $this->read_float_meta( $product, '_unit_price_sale' );
		}

		if ( $unit_price <= 0 ) {
			$unit_price = $this->read_float_meta( $product, '_unit_price_regular' );
		}

		$base           = $this->read_float_meta( $product, '_unit_base' );
		$product_amount = $this->read_float_meta( $product, '_unit_product' );

		if ( $unit_price <= 0 && $product_amount > 0 ) {
			$display = (float) wc_get_price_to_display( $product );
			$base    = $base > 0 ? $base : 1.0;

			if ( $display > 0 ) {
				$unit_price = ( $display / $product_amount ) * $base;
			}
		}

		if ( $unit_price <= 0 ) {
			return null;
		}

		return Unit_Price_Text::format_per_unit( $unit_price, $base > 0 ? $base : 1.0, $unit );
	}

	private function resolve_unit_label( WC_Product $product ): string {
		$unit = trim( (string) $product->get_meta( '_unit' ) );

		if ( '' === $unit ) {
			return '';
		}

		if ( is_numeric( $unit ) && taxonomy_exists( 'product_unit' ) ) {
			$term = get_term( (int) $unit, 'product_unit' );
			if ( $term instanceof \WP_Term && ! is_wp_error( $term ) ) {
				return trim( $term->name );
			}
		}

		if ( taxonomy_exists( 'product_unit' ) ) {
			$terms = wp_get_post_terms( $product->get_id(), 'product_unit', array( 'fields' => 'names' ) );
			if ( is_array( $terms ) && isset( $terms[0] ) && is_string( $terms[0] ) ) {
				return trim( $terms[0] );
			}
		}

		return $unit;
	}

	private function read_float_meta( WC_Product $product, string $key ): float {
		$value = $product->get_meta( $key );

		return is_numeric( $value ) ? (float) $value : 0.0;
	}
}
