<?php
/**
 * Dealer meta boxes for the edit screen.
 *
 * Registers contact info, address, working hours, and location fields.
 *
 * @package ThemeREX\AutoDealer
 */

declare(strict_types=1);

namespace ThemeREX\AutoDealer\Admin;

defined( 'ABSPATH' ) || exit;
class DealerMetaBox {

	/**
	 * Dealer post type slug.
	 *
	 * @var string
	 */
	private const POST_TYPE = 'trx_ad_dealer';

	/**
	 * Nonce action.
	 *
	 * @var string
	 */
	private const NONCE_ACTION = 'trx_ad_dealer_meta_save';

	/**
	 * Nonce field name.
	 *
	 * @var string
	 */
	private const NONCE_FIELD = '_trx_ad_dealer_nonce';

	/**
	 * Meta key prefix.
	 *
	 * @var string
	 */
	private const META_PREFIX = '_trx_ad_';

	/**
	 * Register hooks.
	 *
	 * @return void
	 */
	public function register(): void {
		add_action( 'add_meta_boxes_' . self::POST_TYPE, array( $this, 'addMetaBoxes' ) );
		add_action( 'save_post_' . self::POST_TYPE, array( $this, 'save' ), 10, 1 );
	}

	/**
	 * Register meta boxes.
	 *
	 * @return void
	 */
	public function addMetaBoxes(): void {
		add_meta_box(
			'trx_ad_dealer_contact',
			__( 'Contact Information', 'trx-auto-dealer' ),
			array( $this, 'renderContact' ),
			self::POST_TYPE,
			'normal',
			'high'
		);

		add_meta_box(
			'trx_ad_dealer_address',
			__( 'Address', 'trx-auto-dealer' ),
			array( $this, 'renderAddress' ),
			self::POST_TYPE,
			'normal',
			'high'
		);

		add_meta_box(
			'trx_ad_dealer_hours',
			__( 'Working Hours', 'trx-auto-dealer' ),
			array( $this, 'renderHours' ),
			self::POST_TYPE,
			'normal',
			'default'
		);

		add_meta_box(
			'trx_ad_dealer_location',
			__( 'Map Location', 'trx-auto-dealer' ),
			array( $this, 'renderLocation' ),
			self::POST_TYPE,
			'side',
			'default'
		);
	}

	/**
	 * Get a meta value.
	 *
	 * @param int    $postId Post ID.
	 * @param string $key    Meta key (without prefix).
	 * @return string
	 */
	private function getMeta( int $postId, string $key ): string {
		$value = get_post_meta( $postId, self::META_PREFIX . $key, true );
		return is_string( $value ) ? $value : '';
	}

	/**
	 * Render a text input as a grid cell.
	 *
	 * @param string $name  Field name (without prefix).
	 * @param string $label Label.
	 * @param string $value Current value.
	 * @param string $type  Input type.
	 * @param string $desc  Description.
	 * @param string $size  Cell size: 'full' (100%) or 'half' (50%). Default 'half'.
	 * @return void
	 */
	private function renderField( string $name, string $label, string $value, string $type = 'text', string $desc = '', string $size = 'half' ): void {
		$fullName  = self::META_PREFIX . $name;
		$sizeClass = 'full' === $size ? 'trx-ad-dealer-cell--full' : 'trx-ad-dealer-cell--half';

		printf(
			'<div class="trx-ad-dealer-cell %1$s">'
			. '<label for="%2$s">%3$s</label>'
			. '<input type="%4$s" id="%2$s" name="%2$s" value="%5$s" class="widefat">',
			esc_attr( $sizeClass ),
			esc_attr( $fullName ),
			esc_html( $label ),
			esc_attr( $type ),
			esc_attr( $value )
		);

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

		echo '</div>';
	}

	/**
	 * Render Contact Information meta box.
	 *
	 * @param \WP_Post $post Post object.
	 * @return void
	 */
	public function renderContact( \WP_Post $post ): void {
		wp_nonce_field( self::NONCE_ACTION, self::NONCE_FIELD );

		echo '<div class="trx-ad-dealer-grid">';

		$this->renderField(
			'phone',
			__( 'Phone Number', 'trx-auto-dealer' ),
			$this->getMeta( $post->ID, 'phone' ),
			'tel'
		);

		$this->renderField(
			'email',
			__( 'Email Address', 'trx-auto-dealer' ),
			$this->getMeta( $post->ID, 'email' ),
			'email'
		);

		$this->renderField(
			'website',
			__( 'Website', 'trx-auto-dealer' ),
			$this->getMeta( $post->ID, 'website' ),
			'url'
		);

		$this->renderField(
			'whatsapp',
			__( 'WhatsApp Number', 'trx-auto-dealer' ),
			$this->getMeta( $post->ID, 'whatsapp' ),
			'tel',
			__( 'E.164 format, e.g. +15551234567', 'trx-auto-dealer' )
		);

		echo '</div>';
	}

	/**
	 * Render Address meta box.
	 *
	 * @param \WP_Post $post Post object.
	 * @return void
	 */
	public function renderAddress( \WP_Post $post ): void {
		echo '<div class="trx-ad-dealer-grid">';

		$this->renderField(
			'street_address',
			__( 'Street Address', 'trx-auto-dealer' ),
			$this->getMeta( $post->ID, 'street_address' ),
			'text',
			'',
			'full'
		);

		$this->renderField(
			'city',
			__( 'City', 'trx-auto-dealer' ),
			$this->getMeta( $post->ID, 'city' )
		);

		$this->renderField(
			'state',
			__( 'State / Province', 'trx-auto-dealer' ),
			$this->getMeta( $post->ID, 'state' )
		);

		$this->renderField(
			'postcode',
			__( 'Postcode / ZIP', 'trx-auto-dealer' ),
			$this->getMeta( $post->ID, 'postcode' )
		);

		$this->renderField(
			'country',
			__( 'Country', 'trx-auto-dealer' ),
			$this->getMeta( $post->ID, 'country' )
		);

		echo '</div>';
	}

	/**
	 * Render Working Hours meta box.
	 *
	 * @param \WP_Post $post Post object.
	 * @return void
	 */
	public function renderHours( \WP_Post $post ): void {
		$hours = $this->getMeta( $post->ID, 'working_hours' );

		printf(
			'<div class="trx-ad-dealer-grid">'
			. '<div class="trx-ad-dealer-cell trx-ad-dealer-cell--full">'
			. '<label for="%1$s">%2$s</label>'
			. '<textarea id="%1$s" name="%1$s" class="widefat" rows="7" placeholder="%4$s">%3$s</textarea>'
			. '<span class="description">%4$s</span>'
			. '</div>'
			. '</div>',
			esc_attr( self::META_PREFIX . 'working_hours' ),
			esc_html__( 'Working Hours', 'trx-auto-dealer' ),
			esc_textarea( $hours ),
			esc_html__( 'One line per day, e.g. "Monday: 9:00 AM - 6:00 PM"', 'trx-auto-dealer' )
		);
	}

	/**
	 * Render Map Location meta box.
	 *
	 * @param \WP_Post $post Post object.
	 * @return void
	 */
	public function renderLocation( \WP_Post $post ): void {
		// Side meta box (narrow); render fields full-width within the side column.
		echo '<div class="trx-ad-dealer-grid">';

		$this->renderField(
			'lat',
			__( 'Latitude', 'trx-auto-dealer' ),
			$this->getMeta( $post->ID, 'lat' ),
			'text',
			__( 'e.g. 40.7128', 'trx-auto-dealer' ),
			'full'
		);

		$this->renderField(
			'lng',
			__( 'Longitude', 'trx-auto-dealer' ),
			$this->getMeta( $post->ID, 'lng' ),
			'text',
			__( 'e.g. -74.0060', 'trx-auto-dealer' ),
			'full'
		);

		echo '</div>';
	}

	/**
	 * Save dealer meta box data.
	 *
	 * @param int $postId Post ID.
	 * @return void
	 */
	public function save( int $postId ): void {
		// Verify nonce.
		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;
		}

		if ( wp_is_post_revision( $postId ) ) {
			return;
		}

		// Text fields.
		$textFields = array(
			'phone',
			'street_address',
			'city',
			'state',
			'postcode',
			'country',
		);

		foreach ( $textFields as $field ) {
			$key = self::META_PREFIX . $field;
			if ( isset( $_POST[ $key ] ) ) {
				$value = sanitize_text_field( wp_unslash( (string) $_POST[ $key ] ) );
				update_post_meta( $postId, $key, $value );
			}
		}

		// Email field.
		$emailKey = self::META_PREFIX . 'email';
		if ( isset( $_POST[ $emailKey ] ) ) {
			$email = sanitize_email( wp_unslash( (string) $_POST[ $emailKey ] ) );
			update_post_meta( $postId, $emailKey, $email );
		}

		// URL field.
		$websiteKey = self::META_PREFIX . 'website';
		if ( isset( $_POST[ $websiteKey ] ) ) {
			$website = esc_url_raw( wp_unslash( (string) $_POST[ $websiteKey ] ) );
			update_post_meta( $postId, $websiteKey, $website );
		}

		// WhatsApp — normalise to E.164, then validate.
		$whatsappKey = self::META_PREFIX . 'whatsapp';
		if ( isset( $_POST[ $whatsappKey ] ) ) {
			$whatsapp = sanitize_text_field( wp_unslash( (string) $_POST[ $whatsappKey ] ) );
			if ( '' !== $whatsapp ) {
				// Be lenient about how the number is typed — people paste spaces,
				// dashes, dots, parentheses, and sometimes omit the leading "+".
				// Normalise to E.164 (optional "+", digits only) BEFORE validating
				// instead of silently discarding anything that isn't already bare
				// E.164, which wiped reasonable input on save (UAT #11).
				$has_plus = ( '+' === substr( ltrim( $whatsapp ), 0, 1 ) );
				$digits   = (string) preg_replace( '/\D+/', '', $whatsapp );
				$whatsapp = ( '' === $digits ) ? '' : ( $has_plus ? '+' . $digits : $digits );
				// Plausible international number: 7-15 digits (ITU E.164 max 15),
				// with or without the leading "+".
				if ( '' !== $whatsapp && ! preg_match( '/^\+?[1-9]\d{6,14}$/', $whatsapp ) ) {
					$whatsapp = '';
				}
			}
			update_post_meta( $postId, $whatsappKey, $whatsapp );
		}

		// Working hours (textarea, allow newlines).
		$hoursKey = self::META_PREFIX . 'working_hours';
		if ( isset( $_POST[ $hoursKey ] ) ) {
			$hours = sanitize_textarea_field( wp_unslash( (string) $_POST[ $hoursKey ] ) );
			update_post_meta( $postId, $hoursKey, $hours );
		}

		// Lat/Lng — validate as decimal coordinates.
		$latKey = self::META_PREFIX . 'lat';
		if ( isset( $_POST[ $latKey ] ) ) {
			$lat = sanitize_text_field( wp_unslash( (string) $_POST[ $latKey ] ) );
			if ( $lat !== '' && is_numeric( $lat ) ) {
				$latFloat = (float) $lat;
				if ( $latFloat >= -90.0 && $latFloat <= 90.0 ) {
					update_post_meta( $postId, $latKey, $lat );
				}
			} else {
				delete_post_meta( $postId, $latKey );
			}
		}

		$lngKey = self::META_PREFIX . 'lng';
		if ( isset( $_POST[ $lngKey ] ) ) {
			$lng = sanitize_text_field( wp_unslash( (string) $_POST[ $lngKey ] ) );
			if ( $lng !== '' && is_numeric( $lng ) ) {
				$lngFloat = (float) $lng;
				if ( $lngFloat >= -180.0 && $lngFloat <= 180.0 ) {
					update_post_meta( $postId, $lngKey, $lng );
				}
			} else {
				delete_post_meta( $postId, $lngKey );
			}
		}
	}
}
