<?php
/**
 * Renders and saves user-defined custom meta fields on the vehicle edit screen.
 *
 * Field definitions are stored in the trx_ad_custom_fields option
 * (managed via Vehicles > Settings > Meta Fields).
 * Values are stored as post meta with the _trx_ad_cf_ prefix.
 *
 * @package ThemeREX\AutoDealer
 */

declare(strict_types=1);

namespace ThemeREX\AutoDealer\Admin;

defined( 'ABSPATH' ) || exit;
use ThemeREX\AutoDealer\PostTypes\VehiclePostType;

class CustomFieldMetaBox {

	/**
	 * Post meta key prefix for custom field values.
	 */
	public const META_PREFIX = '_trx_ad_cf_';

	/**
	 * Nonce action.
	 */
	private const NONCE_ACTION = 'trx_ad_cf_save';

	/**
	 * Nonce field name.
	 */
	private const NONCE_FIELD = '_trx_ad_cf_nonce';

	/**
	 * Register hooks.
	 */
	public function register(): void {
		add_action( 'add_meta_boxes_' . VehiclePostType::POST_TYPE, array( $this, 'addMetaBoxes' ) );
		add_action( 'save_post_' . VehiclePostType::POST_TYPE, array( $this, 'save' ), 15 );
	}

	/**
	 * Add meta boxes — one per group, or a single box if no groups are defined.
	 */
	public function addMetaBoxes(): void {
		$fields = AdminSettings::getCustomFields();
		if ( empty( $fields ) ) {
			return;
		}

		$groups = $this->groupFields( $fields );

		foreach ( $groups as $groupName => $groupFields ) {
			$boxId    = 'trx_ad_cf_' . sanitize_key( $groupName );
			$boxTitle = $groupName !== ''
				? $groupName
				: __( 'Custom Fields', 'trx-auto-dealer' );

			add_meta_box(
				$boxId,
				$boxTitle,
				function ( \WP_Post $post ) use ( $groupFields ): void {
					$this->renderFields( $post, $groupFields );
				},
				VehiclePostType::POST_TYPE,
				'normal',
				'default'
			);
		}
	}

	/**
	 * Group fields by their group name.
	 *
	 * @param array<int, array<string,string>> $fields Field definitions.
	 * @return array<string, array<int, array<string,string>>>
	 */
	private function groupFields( array $fields ): array {
		$groups = array();
		foreach ( $fields as $field ) {
			$group              = $field['group'] ?? '';
			$groups[ $group ][] = $field;
		}
		return $groups;
	}

	/**
	 * Render a set of fields inside a meta box.
	 *
	 * @param \WP_Post                         $post   Current post.
	 * @param array<int, array<string,string>> $fields Field definitions.
	 */
	private function renderFields( \WP_Post $post, array $fields ): void {
		wp_nonce_field( self::NONCE_ACTION, self::NONCE_FIELD );

		foreach ( $fields as $field ) {
			$metaKey = self::META_PREFIX . $field['key'];
			$value   = get_post_meta( $post->ID, $metaKey, true );
			$value   = is_string( $value ) ? $value : '';

			$this->renderSingleField( $field, $metaKey, $value );
		}
	}

	/**
	 * Render a single custom field input.
	 *
	 * @param array<string,string> $field   Field definition.
	 * @param string               $metaKey The post meta key.
	 * @param string               $value   Current stored value.
	 */
	private function renderSingleField( array $field, string $metaKey, string $value ): void {
		$label = $field['label'] ?? '';
		$type  = $field['type'] ?? 'text';
		$desc  = $field['description'] ?? '';

		echo '<p>';
		printf( '<label for="%s"><strong>%s</strong></label><br>', esc_attr( $metaKey ), esc_html( $label ) );

		switch ( $type ) {
			case 'textarea':
				printf(
					'<textarea id="%1$s" name="%1$s" class="widefat" rows="3">%2$s</textarea>',
					esc_attr( $metaKey ),
					esc_textarea( $value )
				);
				break;

			case 'select':
				$options = array_map( 'trim', explode( ',', $field['options'] ?? '' ) );
				printf( '<select id="%1$s" name="%1$s" class="widefat">', esc_attr( $metaKey ) );
				echo '<option value="">' . esc_html__( '-- Select --', 'trx-auto-dealer' ) . '</option>';
				foreach ( $options as $opt ) {
					if ( $opt === '' ) {
						continue;
					}
					printf(
						'<option value="%s"%s>%s</option>',
						esc_attr( $opt ),
						selected( $value, $opt, false ),
						esc_html( $opt )
					);
				}
				echo '</select>';
				break;

			case 'checkbox':
				printf(
					'<label><input type="checkbox" id="%1$s" name="%1$s" value="1"%2$s> %3$s</label>',
					esc_attr( $metaKey ),
					checked( $value, '1', false ),
					esc_html__( 'Yes', 'trx-auto-dealer' )
				);
				break;

			default:
				// text, number, date, url
				printf(
					'<input type="%1$s" id="%2$s" name="%2$s" value="%3$s" class="widefat" step="any">',
					esc_attr( $type ),
					esc_attr( $metaKey ),
					esc_attr( $value )
				);
				break;
		}

		if ( $desc !== '' ) {
			printf( '<br><span class="description">%s</span>', esc_html( $desc ) );
		}

		echo '</p>';
	}

	/**
	 * Save custom field values on post save.
	 *
	 * @param int $postId Post ID.
	 */
	public function save( int $postId ): void {
		if (
			! isset( $_POST[ self::NONCE_FIELD ] )
			|| ! wp_verify_nonce(
				sanitize_text_field( wp_unslash( $_POST[ self::NONCE_FIELD ] ) ),
				self::NONCE_ACTION
			)
		) {
			return;
		}

		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}

		if ( ! current_user_can( 'edit_post', $postId ) ) {
			return;
		}

		$fields = AdminSettings::getCustomFields();
		if ( empty( $fields ) ) {
			return;
		}

		foreach ( $fields as $field ) {
			$metaKey = self::META_PREFIX . $field['key'];
			$type    = $field['type'] ?? 'text';

			if ( $type === 'checkbox' ) {
				$value = isset( $_POST[ $metaKey ] ) ? '1' : '0';
			} elseif ( $type === 'url' ) {
				$value = isset( $_POST[ $metaKey ] )
					? esc_url_raw( wp_unslash( (string) $_POST[ $metaKey ] ) )
					: '';
			} else {
				$value = isset( $_POST[ $metaKey ] )
					? sanitize_text_field( wp_unslash( (string) $_POST[ $metaKey ] ) )
					: '';
			}

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