<?php
declare(strict_types=1);

/**
 * Attachment category Select2 UI for the WordPress Media Library (Divi 5).
 *
 * @package DiviSupreme
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Media Library attachment category picker — mirrors Divi 4 Select2 behaviour.
 */
class DSM_Attachment_Category_Fields {

	/**
	 * Taxonomy slug shared with Filterable Gallery and REST.
	 */
	private const TAXONOMY = 'dsm-attachment-category';

	/**
	 * Main plugin bootstrap file (for plugins_url).
	 */
	private string $plugin_file;

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->plugin_file = defined( 'DSM_DIR_PATH' )
			? DSM_DIR_PATH . 'supreme-modules-pro-for-divi.php'
			: dirname( __DIR__, 3 ) . '/supreme-modules-pro-for-divi.php';

		add_action( 'wp_enqueue_media', array( $this, 'enqueue_assets' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'maybe_enqueue_admin_assets' ) );
		add_filter( 'attachment_fields_to_edit', array( $this, 'render_custom_selectbox' ), 99, 2 );
		add_filter( 'attachment_fields_to_save', array( $this, 'handle_store' ), 10, 2 );
	}

	/**
	 * Enqueue Select2 assets on Media Library admin screens.
	 *
	 * WordPress `iframe_header()` (e.g. Event Tickets Move Tickets/RSVP)
	 * fires `admin_enqueue_scripts` with a null hook suffix.
	 *
	 * @param string|null $hook_suffix Current admin page hook suffix.
	 * @return void
	 */
	public function maybe_enqueue_admin_assets( ?string $hook_suffix = null ): void {
		if ( null === $hook_suffix || '' === $hook_suffix ) {
			return;
		}

		if ( ! in_array( $hook_suffix, array( 'upload.php', 'post.php', 'post-new.php' ), true ) ) {
			return;
		}

		$this->enqueue_assets();
	}

	/**
	 * Enqueue Select2 library and initializer for attachment compat fields.
	 *
	 * @return void
	 */
	public function enqueue_assets(): void {
		if ( ! taxonomy_exists( self::TAXONOMY ) ) {
			return;
		}

		$version = defined( 'DSM_PRO_VERSION' ) ? DSM_PRO_VERSION : '1.0.0';

		wp_enqueue_style(
			'dsm-select-two',
			plugins_url( 'divi-4/public/css/select2.css', $this->plugin_file ),
			array(),
			$version
		);

		wp_enqueue_style(
			'dsm-attachment-category-select2',
			plugins_url( 'divi-5/assets/css/dsm-attachment-category-select2.css', $this->plugin_file ),
			array( 'dsm-select-two' ),
			$version
		);

		wp_enqueue_script(
			'dsm-select-two',
			plugins_url( 'divi-4/public/js/select2.min.js', $this->plugin_file ),
			array( 'jquery' ),
			$version,
			true
		);

		wp_enqueue_script(
			'dsm-attachment-category-select2',
			plugins_url( 'divi-5/assets/js/dsm-attachment-category-select2.js', $this->plugin_file ),
			array( 'jquery', 'dsm-select-two', 'media-views' ),
			$version,
			true
		);
	}

	/**
	 * Persist selected attachment categories when the custom field is submitted.
	 *
	 * @param array<string, mixed> $post            Attachment post data.
	 * @param array<string, mixed> $attachment_data Submitted attachment field values.
	 * @return array<string, mixed>
	 */
	public function handle_store( array $post, array $attachment_data ): array {
		if ( ! isset( $attachment_data['dsm_attachment_categories'] ) ) {
			return $post;
		}

		$raw = $attachment_data['dsm_attachment_categories'];

		if ( is_array( $raw ) ) {
			$values = array_map( 'sanitize_text_field', $raw );
		} else {
			$values = array_map(
				'sanitize_text_field',
				explode( ',', (string) $raw )
			);
		}

		$term_ids = array();

		foreach ( $values as $value ) {
			if ( '' === $value ) {
				continue;
			}

			if ( ctype_digit( $value ) ) {
				$term_ids[] = (int) $value;
				continue;
			}

			$term = get_term_by( 'slug', $value, self::TAXONOMY );

			if ( $term instanceof WP_Term ) {
				$term_ids[] = (int) $term->term_id;
			}
		}

		wp_set_object_terms( (int) $post['ID'], array_values( array_unique( $term_ids ) ), self::TAXONOMY );

		return $post;
	}

	/**
	 * Render the Select2 multi-select markup for attachment categories.
	 *
	 * @param \WP_Post $post Attachment post object.
	 * @return string
	 */
	private function render_terms_control( WP_Post $post ): string {
		$terms = get_terms(
			array(
				'taxonomy'   => self::TAXONOMY,
				'hide_empty' => false,
			)
		);

		if ( is_wp_error( $terms ) || ! is_array( $terms ) || array() === $terms ) {
			return '<p class="description">' . esc_html__(
				'No attachment categories yet. Create them under Media → Categories.',
				'dsm-supreme-modules-pro-for-divi'
			) . '</p>';
		}

		ob_start();
		?>
		<div class="dsm-attachment-category-select-wrap">
		<select
			class="dsm-attachment-categories-select"
			name="attachments[<?php echo (int) $post->ID; ?>][dsm_attachment_categories][]"
			multiple="multiple"
			data-placeholder="<?php echo esc_attr__( 'Select categories…', 'dsm-supreme-modules-pro-for-divi' ); ?>"
		>
			<?php foreach ( $terms as $term ) : ?>
				<?php if ( ! $term instanceof WP_Term ) { continue; } ?>
				<option
					value="<?php echo esc_attr( $term->slug ); ?>"
					<?php selected( has_term( $term->term_id, self::TAXONOMY, $post->ID ) ); ?>
				>
					<?php echo esc_html( $term->name ); ?>
				</option>
			<?php endforeach; ?>
		</select>
		</div>
		<script>
			jQuery( function ( $ ) {
				if ( 'function' === typeof window.dsmInitAttachmentCategorySelect ) {
					window.dsmInitAttachmentCategorySelect();
				} else {
					window.setTimeout( function () {
						if ( 'function' === typeof window.dsmInitAttachmentCategorySelect ) {
							window.dsmInitAttachmentCategorySelect();
						}
					}, 100 );
				}
			} );
		</script>
		<?php
		return (string) ob_get_clean();
	}

	/**
	 * Add the custom Select2 control to attachment details in the Media Library.
	 *
	 * @param array<string, mixed> $fields Attachment compat fields.
	 * @param \WP_Post             $post   Attachment post object.
	 * @return array<string, mixed>
	 */
	public function render_custom_selectbox( array $fields, WP_Post $post ): array {
		unset( $fields[ self::TAXONOMY ] );

		$fields['dsm_attachment_categories'] = array(
			'label' => esc_html__( 'Attachment Category - Divi Supreme', 'dsm-supreme-modules-pro-for-divi' ),
			'input' => 'html',
			'html'  => $this->render_terms_control( $post ),
		);

		return $fields;
	}
}

new DSM_Attachment_Category_Fields();
