<?php
/**
 * Taxonomies tab — disable built-in taxonomies, define custom taxonomies.
 *
 * Extracted from AdminSettings per QUALITY-IMPROVEMENT-PLAN.md §T2-2.
 *
 * @package ThemeREX\AutoDealer\Admin\Settings\Tabs
 */

declare(strict_types=1);

namespace ThemeREX\AutoDealer\Admin\Settings\Tabs;

defined( 'ABSPATH' ) || exit;

use ThemeREX\AutoDealer\Admin\AdminSettings;
use ThemeREX\AutoDealer\Admin\Settings\AbstractSettingsTab;
use ThemeREX\AutoDealer\Admin\TaxonomyIconFields;
use ThemeREX\AutoDealer\PostTypes\VehiclePostType;
use ThemeREX\AutoDealer\Taxonomies\UserTaxonomyManager;
use ThemeREX\AutoDealer\Admin\AdminAssets;

final class TaxonomiesTab extends AbstractSettingsTab {

	/**
	 * Spec pseudo-fields that carry configurable icons alongside the real
	 * taxonomies (they render in Specs Highlights; tester feedback #8 —
	 * "not all taxonomies are present in settings").
	 *
	 * @var string[]
	 */
	private const SPEC_ICON_KEYS = array( '_year', '_mileage' );

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

	public function getLabel(): string {
		return __( 'Taxonomies', 'trx-auto-dealer' );
	}

	public function register(): void {
		// Same fix as FieldsTab (UAT #21) / FormsTab: this register() runs
		// *inside* AdminSettings::registerSettings, which is itself hooked to
		// `admin_init` — adding another `admin_init` hook here is too late (the
		// hook is already mid-dispatch for this request), so the save handlers
		// never ran and icon/disable choices silently vanished (tester feedback
		// #8). admin-post.php fires `admin_init` first, *then* the admin_post_*
		// action, so a hook bound during admin_init still runs.
		add_action( 'admin_post_trx_ad_save_taxonomies', array( $this, 'handleTaxonomiesSave' ) );
		add_action( 'admin_post_trx_ad_save_disabled_taxonomies', array( $this, 'handleDisabledTaxonomiesSave' ) );
	}

	/**
	 * POST handler for the user-defined-taxonomies table.
	 */
	public function handleTaxonomiesSave(): void {
		if (
			! isset( $_POST['trx_ad_taxonomies_nonce'] )
			|| ! wp_verify_nonce(
				sanitize_text_field( wp_unslash( $_POST['trx_ad_taxonomies_nonce'] ) ),
				'trx_ad_save_taxonomies'
			)
		) {
			wp_die( esc_html__( 'Invalid request.', 'trx-auto-dealer' ), 400 );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Permission denied.', 'trx-auto-dealer' ), 403 );
		}

		// Sanitized at the read: unslash + text-field-sanitize every leaf of
		// the nested taxonomy-definition array; the loop below then applies
		// the per-key sanitizers (sanitize_key, sanitize_title, ...).
		$raw = isset( $_POST['trx_ad_tax'] ) && is_array( $_POST['trx_ad_tax'] )
			? map_deep( wp_unslash( $_POST['trx_ad_tax'] ), 'sanitize_text_field' )
			: array();

		$taxonomies = array();

		foreach ( $raw as $tax ) {
			if ( ! is_array( $tax ) ) {
				continue;
			}

			$label = sanitize_text_field( $tax['label'] ?? '' );
			if ( $label === '' ) {
				continue;
			}

			$taxonomies[] = array(
				'id'              => sanitize_key( $tax['id'] ?? '' ),
				'slug'            => sanitize_key( $tax['slug'] ?? '' ),
				'label'           => $label,
				'singular'        => sanitize_text_field( $tax['singular'] ?? $label ),
				'hierarchical'    => ! empty( $tax['hierarchical'] ),
				'show_in_filters' => ! empty( $tax['show_in_filters'] ),
				'show_in_specs'   => ! empty( $tax['show_in_specs'] ),
				'rewrite_slug'    => sanitize_title( $tax['rewrite_slug'] ?? $label ),
			);
		}

		$result = UserTaxonomyManager::save( $taxonomies );

		// Sanitized at the read (slug => icon-key / attachment-ID maps).
		$rawIcons  = isset( $_POST['trx_ad_tax_icon'] ) && is_array( $_POST['trx_ad_tax_icon'] )
			? map_deep( wp_unslash( $_POST['trx_ad_tax_icon'] ), 'sanitize_key' )
			: array();
		$rawImages = isset( $_POST['trx_ad_tax_image'] ) && is_array( $_POST['trx_ad_tax_image'] )
			? map_deep( wp_unslash( $_POST['trx_ad_tax_image'] ), 'absint' )
			: array();
		$icons     = get_option( TaxonomyIconFields::OPTION_KEY, array() );

		foreach ( $taxonomies as $tax ) {
			$slug = $tax['slug'] ?? '';
			if ( '' === $slug ) {
				continue;
			}
			$icons[ $slug ] = array(
				'icon'     => isset( $rawIcons[ $slug ] ) ? sanitize_key( $rawIcons[ $slug ] ) : '',
				'image_id' => isset( $rawImages[ $slug ] ) ? absint( $rawImages[ $slug ] ) : 0,
			);
		}

		update_option( TaxonomyIconFields::OPTION_KEY, $icons );

		$args = array(
			'post_type' => 'trx_ad_listing',
			'page'      => AdminSettings::PAGE_SLUG,
			'tab'       => 'taxonomies',
		);

		if ( is_wp_error( $result ) ) {
			$args['error'] = rawurlencode( $result->get_error_message() );
		} else {
			$args['updated'] = '1';
		}

		wp_safe_redirect( add_query_arg( $args, admin_url( 'edit.php' ) ) );
		exit;
	}

	/**
	 * POST handler for the "enable/disable core taxonomies" checkbox grid.
	 */
	public function handleDisabledTaxonomiesSave(): void {
		if (
			! isset( $_POST['trx_ad_disabled_tax_nonce'] )
			|| ! wp_verify_nonce(
				sanitize_text_field( wp_unslash( $_POST['trx_ad_disabled_tax_nonce'] ) ),
				'trx_ad_save_disabled_taxonomies'
			)
		) {
			wp_die( esc_html__( 'Invalid request.', 'trx-auto-dealer' ), 400 );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Permission denied.', 'trx-auto-dealer' ), 403 );
		}

		// Sanitized at the read: list of core-taxonomy slugs.
		$enabled = isset( $_POST['trx_ad_core_enabled'] ) && is_array( $_POST['trx_ad_core_enabled'] )
			? array_map( 'sanitize_key', wp_unslash( $_POST['trx_ad_core_enabled'] ) )
			: array();

		$disabledSlugs = array_diff( UserTaxonomyManager::CORE_TAXONOMIES, $enabled );

		UserTaxonomyManager::saveDisabled( array_values( $disabledSlugs ) );

		// Sanitized at the read (slug => icon-key / attachment-ID maps).
		$rawIcons  = isset( $_POST['trx_ad_tax_icon'] ) && is_array( $_POST['trx_ad_tax_icon'] )
			? map_deep( wp_unslash( $_POST['trx_ad_tax_icon'] ), 'sanitize_key' )
			: array();
		$rawImages = isset( $_POST['trx_ad_tax_image'] ) && is_array( $_POST['trx_ad_tax_image'] )
			? map_deep( wp_unslash( $_POST['trx_ad_tax_image'] ), 'absint' )
			: array();
		$icons     = get_option( TaxonomyIconFields::OPTION_KEY, array() );

		foreach ( array_merge( VehiclePostType::TAXONOMIES, self::SPEC_ICON_KEYS ) as $taxonomy ) {
			$icons[ $taxonomy ] = array(
				'icon'     => isset( $rawIcons[ $taxonomy ] ) ? sanitize_key( $rawIcons[ $taxonomy ] ) : '',
				'image_id' => isset( $rawImages[ $taxonomy ] ) ? absint( $rawImages[ $taxonomy ] ) : 0,
			);
		}

		update_option( TaxonomyIconFields::OPTION_KEY, $icons );

		wp_safe_redirect(
			add_query_arg(
				array(
					'post_type' => 'trx_ad_listing',
					'page'      => AdminSettings::PAGE_SLUG,
					'tab'       => 'taxonomies',
					'updated'   => '1',
				),
				admin_url( 'edit.php' )
			)
		);
		exit;
	}

	public function render(): void {
		$taxonomies = UserTaxonomyManager::getAll();

		if ( isset( $_GET['updated'] ) && $_GET['updated'] === '1' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			echo '<div class="notice notice-success is-dismissible"><p>';
			esc_html_e( 'Custom taxonomies saved.', 'trx-auto-dealer' );
			echo '</p></div>';
		}

		if ( isset( $_GET['error'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			printf(
				'<div class="notice notice-error is-dismissible"><p>%s</p></div>',
				esc_html( urldecode( sanitize_text_field( wp_unslash( $_GET['error'] ) ) ) ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			);
		}

		?>
		<h3><?php esc_html_e( 'Built-in Taxonomies', 'trx-auto-dealer' ); ?></h3>
		<p class="description">
			<?php esc_html_e( 'Core taxonomies are always registered but can be disabled from the UI. Disabled taxonomies are hidden from admin menus, vehicle edit screens, filters, and the frontend. Essential taxonomies (Make, Model, Vehicle Type, Condition) cannot be disabled.', 'trx-auto-dealer' ); ?>
		</p>

		<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
			<input type="hidden" name="action" value="trx_ad_save_disabled_taxonomies">
			<?php wp_nonce_field( 'trx_ad_save_disabled_taxonomies', 'trx_ad_disabled_tax_nonce' ); ?>

			<table class="widefat trx-ad-tax-table" style="margin:10px 0 15px;">
				<thead>
					<tr>
						<th style="width:70px;"><?php esc_html_e( 'Enabled', 'trx-auto-dealer' ); ?></th>
						<th><?php esc_html_e( 'Icon', 'trx-auto-dealer' ); ?></th>
						<th><?php esc_html_e( 'Label', 'trx-auto-dealer' ); ?></th>
						<th><?php esc_html_e( 'Slug', 'trx-auto-dealer' ); ?></th>
						<th><?php esc_html_e( 'Type', 'trx-auto-dealer' ); ?></th>
						<th style="width:80px;"><?php esc_html_e( 'Status', 'trx-auto-dealer' ); ?></th>
					</tr>
				</thead>
				<tbody>
					<?php
					$disabled   = UserTaxonomyManager::getDisabled();
					$savedIcons = get_option( TaxonomyIconFields::OPTION_KEY, array() );
					$core       = array(
						array( 'Make', 'trx_ad_make', 'Flat' ),
						array( 'Model', 'trx_ad_model', 'Hierarchical' ),
						array( 'Body Style', 'trx_ad_body_style', 'Flat' ),
						array( 'Fuel Type', 'trx_ad_fuel_type', 'Flat' ),
						array( 'Transmission', 'trx_ad_transmission', 'Flat' ),
						array( 'Drivetrain', 'trx_ad_drivetrain', 'Flat' ),
						array( 'Color', 'trx_ad_color', 'Flat' ),
						array( 'Feature', 'trx_ad_feature', 'Hierarchical' ),
						array( 'Vehicle Type', 'trx_ad_vehicle_type', 'Flat' ),
						array( 'Condition', 'trx_ad_condition', 'Flat' ),
					);

					foreach ( $core as $row ) :
						$isNonDisableable = in_array( $row[1], UserTaxonomyManager::NON_DISABLEABLE, true );
						$isDisabled       = in_array( $row[1], $disabled, true );
						$isEnabled        = ! $isDisabled;
						?>
						<tr class="<?php echo $isDisabled ? 'trx-ad-tax-disabled-row' : ''; ?>">
							<td style="text-align:center;">
								<?php if ( $isNonDisableable ) : ?>
									<input type="checkbox" checked disabled title="<?php esc_attr_e( 'Required — cannot be disabled', 'trx-auto-dealer' ); ?>">
									<input type="hidden" name="trx_ad_core_enabled[]" value="<?php echo esc_attr( $row[1] ); ?>">
								<?php else : ?>
									<input type="checkbox" name="trx_ad_core_enabled[]" value="<?php echo esc_attr( $row[1] ); ?>" <?php checked( $isEnabled ); ?>>
								<?php endif; ?>
							</td>
							<td>
								<?php
								$taxIconData = $savedIcons[ $row[1] ] ?? array();
								TaxonomyIconFields::renderIconCell(
									$row[1],
									$taxIconData['icon'] ?? '',
									(int) ( $taxIconData['image_id'] ?? 0 )
								);
								?>
							</td>
							<td>
								<strong><?php echo esc_html( $row[0] ); ?></strong>
								<?php if ( $isNonDisableable ) : ?>
									<span class="dashicons dashicons-lock" style="color:#999; font-size:14px; vertical-align:middle;" title="<?php esc_attr_e( 'Required — cannot be disabled', 'trx-auto-dealer' ); ?>"></span>
								<?php endif; ?>
							</td>
							<td><code><?php echo esc_html( $row[1] ); ?></code></td>
							<td><?php echo esc_html( $row[2] ); ?></td>
							<td>
								<?php if ( $isDisabled ) : ?>
									<span style="color:#b32d2e; font-weight:600;"><?php esc_html_e( 'Disabled', 'trx-auto-dealer' ); ?></span>
								<?php else : ?>
									<span style="color:#00a32a; font-weight:600;"><?php esc_html_e( 'Active', 'trx-auto-dealer' ); ?></span>
								<?php endif; ?>
							</td>
						</tr>
					<?php endforeach; ?>
				</tbody>
			</table>

			<h3><?php esc_html_e( 'Spec Field Icons', 'trx-auto-dealer' ); ?></h3>
			<p class="description">
				<?php esc_html_e( 'Year and Mileage are spec fields, not taxonomies, but they appear with icons in the Specs Highlights block/widget — configure those icons here.', 'trx-auto-dealer' ); ?>
			</p>

			<table class="widefat trx-ad-tax-table" style="margin:10px 0 15px;">
				<thead>
					<tr>
						<th><?php esc_html_e( 'Icon', 'trx-auto-dealer' ); ?></th>
						<th><?php esc_html_e( 'Field', 'trx-auto-dealer' ); ?></th>
					</tr>
				</thead>
				<tbody>
					<?php
					$specFields = array(
						'_year'    => __( 'Year', 'trx-auto-dealer' ),
						'_mileage' => __( 'Mileage', 'trx-auto-dealer' ),
					);
					foreach ( $specFields as $specKey => $specLabel ) :
						$specIconData = $savedIcons[ $specKey ] ?? array();
						?>
						<tr>
							<td>
								<?php
								TaxonomyIconFields::renderIconCell(
									$specKey,
									$specIconData['icon'] ?? '',
									(int) ( $specIconData['image_id'] ?? 0 )
								);
								?>
							</td>
							<td><strong><?php echo esc_html( $specLabel ); ?></strong></td>
						</tr>
					<?php endforeach; ?>
				</tbody>
			</table>

			<?php submit_button( __( 'Save Core Taxonomy Settings', 'trx-auto-dealer' ), 'secondary' ); ?>
		</form>

		<h3>
			<?php esc_html_e( 'Custom Taxonomies', 'trx-auto-dealer' ); ?>
		</h3>
		<p class="description">
			<?php esc_html_e( 'Create additional classification groups for your vehicle listings beyond the 10 built-in ones.', 'trx-auto-dealer' ); ?>
		</p>

		<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
			<input type="hidden" name="action" value="trx_ad_save_taxonomies">
			<?php wp_nonce_field( 'trx_ad_save_taxonomies', 'trx_ad_taxonomies_nonce' ); ?>

			<table class="widefat trx-ad-tax-table" id="trx-ad-tax-table">
				<thead>
					<tr>
						<th><?php esc_html_e( 'Icon', 'trx-auto-dealer' ); ?></th>
						<th><?php esc_html_e( 'Label (Plural)', 'trx-auto-dealer' ); ?></th>
						<th><?php esc_html_e( 'Label (Singular)', 'trx-auto-dealer' ); ?></th>
						<th><?php esc_html_e( 'Slug', 'trx-auto-dealer' ); ?></th>
						<th><?php esc_html_e( 'URL Slug', 'trx-auto-dealer' ); ?></th>
						<th style="width:80px;"><?php esc_html_e( 'Hierarchical', 'trx-auto-dealer' ); ?></th>
						<th style="width:80px;"><?php esc_html_e( 'In Filters', 'trx-auto-dealer' ); ?></th>
						<th style="width:80px;"><?php esc_html_e( 'In Specs', 'trx-auto-dealer' ); ?></th>
						<th style="width:50px;"></th>
					</tr>
				</thead>
				<tbody id="trx-ad-tax-body">
					<?php
					if ( ! empty( $taxonomies ) ) {
						foreach ( $taxonomies as $i => $tax ) {
							$this->renderTaxonomyRow( $i, $tax );
						}
					}
					?>
				</tbody>
			</table>

			<p>
				<button type="button" class="button" id="trx-ad-add-tax">
					<?php esc_html_e( '+ Add Taxonomy', 'trx-auto-dealer' ); ?>
				</button>
			</p>

			<?php submit_button( __( 'Save Custom Taxonomies', 'trx-auto-dealer' ) ); ?>
		</form>

		<?php
		// The tab behavior lives in assets/js/admin.js (initTaxonomiesTab,
		// guarded on #trx-ad-tax-body); only DATA crosses the PHP->JS
		// boundary, via wp_localize_script (wp.org 2026-07 review round 2:
		// no PHP-composed script bodies).
		wp_localize_script(
			AdminAssets::JS_HANDLE,
			'trxAdTaxTab',
			array(
				'slugPrefix' => UserTaxonomyManager::SLUG_PREFIX,
				'i18n'       => array(
					'saveFirst'  => __( 'Save first, then set icon.', 'trx-auto-dealer' ),
					'labelPh'    => __( 'e.g. Engine Sizes', 'trx-auto-dealer' ),
					'singularPh' => __( 'e.g. Engine Size', 'trx-auto-dealer' ),
					'rewritePh'  => __( 'engine-size', 'trx-auto-dealer' ),
					'remove'     => __( 'Remove', 'trx-auto-dealer' ),
				),
			)
		);
	}

	private function renderTaxonomyRow( int $i, array $tax ): void {
		$pfx = 'trx_ad_tax[' . $i . ']';
		?>
		<tr>
			<td>
				<?php
				$ctSlug       = $tax['slug'] ?? '';
				$ctSavedIcons = get_option( TaxonomyIconFields::OPTION_KEY, array() );
				$ctIconData   = $ctSavedIcons[ $ctSlug ] ?? array();
				TaxonomyIconFields::renderIconCell(
					$ctSlug,
					$ctIconData['icon'] ?? '',
					(int) ( $ctIconData['image_id'] ?? 0 )
				);
				?>
			</td>
			<td>
				<input type="hidden" name="<?php echo esc_attr( $pfx ); ?>[id]" value="<?php echo esc_attr( $tax['id'] ?? '' ); ?>">
				<input type="text" name="<?php echo esc_attr( $pfx ); ?>[label]" value="<?php echo esc_attr( $tax['label'] ?? '' ); ?>"
						class="regular-text trx-ad-tax-label" placeholder="<?php esc_attr_e( 'e.g. Engine Sizes', 'trx-auto-dealer' ); ?>" required>
			</td>
			<td>
				<input type="text" name="<?php echo esc_attr( $pfx ); ?>[singular]" value="<?php echo esc_attr( $tax['singular'] ?? '' ); ?>"
						class="regular-text" placeholder="<?php esc_attr_e( 'e.g. Engine Size', 'trx-auto-dealer' ); ?>">
			</td>
			<td>
				<input type="text" name="<?php echo esc_attr( $pfx ); ?>[slug]" value="<?php echo esc_attr( $tax['slug'] ?? '' ); ?>"
						class="regular-text trx-ad-tax-slug" data-manual="1" readonly>
			</td>
			<td>
				<input type="text" name="<?php echo esc_attr( $pfx ); ?>[rewrite_slug]" value="<?php echo esc_attr( $tax['rewrite_slug'] ?? '' ); ?>"
						class="regular-text trx-ad-tax-rewrite" data-manual="1" placeholder="<?php esc_attr_e( 'URL slug', 'trx-auto-dealer' ); ?>">
			</td>
			<td style="text-align:center;">
				<input type="checkbox" name="<?php echo esc_attr( $pfx ); ?>[hierarchical]" value="1" <?php checked( ! empty( $tax['hierarchical'] ) ); ?>>
			</td>
			<td style="text-align:center;">
				<input type="checkbox" name="<?php echo esc_attr( $pfx ); ?>[show_in_filters]" value="1" <?php checked( ! empty( $tax['show_in_filters'] ) ); ?>>
			</td>
			<td style="text-align:center;">
				<input type="checkbox" name="<?php echo esc_attr( $pfx ); ?>[show_in_specs]" value="1" <?php checked( ! empty( $tax['show_in_specs'] ) ); ?>>
			</td>
			<td>
				<button type="button" class="button-link trx-ad-remove-tax" style="color:#b32d2e;" title="<?php esc_attr_e( 'Remove', 'trx-auto-dealer' ); ?>">
					<span class="dashicons dashicons-trash"></span>
				</button>
			</td>
		</tr>
		<?php
	}
}
