<?php
/**
 * Rental product: adds a "Rental" tab and fields to the WooCommerce product
 * data metabox, and saves all rental-specific meta on product save.
 *
 * @package WooEquipmentRental
 */

declare( strict_types=1 );

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class WCRent_Rental_Product
 */
class WCRent_Rental_Product {

	// -----------------------------------------------------------------------
	// Initialisation
	// -----------------------------------------------------------------------

	/**
	 * Registers all hooks.
	 */
	public static function init(): void {
		add_filter( 'woocommerce_product_data_tabs', array( self::class, 'add_rental_tab' ) );
		add_action( 'woocommerce_product_data_panels', array( self::class, 'render_rental_panel' ) );
		add_action( 'woocommerce_process_product_meta', array( self::class, 'save_rental_fields' ) );
		add_action( 'admin_enqueue_scripts', array( self::class, 'enqueue_admin_assets' ) );
		add_action( 'woocommerce_before_add_to_cart_button', array( self::class, 'render_date_picker' ) );
		add_filter( 'woocommerce_get_price_html', array( self::class, 'append_per_day_label' ), 10, 2 );
	}

	// -----------------------------------------------------------------------
	// Tab registration
	// -----------------------------------------------------------------------

	/**
	 * Adds the "Rental" tab to the product data metabox.
	 *
	 * @param array<string, array<string, string>> $tabs Existing tabs.
	 * @return array<string, array<string, string>>
	 */
	public static function add_rental_tab( array $tabs ): array {
		$tabs['wcrent_rental'] = array(
			'label'    => __( 'Rental', 'harbor-equipment-rental-for-woocommerce' ),
			'target'   => 'wcrent_rental_product_data',
			'class'    => array( 'show_if_simple' ),
			'priority' => 75,
		);

		return $tabs;
	}

	// -----------------------------------------------------------------------
	// Panel render
	// -----------------------------------------------------------------------

	/**
	 * Renders the "Rental" panel HTML inside the product data metabox.
	 */
	public static function render_rental_panel(): void {
		global $post;

		if ( ! $post instanceof WP_Post ) {
			return;
		}

		$product_id = (int) $post->ID;

		$rental_enabled = get_post_meta( $product_id, '_rental_enabled', true );
		$price_day      = get_post_meta( $product_id, '_rental_price_day', true );
		$price_hour     = get_post_meta( $product_id, '_rental_price_hour', true );
		$price_week     = get_post_meta( $product_id, '_rental_price_week', true );
		$min_days       = get_post_meta( $product_id, '_rental_min_days', true );
		$max_days       = get_post_meta( $product_id, '_rental_max_days', true );
		$buffer_hours   = get_post_meta( $product_id, '_rental_buffer_hours', true );
		$inventory_qty  = get_post_meta( $product_id, '_rental_inventory_qty', true );

		?>
		<div id="wcrent_rental_product_data" class="panel woocommerce_options_panel">

			<div class="options_group">
				<p class="form-field">
					<label for="_rental_enabled">
						<?php esc_html_e( 'Enable rental', 'harbor-equipment-rental-for-woocommerce' ); ?>
					</label>
					<input
						type="checkbox"
						name="_rental_enabled"
						id="_rental_enabled"
						value="yes"
						<?php checked( $rental_enabled, 'yes' ); ?>
					/>
					<span class="description">
						<?php esc_html_e( 'Allow customers to rent this product for a defined period.', 'harbor-equipment-rental-for-woocommerce' ); ?>
					</span>
				</p>
			</div>

			<div class="options_group wcrent-fields">

				<?php
				// Price per day.
				woocommerce_wp_text_input(
					array(
						'id'                => '_rental_price_day',
						'value'             => $price_day,
						'label'             => __( 'Price per day', 'harbor-equipment-rental-for-woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')',
						'placeholder'       => '0.00',
						'desc_tip'          => true,
						'description'       => __( 'Daily rental rate. Used to calculate the total for day-based rentals.', 'harbor-equipment-rental-for-woocommerce' ),
						'type'              => 'number',
						'custom_attributes' => array(
							'step' => '0.01',
							'min'  => '0',
						),
					)
				);

				// Price per hour.
				woocommerce_wp_text_input(
					array(
						'id'                => '_rental_price_hour',
						'value'             => $price_hour,
						'label'             => __( 'Price per hour', 'harbor-equipment-rental-for-woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')',
						'placeholder'       => '0.00',
						'desc_tip'          => true,
						'description'       => __( 'Hourly rental rate. Leave blank if you only offer daily or weekly pricing.', 'harbor-equipment-rental-for-woocommerce' ),
						'type'              => 'number',
						'custom_attributes' => array(
							'step' => '0.01',
							'min'  => '0',
						),
					)
				);

				// Price per week.
				woocommerce_wp_text_input(
					array(
						'id'                => '_rental_price_week',
						'value'             => $price_week,
						'label'             => __( 'Price per week', 'harbor-equipment-rental-for-woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')',
						'placeholder'       => '0.00',
						'desc_tip'          => true,
						'description'       => __( 'Weekly rental rate. Leave blank if you only offer daily or hourly pricing.', 'harbor-equipment-rental-for-woocommerce' ),
						'type'              => 'number',
						'custom_attributes' => array(
							'step' => '0.01',
							'min'  => '0',
						),
					)
				);
				?>

			</div>

			<div class="options_group wcrent-fields">

				<?php
				// Minimum rental period.
				woocommerce_wp_text_input(
					array(
						'id'                => '_rental_min_days',
						'value'             => $min_days,
						'label'             => __( 'Minimum rental period (days)', 'harbor-equipment-rental-for-woocommerce' ),
						'placeholder'       => '1',
						'desc_tip'          => true,
						'description'       => __( 'Customers must rent for at least this many days.', 'harbor-equipment-rental-for-woocommerce' ),
						'type'              => 'number',
						'custom_attributes' => array(
							'step' => '1',
							'min'  => '1',
						),
					)
				);

				// Maximum rental period.
				woocommerce_wp_text_input(
					array(
						'id'                => '_rental_max_days',
						'value'             => $max_days,
						'label'             => __( 'Maximum rental period (days)', 'harbor-equipment-rental-for-woocommerce' ),
						'placeholder'       => '',
						'desc_tip'          => true,
						'description'       => __( 'Leave blank for no maximum. Customers cannot rent beyond this many days.', 'harbor-equipment-rental-for-woocommerce' ),
						'type'              => 'number',
						'custom_attributes' => array(
							'step' => '1',
							'min'  => '1',
						),
					)
				);

				// Buffer hours.
				woocommerce_wp_text_input(
					array(
						'id'                => '_rental_buffer_hours',
						'value'             => $buffer_hours,
						'label'             => __( 'Buffer between rentals (hours)', 'harbor-equipment-rental-for-woocommerce' ),
						'placeholder'       => '0',
						'desc_tip'          => true,
						'description'       => __( 'Hours to block between one rental ending and the next starting. Useful for cleaning or transit time.', 'harbor-equipment-rental-for-woocommerce' ),
						'type'              => 'number',
						'custom_attributes' => array(
							'step' => '1',
							'min'  => '0',
						),
					)
				);

				// Inventory quantity.
				woocommerce_wp_text_input(
					array(
						'id'                => '_rental_inventory_qty',
						'value'             => $inventory_qty,
						'label'             => __( 'Rental inventory units', 'harbor-equipment-rental-for-woocommerce' ),
						'placeholder'       => '1',
						'desc_tip'          => true,
						'description'       => __( 'Total number of units available to rent simultaneously (e.g., 5 bikes).', 'harbor-equipment-rental-for-woocommerce' ),
						'type'              => 'number',
						'custom_attributes' => array(
							'step' => '1',
							'min'  => '1',
						),
					)
				);
				?>

			</div>

			<?php
			/**
			 * Renders additional rental fields inside the Rental product panel.
			 *
			 * @param int $product_id Product post ID.
			 */
			do_action( 'wcrent_product_panel_fields', $product_id );
			?>

			<?php wp_nonce_field( 'wcrent_save_product_meta', 'wcrent_product_nonce' ); ?>

		</div>
		<?php
	}

	// -----------------------------------------------------------------------
	// Save
	// -----------------------------------------------------------------------

	/**
	 * Saves all rental fields when a product is saved.
	 *
	 * @param int $product_id Product post ID.
	 */
	public static function save_rental_fields( int $product_id ): void {
		// Nonce check.
		if ( ! isset( $_POST['wcrent_product_nonce'] )
			|| ! wp_verify_nonce(
				sanitize_text_field( wp_unslash( $_POST['wcrent_product_nonce'] ) ),
				'wcrent_save_product_meta'
			)
		) {
			return;
		}

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

		$enabled = isset( $_POST['_rental_enabled'] ) ? 'yes' : 'no';
		update_post_meta( $product_id, '_rental_enabled', $enabled );

		$float_fields = array(
			'_rental_price_day',
			'_rental_price_hour',
			'_rental_price_week',
		);

		foreach ( $float_fields as $field ) {
			if ( isset( $_POST[ $field ] ) && '' !== $_POST[ $field ] ) {
				update_post_meta(
					$product_id,
					$field,
					wc_format_decimal( sanitize_text_field( wp_unslash( $_POST[ $field ] ) ) )
				);
			} else {
				delete_post_meta( $product_id, $field );
			}
		}

		$int_fields = array(
			'_rental_min_days',
			'_rental_max_days',
			'_rental_buffer_hours',
			'_rental_inventory_qty',
		);

		foreach ( $int_fields as $field ) {
			if ( isset( $_POST[ $field ] ) && '' !== $_POST[ $field ] ) {
				update_post_meta( $product_id, $field, absint( wp_unslash( $_POST[ $field ] ) ) );
			} else {
				delete_post_meta( $product_id, $field );
			}
		}

		/**
		 * Saves additional rental fields registered via wcrent_product_panel_fields.
		 *
		 * Fires inside the nonce- and capability-checked save path.
		 *
		 * @param int $product_id Product post ID.
		 */
		do_action( 'wcrent_save_product_fields', $product_id );

		WCRent_Rental_Availability::clear_product_cache( $product_id );
	}

	// -----------------------------------------------------------------------
	// Admin assets
	// -----------------------------------------------------------------------

	/**
	 * Enqueues admin JS/CSS on the product edit page.
	 *
	 * @param string $hook Current admin page hook.
	 */
	public static function enqueue_admin_assets( string $hook ): void {
		if ( ! in_array( $hook, array( 'post.php', 'post-new.php' ), true ) ) {
			return;
		}

		$screen = get_current_screen();
		if ( ! $screen || 'product' !== $screen->post_type ) {
			return;
		}

		wp_enqueue_style(
			'wcrent-admin',
			WCRENT_PLUGIN_URL . 'assets/admin-rental.css',
			array(),
			WCRENT_VERSION
		);

		wp_enqueue_script(
			'wcrent-admin',
			WCRENT_PLUGIN_URL . 'assets/admin-rental.js',
			array( 'jquery' ),
			WCRENT_VERSION,
			true
		);

		wp_localize_script(
			'wcrent-admin',
			'wcRentAdmin',
			array(
				'i18n' => array(
					'priceRequired' => __( 'Equipment Rental: Please set at least one rental price (per day, per hour, or per week) before publishing this rental product.', 'harbor-equipment-rental-for-woocommerce' ),
				),
			)
		);
	}

	// -----------------------------------------------------------------------
	// Frontend date picker
	// -----------------------------------------------------------------------

	/**
	 * Renders the rental date picker and hidden inputs inside the
	 * WooCommerce add-to-cart form, directly before the submit button.
	 *
	 * Only outputs for rental-enabled products on single product pages.
	 */
	public static function render_date_picker(): void {
		if ( ! is_product() ) {
			return;
		}

		global $post;

		$product_id = (int) $post->ID;

		if ( ! WCRent_Utils::is_rental_product( $product_id ) ) {
			return;
		}

		$min_days = (int) get_post_meta( $product_id, '_rental_min_days', true );
		$max_days = (int) get_post_meta( $product_id, '_rental_max_days', true );

		?>
		<div class="wcrent-date-picker-wrapper">

			<label class="wcrent-label" for="wcrent-date-range-alt">
				<?php esc_html_e( 'Select rental dates', 'harbor-equipment-rental-for-woocommerce' ); ?>
				<?php if ( $min_days > 0 ) : ?>
					<span class="wcrent-min-days-note" id="wcrent-min-days-note">
						<?php
						printf(
							esc_html(
								/* translators: %d: minimum rental days */
								_n(
									'(minimum %d day)',
									'(minimum %d days)',
									$min_days,
									'harbor-equipment-rental-for-woocommerce'
								)
							),
							(int) $min_days
						);
						?>
					</span>
				<?php endif; ?>
			</label>

			<input
				type="text"
				id="wcrent-date-range"
				class="wcrent-date-input"
				placeholder="<?php esc_attr_e( 'Start date — End date', 'harbor-equipment-rental-for-woocommerce' ); ?>"
				readonly="readonly"
				autocomplete="off"
			/>

			<p class="wcrent-availability-note">
				<?php esc_html_e( 'Greyed-out dates are unavailable.', 'harbor-equipment-rental-for-woocommerce' ); ?>
			</p>

			<div class="wcrent-rental-summary wcrent-visually-hidden" aria-live="polite" aria-atomic="true">
				<span class="wcrent-summary-text"></span>
			</div>

			<div class="wcrent-error" id="wcrent-error" aria-live="assertive" aria-atomic="true"></div>

			<?php
			$price_hour = (float) get_post_meta( $product_id, '_rental_price_hour', true );
			if ( $price_hour > 0 ) :
				?>
			<div
				class="wcrent-time-picker-wrapper"
				id="wcrent-time-picker"
				aria-hidden="true"
				style="display:none"
			>
				<div class="wcrent-time-row">
					<label class="wcrent-label wcrent-time-label" for="wcrent-start-time">
						<?php esc_html_e( 'Start time', 'harbor-equipment-rental-for-woocommerce' ); ?>
					</label>
					<input
						type="time"
						id="wcrent-start-time"
						name="rental_start_time"
						class="wcrent-time-input"
						step="900"
					/>
				</div>
				<div class="wcrent-time-row">
					<label class="wcrent-label wcrent-time-label" for="wcrent-end-time">
						<?php esc_html_e( 'End time', 'harbor-equipment-rental-for-woocommerce' ); ?>
					</label>
					<input
						type="time"
						id="wcrent-end-time"
						name="rental_end_time"
						class="wcrent-time-input"
						step="900"
					/>
				</div>
			</div>
			<?php endif; ?>

			<?php wp_nonce_field( 'wcrent_add_rental', 'wcrent_nonce' ); ?>
			<input type="hidden" name="rental_start" id="wcrent-rental-start" value="" />
			<input type="hidden" name="rental_end"   id="wcrent-rental-end"   value="" />
			<input type="hidden" name="rental_days"  id="wcrent-rental-days"  value="" />

		</div>
		<?php
	}

	// -----------------------------------------------------------------------
	// Price label
	// -----------------------------------------------------------------------

	/**
	 * Appends a /day label to the price HTML for rental-enabled products.
	 *
	 * @param string     $price_html Existing price HTML.
	 * @param WC_Product $product    WooCommerce product object.
	 * @return string
	 */
	public static function append_per_day_label( string $price_html, WC_Product $product ): string {
		$product_id = $product->get_id();
		if ( ! WCRent_Utils::is_rental_product( $product_id ) ) {
			return $price_html;
		}

		$price_day  = (float) get_post_meta( $product_id, '_rental_price_day', true );
		$price_week = (float) get_post_meta( $product_id, '_rental_price_week', true );
		$price_hour = (float) get_post_meta( $product_id, '_rental_price_hour', true );

		if ( $price_day > 0 && $price_week > 0 ) {
			/* translators: price-per-period label showing both daily and weekly rates */
			$aria_suffix = __( 'per day or per week', 'harbor-equipment-rental-for-woocommerce' );
			$suffix_html = '<span class="wcrent-per-day" aria-hidden="true"> '
				. esc_html__( 'from', 'harbor-equipment-rental-for-woocommerce' ) . ' / '
				. esc_html__( 'day', 'harbor-equipment-rental-for-woocommerce' )
				. ' &middot; ' . wc_price( $price_week ) . ' / '
				. esc_html__( 'week', 'harbor-equipment-rental-for-woocommerce' )
				. '</span>';
		} elseif ( $price_day > 0 ) {
			/* translators: price-per-period suffix shown after a currency amount, e.g. "/ day" */
			$aria_suffix = __( 'per day', 'harbor-equipment-rental-for-woocommerce' );
			$suffix_html = '<span class="wcrent-per-day" aria-hidden="true"> / ' . esc_html__( 'day', 'harbor-equipment-rental-for-woocommerce' ) . '</span>';
		} elseif ( $price_hour > 0 ) {
			/* translators: price-per-period suffix shown after a currency amount, e.g. "/ hour" */
			$aria_suffix = __( 'per hour', 'harbor-equipment-rental-for-woocommerce' );
			$suffix_html = '<span class="wcrent-per-day" aria-hidden="true"> / ' . esc_html__( 'hour', 'harbor-equipment-rental-for-woocommerce' ) . '</span>';
		} else {
			return $price_html;
		}

		return '<span class="wcrent-price-with-unit" aria-label="'
			. esc_attr( wp_strip_all_tags( $price_html ) . ' ' . $aria_suffix )
			. '">'
			. $price_html
			. $suffix_html
			. '</span>';
	}
}
