<?php
/**
 * Value handler for WPML trid field.
 *
 * @package Ealab\Deployer
 */

namespace EaLab\WP_Deployer\vendor\Ealab\Deployer\Tracking\ItemValueHandler\Compatibility\sitepress_multilingual_cms;

use EaLab\WP_Deployer\vendor\Dakwamine\Component\RootDependencyDefinition;
use EaLab\WP_Deployer\vendor\Ealab\Deployer\Exception\WpDeployException;
use EaLab\WP_Deployer\vendor\Ealab\Deployer\Tracking\ItemValueHandler\ItemValueHandlerBase;
use EaLab\WP_Deployer\vendor\Ealab\Deployer\Tracking\SqlChangesTracker;
use EaLab\WP_Deployer\vendor\Ealab\Deployer\Tracking\TrackingManager;
use EaLab\WP_Deployer\vendor\Ealab\Deployer\Utility\Database;
use EaLab\WP_Deployer\vendor\Ealab\Deployer\Utility\Plugin;

/**
 * Value handler for WPML trid field.
 */
class WpmlTridItemValueHandler extends ItemValueHandlerBase {
	/**
	 * The tracking manager.
	 *
	 * @var \EaLab\WP_Deployer\vendor\Ealab\Deployer\Tracking\TrackingManager|null
	 */
	private ?TrackingManager $tracking_manager = null;

	/**
	 * Generates a new trid.
	 *
	 * @return int The generated trid.
	 */
	protected function generateTrid(): int {
		$wpdb = Database::getDatabaseHandle();

		// Taken from class-wpml-set-language.php of WPML.
		return 1 + (int) $wpdb->get_var( "SELECT MAX(trid) FROM {$wpdb->prefix}icl_translations;" . SqlChangesTracker::IGNORE_TRACKING );
	}

	/**
	 * {@inheritDoc}
	 */
	public function getDependencyDefinitions(): array {
		$definitions = parent::getDependencyDefinitions();

		$definitions[] = new RootDependencyDefinition( TrackingManager::class, $this->tracking_manager );

		return $definitions;
	}

	/**
	 * {@inheritDoc}
	 */
	public static function getHandlerBaseId(): string {
		return 'wpml_trid';
	}

	/**
	 * {@inheritDoc}
	 */
	public static function getLabel(): string {
		return _dpgettext( 'deployer-core', 'processor label', 'WPML trid' );
	}

	/**
	 * Gets the trid (translation group) from element_type and element_id.
	 *
	 * @param string $element_type The element type.
	 * @param int    $element_id The element ID.
	 *
	 * @return int|null The trid if found, null otherwise.
	 */
	protected function getTridFromElementTypeAndId( string $element_type, int $element_id ): ?int {
		global $sitepress;

		return $sitepress->get_element_trid( $element_id, $element_type );
	}

	/**
	 * {@inheritDoc}
	 */
	public function getUnprocessedValue( int $operation, ?callable $progress_callback = null ) {
		if ( ! Plugin::isPluginActive( 'sitepress-multilingual-cms/sitepress.php' ) ) {
			// The plugin is not enabled, do not process anything.
			return $this->value;
		}

		$holder_item_fields = $this->holder_item->getRawDataFields();

		switch ( $operation ) {
			case ItemValueHandlerBase::OPERATION__EXPORT:
				// Export as a placeholder. We don't need to export anything.
				return static::getProcessorPlaceholder();

			case ItemValueHandlerBase::OPERATION__IMPORT__FINALIZE:
				// Get the current trid (translation group) of this item, or generate a new one.
				$pointed_element_uuid = $holder_item_fields['element_id'];

				$tracker = $this->tracking_manager->getItemTrackerByItemFullUuid( $pointed_element_uuid );

				$pointed_element_local_id = $tracker->getLocalIdFromUuid( $pointed_element_uuid );

				return $this->getTridFromElementTypeAndId( $holder_item_fields['element_type'], $pointed_element_local_id ) ?? $this->generateTrid();

			case ItemValueHandlerBase::OPERATION__IMPORT__PRESAVE:
				// Do not save a value yet, because we need the local ID
				// of the referenced item pointed by the
				// element_type+element_id fields
				// that WpmlElementIdItemValueHandler is supposed to import
				// alongside this handler.
				return 0;

			default:
				throw new WpDeployException( 'Invalid operation in WpmlTridItemValueHandler::getUnprocessedValue() : ' . $operation . '.' );
		}
	}
}
