<?php
/**
 * Money helpers — integer minor units only.
 *
 * @package WPDudeProducts
 */

declare(strict_types=1);

namespace WPDude\Products\Support;

/**
 * Currency / amount utilities.
 */
final class Money {

	/**
	 * Zero-decimal currencies (amount already in minor unit = major unit).
	 *
	 * @var list<string>
	 */
	private const ZERO_DECIMAL = array(
		'bif', 'clp', 'djf', 'gnf', 'jpy', 'kmf', 'krw', 'mga', 'pyg', 'rwf', 'ugx', 'vnd', 'vuv', 'xaf', 'xof', 'xpf',
	);

	/**
	 * Whether the currency uses zero decimal places.
	 */
	public static function is_zero_decimal( string $currency ): bool {
		return in_array( strtolower( $currency ), self::ZERO_DECIMAL, true );
	}

	/**
	 * Convert major-unit decimal string to integer minor units.
	 */
	public static function to_minor( string $amount, string $currency ): int {
		$currency = strtolower( $currency );
		$amount   = trim( str_replace( array( ',', ' ' ), array( '', '' ), $amount ) );

		if ( ! is_numeric( $amount ) ) {
			return 0;
		}

		if ( self::is_zero_decimal( $currency ) ) {
			return (int) round( (float) $amount );
		}

		return (int) round( (float) $amount * 100 );
	}

	/**
	 * Format minor units for display.
	 */
	public static function format( int $minor, string $currency ): string {
		$currency = strtoupper( $currency );
		if ( self::is_zero_decimal( $currency ) ) {
			return $currency . ' ' . (string) $minor;
		}

		return $currency . ' ' . number_format( $minor / 100, 2, '.', '' );
	}

	/**
	 * Validate positive amount in minor units.
	 */
	public static function is_valid_positive( int $minor ): bool {
		return $minor > 0;
	}
}
