<?php
/**
 * Adds a "Parent Make" field to the Model taxonomy admin UI and exposes
 * helpers for resolving model→make linkage at runtime.
 *
 * Why term meta and not WP's built-in `parent`? `parent` only points at
 * terms in the SAME taxonomy. Models live in `trx_ad_model` and Makes
 * in `trx_ad_make` — different taxonomies — so we need a cross-taxonomy
 * linker. We store the parent-make term ID under the
 * `_trx_ad_model_make` term meta key on each model term.
 *
 * Surfaces:
 *   - "Add New Model" form: dropdown to pick the parent Make.
 *   - "Edit Model" form: same dropdown, pre-selected.
 *   - Models list table: extra "Make" column.
 *
 * @package ThemeREX\AutoDealer
 */

declare(strict_types=1);

namespace ThemeREX\AutoDealer\Taxonomies;

defined( 'ABSPATH' ) || exit;
final class ModelMakeLink {

	public const META_KEY = '_trx_ad_model_make';

	public function register(): void {
		add_action( 'trx_ad_model_add_form_fields', array( $this, 'renderAddField' ) );
		add_action( 'trx_ad_model_edit_form_fields', array( $this, 'renderEditField' ) );
		add_action( 'created_trx_ad_model', array( $this, 'saveField' ) );
		add_action( 'edited_trx_ad_model', array( $this, 'saveField' ) );

		add_filter( 'manage_edit-trx_ad_model_columns', array( $this, 'addMakeColumn' ) );
		add_filter( 'manage_trx_ad_model_custom_column', array( $this, 'renderMakeColumn' ), 10, 3 );
	}

	/**
	 * Returns the make term ID linked to a model term, or 0 if unset.
	 */
	public static function getMakeIdForModel( int $modelTermId ): int {
		return (int) get_term_meta( $modelTermId, self::META_KEY, true );
	}

	/**
	 * Returns model term IDs whose `_trx_ad_model_make` is the given make.
	 *
	 * @return int[]
	 */
	public static function getModelIdsForMake( int $makeTermId ): array {
		if ( $makeTermId <= 0 ) {
			return array();
		}
		$rows = get_terms(
			array(
				'taxonomy'   => 'trx_ad_model',
				'hide_empty' => false,
				'meta_query' => array(
					array(
						'key'   => self::META_KEY,
						'value' => (string) $makeTermId,
					),
				),
				'fields'     => 'ids',
			)
		);
		if ( is_wp_error( $rows ) || ! is_array( $rows ) ) {
			return array();
		}
		return array_values( array_map( 'intval', $rows ) );
	}

	/**
	 * Render the field on the "Add New Model" form (no $term yet).
	 */
	public function renderAddField(): void {
		$makes = $this->fetchMakes();
		?>
		<div class="form-field">
			<label for="trx_ad_model_make"><?php esc_html_e( 'Parent Make', 'trx-auto-dealer' ); ?></label>
			<select id="trx_ad_model_make" name="trx_ad_model_make">
				<option value="0"><?php esc_html_e( '— Select a make —', 'trx-auto-dealer' ); ?></option>
				<?php foreach ( $makes as $make ) : ?>
					<option value="<?php echo esc_attr( (string) $make->term_id ); ?>">
						<?php echo esc_html( $make->name ); ?>
					</option>
				<?php endforeach; ?>
			</select>
			<p><?php esc_html_e( 'Pick the make this model belongs to so frontend filters can cascade Make → Model.', 'trx-auto-dealer' ); ?></p>
		</div>
		<?php
	}

	/**
	 * Render the field on the "Edit Model" form.
	 *
	 * @param \WP_Term $term
	 */
	public function renderEditField( $term ): void {
		if ( ! ( $term instanceof \WP_Term ) ) {
			return;
		}
		$makes    = $this->fetchMakes();
		$selected = self::getMakeIdForModel( (int) $term->term_id );
		?>
		<tr class="form-field">
			<th scope="row"><label for="trx_ad_model_make"><?php esc_html_e( 'Parent Make', 'trx-auto-dealer' ); ?></label></th>
			<td>
				<select id="trx_ad_model_make" name="trx_ad_model_make">
					<option value="0"><?php esc_html_e( '— None —', 'trx-auto-dealer' ); ?></option>
					<?php foreach ( $makes as $make ) : ?>
						<option value="<?php echo esc_attr( (string) $make->term_id ); ?>" <?php selected( $selected, (int) $make->term_id ); ?>>
							<?php echo esc_html( $make->name ); ?>
						</option>
					<?php endforeach; ?>
				</select>
				<p class="description"><?php esc_html_e( 'Pick the make this model belongs to so frontend filters can cascade Make → Model.', 'trx-auto-dealer' ); ?></p>
			</td>
		</tr>
		<?php
	}

	public function saveField( int $termId ): void {
		// `created_*` and `edited_*` hooks are called from inside
		// `wp_insert_term`/`wp_update_term`, which are themselves called
		// from the admin's nonce-checked form handlers. Nonce: `add-tag`
		// for create, `update-tag_{term_id}` for edit.
		if ( isset( $_POST['_wpnonce_add-tag'] ) ) {
			if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( (string) $_POST['_wpnonce_add-tag'] ) ), 'add-tag' ) ) {
				return;
			}
		} elseif ( isset( $_POST['_wpnonce'] ) ) {
			$nonce = sanitize_text_field( wp_unslash( (string) $_POST['_wpnonce'] ) );
			if ( ! wp_verify_nonce( $nonce, 'update-tag_' . $termId ) ) {
				return;
			}
		}

		if ( ! isset( $_POST['trx_ad_model_make'] ) ) {
			return;
		}
		$make_id = (int) $_POST['trx_ad_model_make'];
		if ( $make_id > 0 ) {
			update_term_meta( $termId, self::META_KEY, $make_id );
		} else {
			delete_term_meta( $termId, self::META_KEY );
		}
	}

	/**
	 * @param array<string, string> $columns
	 * @return array<string, string>
	 */
	public function addMakeColumn( array $columns ): array {
		$out = array();
		foreach ( $columns as $key => $label ) {
			$out[ $key ] = $label;
			if ( 'name' === $key ) {
				$out['trx_ad_make'] = __( 'Make', 'trx-auto-dealer' );
			}
		}
		return $out;
	}

	/**
	 * @param string $content
	 */
	public function renderMakeColumn( $content, string $columnName, int $termId ): string {
		if ( 'trx_ad_make' !== $columnName ) {
			return (string) $content;
		}
		$make_id = self::getMakeIdForModel( $termId );
		if ( $make_id <= 0 ) {
			return '<em style="color:#999;">' . esc_html__( '— unset —', 'trx-auto-dealer' ) . '</em>';
		}
		$make = get_term( $make_id, 'trx_ad_make' );
		if ( ! ( $make instanceof \WP_Term ) ) {
			return '';
		}
		return esc_html( $make->name );
	}

	/**
	 * @return \WP_Term[]
	 */
	private function fetchMakes(): array {
		$terms = get_terms(
			array(
				'taxonomy'   => 'trx_ad_make',
				'hide_empty' => false,
				'orderby'    => 'name',
				'order'      => 'ASC',
			)
		);
		if ( is_wp_error( $terms ) || ! is_array( $terms ) ) {
			return array();
		}
		return array_values( array_filter( $terms, static fn( $t ) => $t instanceof \WP_Term ) );
	}
}
