<?php
/**
 * Admin settings: adds a "Rental" tab to WooCommerce -> Settings with global
 * plugin configuration options.
 *
 * @package WooEquipmentRental
 */

declare( strict_types=1 );

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

/**
 * Class WCRent_Admin_Settings
 */
class WCRent_Admin_Settings {

	/**
	 * Settings section ID.
	 */
	private const SECTION_ID = 'wcrent';

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

	/**
	 * Registers WooCommerce settings hooks.
	 */
	public static function init(): void {
		// Register the settings tab.
		add_filter( 'woocommerce_settings_tabs_array', array( self::class, 'add_settings_tab' ), 50 );

		// Render the settings tab content.
		add_action( 'woocommerce_settings_tabs_' . self::SECTION_ID, array( self::class, 'render_settings' ) );

		// Save the settings.
		add_action( 'woocommerce_update_options_' . self::SECTION_ID, array( self::class, 'save_settings' ) );

		// Register the sections within the tab.
		add_filter( 'woocommerce_get_sections_' . self::SECTION_ID, array( self::class, 'get_sections' ) );

		// Settings fields per section.
		add_filter( 'woocommerce_get_settings_' . self::SECTION_ID, array( self::class, 'get_settings' ), 10, 2 );

		// Post-save: flush cache if the checkbox was ticked.
		add_action( 'woocommerce_update_options_' . self::SECTION_ID, array( self::class, 'maybe_flush_cache' ), 20 );

		// Sanitize integer settings so arbitrary values cannot be saved via direct POST.
		foreach ( array( 'wcrent_default_buffer_hours', 'wcrent_default_inventory_qty', 'wcrent_cache_ttl' ) as $_opt ) {
			add_filter( 'woocommerce_admin_settings_sanitize_option_' . $_opt, 'absint', 10, 1 );
		}
		unset( $_opt );
	}

	// -----------------------------------------------------------------------
	// Tab
	// -----------------------------------------------------------------------

	/**
	 * Adds the "Rental" tab to the WooCommerce settings tab array.
	 *
	 * @param array<string, string> $tabs Existing tabs.
	 * @return array<string, string>
	 */
	public static function add_settings_tab( array $tabs ): array {
		$tabs[ self::SECTION_ID ] = __( 'Rental', 'harbor-equipment-rental-for-woocommerce' );

		return $tabs;
	}

	// -----------------------------------------------------------------------
	// Sections
	// -----------------------------------------------------------------------

	/**
	 * Defines sub-sections within the Rental settings tab.
	 *
	 * @param array<string, string> $sections Existing sections.
	 * @return array<string, string>
	 */
	public static function get_sections( array $sections ): array {
		$sections[''] = __( 'General', 'harbor-equipment-rental-for-woocommerce' );

		/**
		 * Filters the Rental settings tab sections so add-on classes can
		 * register their own. Advanced is appended afterwards so it stays last.
		 *
		 * @param array<string, string> $sections Section slug => label.
		 */
		$sections = (array) apply_filters( 'wcrent_settings_sections', $sections );

		$sections['advanced'] = __( 'Advanced', 'harbor-equipment-rental-for-woocommerce' );

		return $sections;
	}

	// -----------------------------------------------------------------------
	// Render / save
	// -----------------------------------------------------------------------

	/**
	 * Renders the settings page using WooCommerce's built-in output helper.
	 */
	public static function render_settings(): void {
		global $current_section;

		WC_Admin_Settings::output_fields( self::section_settings( (string) $current_section ) );
	}

	/**
	 * Saves the settings using WooCommerce's built-in save helper.
	 */
	public static function save_settings(): void {
		global $current_section;

		WC_Admin_Settings::save_fields( self::section_settings( (string) $current_section ) );
	}

	/**
	 * Resolves a section's fields through the full WooCommerce filter chain so
	 * fields registered by add-on classes are rendered and saved too.
	 *
	 * @param string $current_section Active section slug.
	 * @return array<int, array<string, mixed>>
	 */
	private static function section_settings( string $current_section ): array {
		return (array) apply_filters( 'woocommerce_get_settings_' . self::SECTION_ID, array(), $current_section );
	}

	// -----------------------------------------------------------------------
	// Settings definitions
	// -----------------------------------------------------------------------

	/**
	 * Returns the settings fields for the given section.
	 *
	 * @param array<int, array<string, mixed>> $settings        Existing settings (unused, replaced).
	 * @param string                           $current_section Active section slug.
	 * @return array<int, array<string, mixed>>
	 */
	public static function get_settings(
		array $settings,
		string $current_section = ''
	): array {
		switch ( $current_section ) {
			case '':
				return self::general_settings();

			case 'advanced':
				return self::advanced_settings();

			default:
				// Sections registered by add-on classes supply their own fields
				// via this same WooCommerce filter at a later priority.
				return $settings;
		}
	}

	// -----------------------------------------------------------------------
	// Section definitions
	// -----------------------------------------------------------------------

	/**
	 * General settings fields.
	 *
	 * @return array<int, array<string, mixed>>
	 */
	private static function general_settings(): array {
		return array(
			array(
				'title' => __( 'General Rental Settings', 'harbor-equipment-rental-for-woocommerce' ),
				'type'  => 'title',
				'id'    => 'wcrent_general_section',
			),
			array(
				'title'             => __( 'Default buffer hours', 'harbor-equipment-rental-for-woocommerce' ),
				'desc'              => __( 'Hours to block between rentals (cleaning / transit time). Applied to products that have no per-product override.', 'harbor-equipment-rental-for-woocommerce' ),
				'id'                => 'wcrent_default_buffer_hours',
				'default'           => '0',
				'type'              => 'number',
				'css'               => 'width:80px;',
				'custom_attributes' => array(
					'min'  => '0',
					'step' => '1',
				),
				'desc_tip'          => true,
			),
			array(
				'title'             => __( 'Default inventory units', 'harbor-equipment-rental-for-woocommerce' ),
				'desc'              => __( 'Default number of units available to rent simultaneously for new rental products.', 'harbor-equipment-rental-for-woocommerce' ),
				'id'                => 'wcrent_default_inventory_qty',
				'default'           => '1',
				'type'              => 'number',
				'css'               => 'width:80px;',
				'custom_attributes' => array(
					'min'  => '1',
					'step' => '1',
				),
				'desc_tip'          => true,
			),
			array(
				'title'    => __( 'Date format', 'harbor-equipment-rental-for-woocommerce' ),
				'desc'     => __( 'How selected dates are displayed to customers on the product page. Supports Flatpickr format tokens.', 'harbor-equipment-rental-for-woocommerce' ),
				'id'       => 'wcrent_date_format',
				'default'  => 'M j, Y',
				'type'     => 'text',
				'desc_tip' => true,
			),
			array(
				'title'   => __( 'Enable availability check', 'harbor-equipment-rental-for-woocommerce' ),
				'desc'    => __( 'Disable dates already booked in the Flatpickr date picker.', 'harbor-equipment-rental-for-woocommerce' ),
				'id'      => 'wcrent_enable_availability_check',
				'default' => 'yes',
				'type'    => 'checkbox',
			),
			array(
				'title'    => __( 'Billing method', 'harbor-equipment-rental-for-woocommerce' ),
				'desc'     => __( 'How rental days are counted. Calendar days: both pickup and return day are billable (industry standard for equipment). Rental nights: return day is free (hotel convention).', 'harbor-equipment-rental-for-woocommerce' ),
				'id'       => 'wcrent_billing_method',
				'type'     => 'select',
				'default'  => 'calendar_days',
				'options'  => array(
					'calendar_days' => __( 'Calendar days (both pickup and return day billable)', 'harbor-equipment-rental-for-woocommerce' ),
					'rental_nights' => __( 'Rental nights (return day is free)', 'harbor-equipment-rental-for-woocommerce' ),
				),
				'desc_tip' => true,
			),
			array(
				'type' => 'sectionend',
				'id'   => 'wcrent_general_section',
			),
		);
	}

	/**
	 * Advanced settings fields.
	 *
	 * @return array<int, array<string, mixed>>
	 */
	private static function advanced_settings(): array {
		$fields = array(
			array(
				'title' => __( 'Advanced Settings', 'harbor-equipment-rental-for-woocommerce' ),
				'type'  => 'title',
				'id'    => 'wcrent_advanced_section',
			),
			array(
				'title'             => __( 'Transient cache TTL (seconds)', 'harbor-equipment-rental-for-woocommerce' ),
				'desc'              => __( 'How long to cache availability results. Lower = more accurate but more DB queries.', 'harbor-equipment-rental-for-woocommerce' ),
				'id'                => 'wcrent_cache_ttl',
				'default'           => '300',
				'type'              => 'number',
				'css'               => 'width:100px;',
				'custom_attributes' => array(
					'min'  => '0',
					'step' => '1',
				),
				'desc_tip'          => true,
			),
			array(
				'title'   => __( 'Clear availability cache', 'harbor-equipment-rental-for-woocommerce' ),
				'desc'    => __( 'Check this and save to immediately clear all availability transients.', 'harbor-equipment-rental-for-woocommerce' ),
				'id'      => 'wcrent_flush_cache',
				'default' => 'no',
				'type'    => 'checkbox',
			),
		);

		/**
		 * Filters the Advanced section fields before the closing sectionend so
		 * add-on classes can append their own.
		 *
		 * @param array<int, array<string, mixed>> $fields Advanced fields so far.
		 */
		$fields = (array) apply_filters( 'wcrent_advanced_settings_fields', $fields );

		$fields[] = array(
			'type' => 'sectionend',
			'id'   => 'wcrent_advanced_section',
		);

		return $fields;
	}

	// -----------------------------------------------------------------------
	// Cache flush
	// -----------------------------------------------------------------------

	/**
	 * Flushes all availability transients if the flush-cache checkbox was ticked on save.
	 */
	public static function maybe_flush_cache(): void {
		if ( 'yes' === get_option( 'wcrent_flush_cache' ) ) {
			WCRent_Rental_Availability::clear_all_availability_cache();
			// Reset the checkbox so it does not persist as "yes".
			update_option( 'wcrent_flush_cache', 'no' );
		}
	}
}
