<?php
/**
 * Sortable columns for the vehicle admin list table.
 *
 * Maps custom column names to specs-table columns and adds a JOIN +
 * ORDER BY clause to the main admin query when one is selected.
 *
 * @package ThemeREX\AutoDealer\Admin\ListTable
 */

declare(strict_types=1);

namespace ThemeREX\AutoDealer\Admin\ListTable;

defined( 'ABSPATH' ) || exit;

use ThemeREX\AutoDealer\PostTypes\VehiclePostType;

final class Sorting {

	private const COLUMN_MAP = array(
		'trx_ad_year'      => 'year',
		'trx_ad_make'      => 'make',
		'trx_ad_model'     => 'model',
		'trx_ad_price'     => 'price',
		'trx_ad_status'    => 'status',
		'trx_ad_condition' => 'condition_type',
		'trx_ad_quality'   => 'listing_quality',
	);

	public function register(): void {
		$postType = VehiclePostType::POST_TYPE;
		add_filter( "manage_edit-{$postType}_sortable_columns", array( $this, 'sortableColumns' ) );
		add_action( 'pre_get_posts', array( $this, 'handleSorting' ) );
	}

	/**
	 * @param array<string,string> $columns Existing sortable columns.
	 * @return array<string,string>
	 */
	public function sortableColumns( array $columns ): array {
		foreach ( array_keys( self::COLUMN_MAP ) as $key ) {
			$columns[ $key ] = $key;
		}
		return $columns;
	}

	public function handleSorting( \WP_Query $query ): void {
		if ( ! is_admin() || ! $query->is_main_query() ) {
			return;
		}

		if ( $query->get( 'post_type' ) !== VehiclePostType::POST_TYPE ) {
			return;
		}

		$orderby = $query->get( 'orderby' );

		if ( ! is_string( $orderby ) || ! isset( self::COLUMN_MAP[ $orderby ] ) ) {
			return;
		}

		$specColumn = self::COLUMN_MAP[ $orderby ];

		add_filter(
			'posts_join',
			static function ( string $join, \WP_Query $q ) use ( $query ): string {
				if ( $q !== $query ) {
					return $join;
				}

				global $wpdb;
				$table = $wpdb->prefix . 'trx_ad_vehicle_specs';
				$join .= " LEFT JOIN `{$table}` AS trx_specs ON ({$wpdb->posts}.ID = trx_specs.post_id)";

				return $join;
			},
			10,
			2
		);

		add_filter(
			'posts_orderby',
			static function ( string $orderbyClause, \WP_Query $q ) use ( $query, $specColumn ): string {
				if ( $q !== $query ) {
					return $orderbyClause;
				}

				$order = strtoupper( $query->get( 'order' ) ) === 'ASC' ? 'ASC' : 'DESC';
				return "trx_specs.`{$specColumn}` {$order}";
			},
			10,
			2
		);
	}
}
