<?php
/**
 * Registers a cron component to get VAT rates.
 *
 * @package     EDD\Pro\Cron\Components
 * @copyright   Copyright (c) 2025, Sandhills Development, LLC
 * @license     https://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       3.5.0
 */

namespace EDD\Pro\Cron\Components;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore

use EDD\Cron\Components\Component;
use EDD\Utils\Transient;
use EDD\Pro\Taxes\VAT\StandardRate;

/**
 * VAT Rates.
 *
 * @since 3.5.0
 */
class VATRates extends Component {

	/**
	 * The component ID.
	 *
	 * @var string
	 */
	protected static $id = 'vat_rates';

	/**
	 * Register the event to run.
	 *
	 * @since 3.5.0
	 */
	public static function get_subscribed_events(): array {
		$events = array(
			'edd_get_vat_rates' => 'get_rates',
		);

		if ( edd_get_option( 'vat_auto_rates', false ) ) {
			$events['edd_pro_weekly_scheduled_events'] = 'get_rates';
		}

		return $events;
	}

	/**
	 * Get and update the VAT rates.
	 *
	 * @since 3.5.0
	 */
	public function get_rates() {
		if ( ! edd_get_option( 'vat_auto_rates', false ) ) {
			return;
		}

		// Delete the transient to ensure we get the latest rates.
		$transient = new Transient( 'edd_vat_rates' );
		$transient->delete();

		$eu_countries = \EDD\Utils\Countries::get_eu_countries();
		$rates        = array();
		foreach ( $eu_countries as $country ) {
			$existing_rate = $this->get_existing_rate( $country );
			if ( ! empty( $existing_rate ) && 'manual' === $existing_rate->source ) {
				edd_debug_log( 'Tax rate for ' . $country . ' is manually set' );
				continue;
			}

			$standard_getter = new StandardRate( $country );
			$standard_rate   = $standard_getter->get();
			if ( empty( $standard_rate ) ) {
				continue;
			}

			$rates[ $country ] = $standard_rate;
			if ( $existing_rate && round( (float) $existing_rate->amount, 4 ) === round( (float) $standard_rate, 4 ) ) {
				edd_debug_log( 'Tax rate for ' . $country . ' is already up to date: ' . $standard_rate );
				continue;
			}

			if ( $existing_rate ) {
				edd_update_tax_rate(
					$existing_rate->id,
					array(
						'status' => 'inactive',
					)
				);
			}

			$tax_rate_id = edd_add_tax_rate(
				array(
					'country' => $country,
					'scope'   => 'country',
					'amount'  => $standard_rate,
					'status'  => 'active',
					'source'  => 'api',
				)
			);
			edd_debug_log( 'Added tax rate for ' . $country . ': ' . $standard_rate );
		}
	}

	/**
	 * Get the existing tax rate for a country.
	 *
	 * @since 3.5.0
	 * @param string $country The country code.
	 * @return false|object
	 */
	private function get_existing_rate( $country ) {
		$tax_rates = edd_get_tax_rates(
			array(
				'status'  => 'active',
				'country' => $country,
				'scope'   => 'country',
			),
			OBJECT
		);
		if ( empty( $tax_rates ) ) {
			return false;
		}

		$tax_rate = reset( $tax_rates );
		edd_debug_log( 'Tax rate already exists for ' . $country . ': ' . $tax_rate->amount );

		return $tax_rate;
	}
}
