<?php
/**
 * Classification section — taxonomy assignments (multi-select for most,
 * cascading select for Model, grouped checkboxes for Feature).
 *
 * Extracted from VehicleDataMetaBox per QUALITY-IMPROVEMENT-PLAN.md §T2-2.
 * Carries the public DISPLAY_ORDER constant the orchestrator uses to
 * suppress the default core taxonomy sidebar meta boxes.
 *
 * @package ThemeREX\AutoDealer\Admin\MetaBoxes\Sections
 */

declare(strict_types=1);

namespace ThemeREX\AutoDealer\Admin\MetaBoxes\Sections;

defined( 'ABSPATH' ) || exit;

use ThemeREX\AutoDealer\Admin\MetaBoxes\AbstractVehicleDataSection;
use ThemeREX\AutoDealer\PostTypes\VehiclePostType;
use ThemeREX\AutoDealer\Taxonomies\UserTaxonomyManager;

final class ClassificationSection extends AbstractVehicleDataSection {

	/**
	 * Render order for built-in taxonomies. Mirrored by the orchestrator's
	 * `removeDefaultMetaBoxes()` when suppressing WP's default sidebar boxes.
	 */
	public const DISPLAY_ORDER = array(
		'trx_ad_vehicle_type',
		'trx_ad_condition',
		'trx_ad_make',
		'trx_ad_model',
		'trx_ad_body_style',
		'trx_ad_fuel_type',
		'trx_ad_transmission',
		'trx_ad_drivetrain',
		'trx_ad_color',
		'trx_ad_feature',
	);

	public function getKey(): string {
		return 'classification';
	}

	public function render( \WP_Post $post ): void {
		$slugs = self::getActiveSlugs();

		if ( empty( $slugs ) ) {
			echo '<p>' . esc_html__( 'No taxonomies available.', 'trx-auto-dealer' ) . '</p>';
			return;
		}

		echo '<div class="trx-ad-tax-grid">';

		foreach ( $slugs as $slug ) {
			$taxonomy = get_taxonomy( $slug );
			if ( ! $taxonomy instanceof \WP_Taxonomy ) {
				continue; }

			$isFeature = ( $slug === 'trx_ad_feature' );
			$cls       = 'trx-ad-tax-field' . ( $isFeature ? ' trx-ad-tax-field--full' : '' );
			echo '<div class="' . esc_attr( $cls ) . '">';
			printf( '<label class="trx-ad-tax-label">%s</label>', esc_html( $taxonomy->labels->name ?? $slug ) );

			if ( $isFeature ) {
				$this->renderFeatureCheckboxes( $post );
			} elseif ( $slug === 'trx_ad_model' ) {
				$this->renderModelSelect( $post );
			} else {
				$this->renderMultiSelect( $post, $slug );
			}

			echo '</div>';
		}

		echo '</div>';
	}

	public function save( int $postId ): void {
		// Re-verify the meta-box nonce here as well as in the VehicleDataMetaBox
		// dispatcher -- defense in depth, and each save path is independently
		// auditable (wp.org 2026-07 review round 2).
		if (
			! isset( $_POST['_trx_ad_vehicle_data_nonce'] )
			|| ! wp_verify_nonce( sanitize_text_field( wp_unslash( (string) $_POST['_trx_ad_vehicle_data_nonce'] ) ), 'trx_ad_vehicle_data_save' )
		) {
			return;
		}

		$slugs = self::getActiveSlugs();

		foreach ( $slugs as $slug ) {
			$taxonomy = get_taxonomy( $slug );
			if ( ! $taxonomy instanceof \WP_Taxonomy ) {
				continue; }

			$fieldName = 'trx_ad_tax_' . $slug;

			// Sanitized at the read: unslash + absint every entry (scalar
			// input degrades to a one-element array; empty/invalid entries
			// fall out through array_filter).
			$posted  = isset( $_POST[ $fieldName ] )
				? map_deep( wp_unslash( (array) $_POST[ $fieldName ] ), 'absint' )
				: array();
			$termIds = array_filter( $posted );
			wp_set_object_terms( $postId, $termIds, $slug );
		}
	}

	public static function getActiveSlugs(): array {
		$slugs = array();
		foreach ( self::DISPLAY_ORDER as $slug ) {
			if ( ! UserTaxonomyManager::isDisabled( $slug ) ) {
				$slugs[] = $slug;
			}
		}
		foreach ( UserTaxonomyManager::getAll() as $tax ) {
			if ( isset( $tax['slug'] ) && $tax['slug'] !== '' ) {
				$slugs[] = $tax['slug'];
			}
		}
		return $slugs;
	}

	private function renderMultiSelect( \WP_Post $post, string $slug ): void {
		$terms   = get_terms(
			array(
				'taxonomy'   => $slug,
				'hide_empty' => false,
				'orderby'    => 'name',
				'order'      => 'ASC',
			)
		);
		$current = wp_get_object_terms( $post->ID, $slug, array( 'fields' => 'ids' ) );
		if ( is_wp_error( $current ) ) {
			$current = array(); }

		// The Make select keeps its historical id (the Make->Model linkage JS
		// targets #trx-ad-make-select); every other taxonomy gets a derived one.
		$select_id = 'trx_ad_make' === $slug ? 'trx-ad-make-select' : 'trx-ad-' . str_replace( '_', '-', $slug ) . '-select';

		printf(
			'<select name="trx_ad_tax_%s[]" id="%s" class="trx-ad-tax-multiselect" multiple="multiple" data-placeholder="%s">',
			esc_attr( $slug ),
			esc_attr( $select_id ),
			/* translators: %s: taxonomy label */
			esc_attr( sprintf( __( 'Select %s...', 'trx-auto-dealer' ), get_taxonomy( $slug )->labels->name ?? '' ) )
		);

		if ( ! is_wp_error( $terms ) ) {
			foreach ( $terms as $t ) {
				printf(
					'<option value="%d"%s>%s</option>',
					absint( $t->term_id ),
					in_array( $t->term_id, $current, true ) ? ' selected' : '',
					esc_html( $t->name )
				);
			}
		}

		echo '</select>';
	}

	private function renderModelSelect( \WP_Post $post ): void {
		$curModel = wp_get_object_terms( $post->ID, 'trx_ad_model', array( 'fields' => 'ids' ) );
		if ( is_wp_error( $curModel ) ) {
			$curModel = array(); }

		$all = get_terms(
			array(
				'taxonomy'   => 'trx_ad_model',
				'hide_empty' => false,
				'orderby'    => 'name',
				'order'      => 'ASC',
			)
		);

		printf(
			'<select name="trx_ad_tax_trx_ad_model[]" id="trx-ad-model-select" class="trx-ad-tax-multiselect" multiple="multiple" data-placeholder="%s">',
			esc_attr__( 'Select Model...', 'trx-auto-dealer' )
		);

		if ( ! is_wp_error( $all ) ) {
			foreach ( $all as $t ) {
				// Make->Model linkage lives in term meta (Models is a flat
				// taxonomy; parent isn't usable cross-taxonomy). See
				// Taxonomies\ModelMakeLink.
				$make_id = (int) get_term_meta( $t->term_id, '_trx_ad_model_make', true );
				printf(
					'<option value="%d" data-make="%d"%s>%s</option>',
					absint( $t->term_id ),
					absint( $make_id ),
					in_array( $t->term_id, $curModel, true ) ? ' selected' : '',
					esc_html( $t->name )
				);
			}
		}

		echo '</select>';
	}

	private function renderFeatureCheckboxes( \WP_Post $post ): void {
		$curIds = wp_get_object_terms( $post->ID, 'trx_ad_feature', array( 'fields' => 'ids' ) );
		if ( is_wp_error( $curIds ) ) {
			$curIds = array();
		}

		$tax             = get_taxonomy( 'trx_ad_feature' );
		$is_hierarchical = $tax instanceof \WP_Taxonomy && $tax->hierarchical;

		if ( $is_hierarchical ) {
			$parents = get_terms(
				array(
					'taxonomy'   => 'trx_ad_feature',
					'hide_empty' => false,
					'parent'     => 0,
					'orderby'    => 'name',
				)
			);
			if ( ! is_wp_error( $parents ) && ! empty( $parents ) ) {
				$rendered_any = false;
				ob_start();
				echo '<div class="trx-ad-feature-groups">';
				foreach ( $parents as $parent ) {
					$children = get_terms(
						array(
							'taxonomy'   => 'trx_ad_feature',
							'hide_empty' => false,
							'parent'     => $parent->term_id,
							'orderby'    => 'name',
						)
					);
					if ( is_wp_error( $children ) || empty( $children ) ) {
						continue;
					}
					$rendered_any = true;
					echo '<div class="trx-ad-feature-group">';
					printf( '<h5 class="trx-ad-feature-group-title">%s</h5>', esc_html( $parent->name ) );
					echo '<div class="trx-ad-feature-checkboxes">';
					foreach ( $children as $c ) {
						printf(
							'<label class="trx-ad-feature-checkbox"><input type="checkbox" name="trx_ad_tax_trx_ad_feature[]" value="%d"%s> %s</label>',
							absint( $c->term_id ),
							in_array( $c->term_id, $curIds, true ) ? ' checked' : '',
							esc_html( $c->name )
						);
					}
					echo '</div></div>';
				}
				echo '</div>';
				$grouped = (string) ob_get_clean();
				if ( $rendered_any ) {
					echo wp_kses( $grouped, \ThemeREX\AutoDealer\allowedHtml() );
					return;
				}
			}
		}

		$terms = get_terms(
			array(
				'taxonomy'   => 'trx_ad_feature',
				'hide_empty' => false,
				'orderby'    => 'name',
			)
		);
		if ( is_wp_error( $terms ) || empty( $terms ) ) {
			$add_url = admin_url( 'edit-tags.php?taxonomy=trx_ad_feature&post_type=' . VehiclePostType::POST_TYPE );
			printf(
				'<p class="description">%s <a href="%s">%s</a>.</p>',
				esc_html__( 'No features are defined yet.', 'trx-auto-dealer' ),
				esc_url( $add_url ),
				esc_html__( 'Add features', 'trx-auto-dealer' )
			);
			return;
		}
		echo '<div class="trx-ad-feature-checkboxes">';
		foreach ( $terms as $t ) {
			printf(
				'<label class="trx-ad-feature-checkbox"><input type="checkbox" name="trx_ad_tax_trx_ad_feature[]" value="%d"%s> %s</label>',
				absint( $t->term_id ),
				in_array( $t->term_id, $curIds, true ) ? ' checked' : '',
				esc_html( $t->name )
			);
		}
		echo '</div>';
	}
}
