<?php
/**
 * Specifications section — five fieldsets covering identification, drivetrain,
 * EV data, dimensions, and history.
 *
 * Extracted from VehicleDataMetaBox per QUALITY-IMPROVEMENT-PLAN.md §T2-2.
 *
 * @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;

final class SpecificationsSection extends AbstractVehicleDataSection {

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

	/**
	 * Field registry. Order is render order. Keys are section labels.
	 *
	 * Each row: [ meta_key, label, input_type, options_or_attrs ]
	 *
	 * @return array<string, array<int, array{0:string,1:string,2:string,3:array<string,mixed>}>>
	 */
	private function fields(): array {
		return array(
			'Identification' => array(
				array(
					'_trx_ad_vin',
					__( 'VIN', 'trx-auto-dealer' ),
					'text',
					array(
						'maxlength' => 17,
						'pattern'   => '[A-HJ-NPR-Z0-9]{11,17}',
					),
				),
				array( '_trx_ad_stock_number', __( 'Stock #', 'trx-auto-dealer' ), 'text', array() ),
				array(
					'_trx_ad_status',
					__( 'Status', 'trx-auto-dealer' ),
					'select',
					array(
						'options' => array(
							'available'   => __( 'Available', 'trx-auto-dealer' ),
							'sold'        => __( 'Sold', 'trx-auto-dealer' ),
							'reserved'    => __( 'Reserved', 'trx-auto-dealer' ),
							'coming_soon' => __( 'Coming soon', 'trx-auto-dealer' ),
						),
					),
				),
				array(
					'_trx_ad_year',
					__( 'Year', 'trx-auto-dealer' ),
					'number',
					array(
						'min' => 1900,
						'max' => (int) gmdate( 'Y' ) + 2,
					),
				),
				array( '_trx_ad_trim', __( 'Trim', 'trx-auto-dealer' ), 'text', array() ),
				array( '_trx_ad_registration_date', __( 'Registration date', 'trx-auto-dealer' ), 'date', array() ),
			),
			'Drivetrain'     => array(
				array(
					'_trx_ad_engine_size',
					__( 'Engine size (L)', 'trx-auto-dealer' ),
					'number',
					array(
						'min'  => 0,
						'step' => '0.1',
					),
				),
				array( '_trx_ad_cylinders', __( 'Cylinders', 'trx-auto-dealer' ), 'number', array( 'min' => 0 ) ),
				array( '_trx_ad_horsepower', __( 'Horsepower (hp)', 'trx-auto-dealer' ), 'number', array( 'min' => 0 ) ),
				array( '_trx_ad_torque_nm', __( 'Torque (Nm)', 'trx-auto-dealer' ), 'number', array( 'min' => 0 ) ),
				array(
					'_trx_ad_fuel_economy_city',
					__( 'Fuel economy: city', 'trx-auto-dealer' ),
					'number',
					array(
						'min'  => 0,
						'step' => '0.1',
					),
				),
				array(
					'_trx_ad_fuel_economy_hwy',
					__( 'Fuel economy: highway', 'trx-auto-dealer' ),
					'number',
					array(
						'min'  => 0,
						'step' => '0.1',
					),
				),
				array(
					'_trx_ad_fuel_economy_combined',
					__( 'Fuel economy: combined', 'trx-auto-dealer' ),
					'number',
					array(
						'min'  => 0,
						'step' => '0.1',
					),
				),
				array( '_trx_ad_co2_emissions', __( 'CO2 emissions (g/km)', 'trx-auto-dealer' ), 'number', array( 'min' => 0 ) ),
			),
			'EV'             => array(
				array( '_trx_ad_ev_range_km', __( 'EV range (km)', 'trx-auto-dealer' ), 'number', array( 'min' => 0 ) ),
				array(
					'_trx_ad_ev_battery_kwh',
					__( 'Battery (kWh)', 'trx-auto-dealer' ),
					'number',
					array(
						'min'  => 0,
						'step' => '0.1',
					),
				),
				array( '_trx_ad_ev_charging_type', __( 'Charging type', 'trx-auto-dealer' ), 'text', array() ),
				array( '_trx_ad_ev_charge_time_min', __( 'Charge time (min)', 'trx-auto-dealer' ), 'number', array( 'min' => 0 ) ),
			),
			'Dimensions'     => array(
				array(
					'_trx_ad_doors',
					__( 'Doors', 'trx-auto-dealer' ),
					'number',
					array(
						'min' => 0,
						'max' => 8,
					),
				),
				array(
					'_trx_ad_seats',
					__( 'Seats', 'trx-auto-dealer' ),
					'number',
					array(
						'min' => 0,
						'max' => 60,
					),
				),
				array( '_trx_ad_color_int', __( 'Interior colour', 'trx-auto-dealer' ), 'text', array() ),
				array( '_trx_ad_weight_kg', __( 'Weight (kg)', 'trx-auto-dealer' ), 'number', array( 'min' => 0 ) ),
				array( '_trx_ad_cargo_volume_l', __( 'Cargo volume (L)', 'trx-auto-dealer' ), 'number', array( 'min' => 0 ) ),
				array( '_trx_ad_engine_hours', __( 'Engine hours', 'trx-auto-dealer' ), 'number', array( 'min' => 0 ) ),
				array( '_trx_ad_hull_material', __( 'Hull material', 'trx-auto-dealer' ), 'text', array() ),
			),
			'History'        => array(
				array( '_trx_ad_mileage', __( 'Mileage', 'trx-auto-dealer' ), 'number', array( 'min' => 0 ) ),
				array( '_trx_ad_prev_owners', __( 'Previous owners', 'trx-auto-dealer' ), 'number', array( 'min' => 0 ) ),
				array( '_trx_ad_accident_free', __( 'Accident-free', 'trx-auto-dealer' ), 'checkbox', array() ),
				array( '_trx_ad_warranty_expiry', __( 'Warranty expiry', 'trx-auto-dealer' ), 'date', array() ),
			),
		);
	}

	public function render( \WP_Post $post ): void {
		$sections = array(
			'Identification' => __( 'Identification', 'trx-auto-dealer' ),
			'Drivetrain'     => __( 'Drivetrain', 'trx-auto-dealer' ),
			'EV'             => __( 'EV', 'trx-auto-dealer' ),
			'Dimensions'     => __( 'Dimensions', 'trx-auto-dealer' ),
			'History'        => __( 'History', 'trx-auto-dealer' ),
		);

		foreach ( $this->fields() as $sectionKey => $rows ) {
			$label = $sections[ $sectionKey ] ?? $sectionKey;
			?>
			<fieldset class="trx-ad-spec-fieldset" style="margin:0 0 18px;padding:12px 16px;border:1px solid #dcdcde;border-radius:4px;">
				<legend style="padding:0 6px;font-weight:600;">
					<?php echo esc_html( $label ); ?>
				</legend>
				<table class="form-table" style="margin:0;">
					<?php foreach ( $rows as $row ) : ?>
						<?php $this->renderRow( $post->ID, $row ); ?>
					<?php endforeach; ?>
				</table>
			</fieldset>
			<?php
		}
	}

	/**
	 * @param array{0:string,1:string,2:string,3:array<string,mixed>} $row
	 */
	private function renderRow( int $postId, array $row ): void {
		[ $metaKey, $label, $type, $attrs ] = $row;
		$value                              = $this->metaOrSpec( $postId, $metaKey );
		$id                                 = 'tr_' . ltrim( $metaKey, '_' );
		?>
		<tr>
			<th scope="row">
				<label for="<?php echo esc_attr( $id ); ?>"><?php echo esc_html( $label ); ?></label>
			</th>
			<td>
				<?php
				if ( 'select' === $type ) {
					$options = isset( $attrs['options'] ) && is_array( $attrs['options'] ) ? $attrs['options'] : array();
					echo '<select id="' . esc_attr( $id ) . '" name="' . esc_attr( $metaKey ) . '" class="regular-text">';
					echo '<option value="">' . esc_html__( '-- Select --', 'trx-auto-dealer' ) . '</option>';
					foreach ( $options as $opt => $optLabel ) {
						printf(
							'<option value="%1$s" %2$s>%3$s</option>',
							esc_attr( (string) $opt ),
							selected( $value, (string) $opt, false ),
							esc_html( (string) $optLabel )
						);
					}
					echo '</select>';
				} elseif ( 'checkbox' === $type ) {
					printf(
						'<label><input type="checkbox" id="%1$s" name="%2$s" value="1" %3$s /> %4$s</label>',
						esc_attr( $id ),
						esc_attr( $metaKey ),
						checked( $value, '1', false ),
						esc_html__( 'Yes', 'trx-auto-dealer' )
					);
				} else {
					$inputType  = in_array( $type, array( 'number', 'date', 'text' ), true ) ? $type : 'text';
					$input_html = sprintf(
						'<input type="%1$s" id="%2$s" name="%3$s" value="%4$s" class="regular-text"',
						esc_attr( $inputType ),
						esc_attr( $id ),
						esc_attr( $metaKey ),
						esc_attr( $value )
					);
					foreach ( array( 'min', 'max', 'step', 'maxlength', 'pattern' ) as $a ) {
						if ( isset( $attrs[ $a ] ) ) {
							$input_html .= ' ' . $a . '="' . esc_attr( (string) $attrs[ $a ] ) . '"';
						}
					}
					$input_html .= ' />';
					echo wp_kses( $input_html, \ThemeREX\AutoDealer\allowedHtml() );
				}
				?>
			</td>
		</tr>
		<?php
	}

	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;
		}

		// Submission marker — present whenever the Specifications panel renders.
		// Without it, the "no value posted" path would erase data on saves
		// triggered by other contexts (Gutenberg block editor, REST, etc.).
		if ( ! isset( $_POST['_trx_ad_specs_panel'] ) ) {
			$any = false;
			foreach ( $this->fields() as $rows ) {
				foreach ( $rows as $row ) {
					if ( array_key_exists( $row[0], $_POST ) ) {
						$any = true;
						break 2; }
				}
			}
			if ( ! $any ) {
				return;
			}
		}

		foreach ( $this->fields() as $rows ) {
			foreach ( $rows as $row ) {
				[ $metaKey, , $type ] = $row;

				if ( 'checkbox' === $type ) {
					$value = ! empty( $_POST[ $metaKey ] ) ? '1' : '';
				} else {
					$raw   = isset( $_POST[ $metaKey ] ) ? sanitize_text_field( wp_unslash( (string) $_POST[ $metaKey ] ) ) : '';
					$value = $raw;
				}

				if ( '' !== $value ) {
					update_post_meta( $postId, $metaKey, $value );
				} else {
					delete_post_meta( $postId, $metaKey );
				}
			}
		}
	}
}
