<?php
/**
 * Class to handle booking add-on metaboxes.
 */
namespace HBFWC\Admin;

use function HBFWC\HBF_WC;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

/**
 * Class Booking_Addon_Metabox.
 */
class Booking_Addon_Metabox {
	/**
	 * Class init.
	 */
	public static function init() {
		add_action( 'save_post', [ __CLASS__, 'save_addon' ], 10 );
		add_filter( 'manage_booking_addon_posts_columns', [ __CLASS__, 'addon_custom_columns' ] );
		add_action( 'manage_booking_addon_posts_custom_column', [ __CLASS__, 'addon_custom_column_content' ], 10, 2 );
	}

	/**
	 * Register metaboxes.
	 */
	public static function register_metaboxes() {
		add_meta_box(
			'hbfwc_booking_addon_details',
			esc_html__( 'Add-on data', 'hotel-booking-for-woocommerce' ),
			array( __CLASS__, 'render_metabox' ),
			'booking_addon',
			'advanced',
			'high'
		);
	}

	/**
	 * Render the metabox content.
	 *
	 * @param \WP_Post $post The post object.
	 */
	public static function render_metabox( $post ) {
		wp_nonce_field( 'hbfwc_booking_addon_details', 'hbfwc_booking_addon_nonce' );
		
		self::addon_types( $post );
		$metabox = __CLASS__;
		$fields  = self::get_metabox_fields();
		
		include dirname( HBF_WC()->plugin_file ) . '/includes/admin/views/addon-metabox.php';
	}

	/**
	 * Get the value of a post meta field.
	 * @param \WP_Post $post The post object.
	 * @param string   $key  The meta key.
	 * @param string   $default Default value if the meta key does not exist.
	 * @return mixed The value of the meta key or the default value.
	 */
	public static function get_value( $post, $key, $default = '' ) {
		$value = get_post_meta( $post->ID, $key, true );
		return ! empty( $value ) ? $value : $default;
	}

	/**
	 * Add-on data save.
	 * @param int $post_id The post ID.
	 *
	 * @return void
	 */
	public static function save_addon( $post_id ) {
		if ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
			return;
		}

		// Autosaving, bail.
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}

		if ( 'booking_addon' !== get_post_type( $post_id ) ) {
			return;
		}

		if ( ! isset( $_POST['hbfwc_booking_addon_nonce'] ) 
			|| ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['hbfwc_booking_addon_nonce'] ) ), 'hbfwc_booking_addon_details' ) 
		) {
			print esc_html__( 'Invalid nonce specified.', 'hotel-booking-for-woocommerce' );
			exit;
		}

		$fields = self::get_metabox_fields();
		$fields['_addon_type'] = [
			'type' => 'select',
			'default' => 'fixed'
		];

		foreach( $fields as $key => $config ) {
			if ( isset( $_POST[$key] ) ) {
				if ( $config['type'] !== 'woo-select' ) {
					$value = ( 'textarea' === $config['type'] ) ? wp_kses_post( wp_unslash( $_POST[$key] ) ) : sanitize_text_field( wp_unslash( $_POST[$key] ) );
				} else {
					$value = map_deep( wp_unslash( $_POST[$key] ), 'absint' );
				}
				if ( 'price' === $key ) {
					$value = wc_format_decimal( $value, wc_get_price_decimals() );
				}
				update_post_meta( $post_id, $key, $value );
			} else {
				if ( '' === $config['default'] ) {
					delete_post_meta( $post_id, $key );
				} else {
					if ( 'toggle' === $config['type'] && 'yes' === $config['default'] ) {
						update_post_meta( $post_id, $key, 'no' );
					} else {
						update_post_meta( $post_id, $key, $config['default'] );
					}
				}
			}
		}
	}

	/**
	 * Metabox fields.
	 * @return array
	 */
	private static function get_metabox_fields() {
		$fields = [
			'price'   => [
				'label'       => esc_html__( 'Price', 'hotel-booking-for-woocommerce' ),
				'type'        => 'text',
				'default'     => '',
				'description' => '',
				'class'       => 'short wc_input_price'
			],
			'sub_type' => [
				'label'       => esc_html__( 'Sub type', 'hotel-booking-for-woocommerce' ),
				'type'        => 'radio',
				'default'     => 'room',
				'options'     => [
					'room' => [
						'label'       => esc_html__( 'Per Room', 'hotel-booking-for-woocommerce' ),
						'description' => esc_html__( 'Charge this add-on for each booked room.', 'hotel-booking-for-woocommerce' ),
						'disabled'    => false,
						'use_tooltip' => true,
					],
					'book' => [
						'label'       => esc_html__( 'Per Booking', 'hotel-booking-for-woocommerce' ) . ' (Pro)',
						'description' => esc_html__( 'Charge this add-on once per booking, regardless of number of rooms.', 'hotel-booking-for-woocommerce' ),
						'disabled'    => true,
						'use_tooltip' => true,
					],
				],
				'wrapper_class' => 'show_if_fixed',
			],
			'unit'   => [
				'label'       => esc_html__( 'Unit', 'hotel-booking-for-woocommerce' ),
				'type'        => 'text',
				'default'     => '',
				'description' => esc_html__( 'For quantity-based, e.g. \'set\', \'pax\', \'portion\', etc.', 'hotel-booking-for-woocommerce' ),
				'wrapper_class' => 'show_if_quantity_based',
				'class'       => 'short',
				'use_tooltip' => true,
			],
			'min'    => [
				'label'       => esc_html__( 'Min Quantity', 'hotel-booking-for-woocommerce' ),
				'type'        => 'number',
				'default'     => '1',
				'description' => '',
				'wrapper_class' => 'show_if_quantity_based',
			],
			'max'    => [
				'label'       => esc_html__( 'Max Quantity', 'hotel-booking-for-woocommerce' ),
				'type'        => 'number',
				'default'     => '10',
				'description' => '',
				'wrapper_class' => 'show_if_quantity_based',
			],
			'byguests'   => [
				'label'         => esc_html__( 'Multiply by guests', 'hotel-booking-for-woocommerce' ) .  ' (Pro)',
				'type'          => 'toggle',
				'default'       => '',
				'description' => esc_html__( 'If enabled, quantity is based on guest count. (input will be hidden)', 'hotel-booking-for-woocommerce' ),
				'use_tooltip' => true,
				'disabled'    => true,
				'wrapper_class' => 'show_if_quantity_based',
			],
			'bynights'   => [
				'label'         => esc_html__( 'Multiply by nights', 'hotel-booking-for-woocommerce' ) .  ' (Pro)',
				'type'          => 'toggle',
				'default'       => '',
				'description' => esc_html__( 'Multiply the total by number of nights booked.', 'hotel-booking-for-woocommerce' ),
				'use_tooltip' => true,
				'disabled'    => true,
				'wrapper_class' => 'show_if_quantity_based',
			],
			'room_ids' => [
				'label'       => esc_html__( 'Specific Rooms', 'hotel-booking-for-woocommerce' ) . '  (Pro)',
				'type'        => 'text',
				'default'     => '',
				'description' => esc_html__( 'Select which rooms this add-on applies to. Leave empty to apply to all rooms.', 'hotel-booking-for-woocommerce' ),
				'use_tooltip' => true,
				'disabled'    => true,
			],
			'description' => [
				'label'       => esc_html__( 'Description', 'hotel-booking-for-woocommerce' ),
				'type'        => 'textarea',
				'default'     => '',
				'description' => esc_html__( 'Short description of this add-on. Include what\'s included, how it works, or any relevant instructions.', 'hotel-booking-for-woocommerce' ),
			],
			'required' => [
				'label'       => esc_html__( 'Required?', 'hotel-booking-for-woocommerce' ),
				'type'        => 'toggle',
				'default'     => '',
				'description' => esc_html__( 'If enabled, this add-on will be automatically included and cannot be turned off by the customer.', 'hotel-booking-for-woocommerce' ),
				'use_tooltip' => true,
				'wrapper_class' => 'show_if_fixed',
			],
			'active'   => [
				'label'       => esc_html__( 'Active', 'hotel-booking-for-woocommerce' ),
				'type'        => 'toggle',
				'default'     => 'yes',
				'description' => '',
			],
			'priority'   => [
				'label'       => esc_html__( 'Priority', 'hotel-booking-for-woocommerce' ),
				'type'        => 'number',
				'default'     => '10',
				'description' => '',
			],
		];

		return apply_filters( 'hbfwc_booking_addon_metabox_fields', $fields );
	}

	/**
	 * Custom admin columns.
	 */
	public static function addon_custom_columns( $columns ) {
		$new_columns = [];
		foreach ( $columns as $key => $value ) {
			$new_columns[ $key ] = $value;
			if ( $key === 'title' ) {
				$new_columns['addon_type']     = esc_html__( 'Type', 'hotel-booking-for-woocommerce' );
				$new_columns['addon_price']    = esc_html__( 'Price', 'hotel-booking-for-woocommerce' );
				$new_columns['addon_required'] = esc_html__( 'Required?', 'hotel-booking-for-woocommerce' );
			}
		}
		return $new_columns;
	}

	public static function addon_custom_column_content( $column, $post_id ) {
		switch ( $column ) {
			case 'addon_type':
				$type = get_post_meta( $post_id, '_addon_type', true );
				echo $type ? esc_html( ucfirst( str_replace( '_', ' ', $type ) ) ) : '&mdash;';
				break;

			case 'addon_price':
				$price = (float) get_post_meta( $post_id, 'price', true );
				echo $price ? wp_kses_post( wc_price( $price ) ) : '&mdash;';
				break;

			case 'addon_required':
				$required = get_post_meta( $post_id, 'required', true );
				echo ( $required === 'yes' ) ? '<span style="color:green;">' . esc_html__( 'Yes', 'hotel-booking-for-woocommerce' ) . '</span>' : esc_html__( 'No', 'hotel-booking-for-woocommerce' );
				break;
		}
	}

	/**
	 * Display the add-on type selection.
	 *
	 * @param \WP_Post $post The post object.
	 */
	private static function addon_types( $post ) {
		$types = [
			'fixed'          => esc_html__( 'Fixed', 'hotel-booking-for-woocommerce' ),
			'quantity_based' => esc_html__( 'Quantity based', 'hotel-booking-for-woocommerce' ),
		];

		$types = apply_filters( 'hbfwc_booking_addon_types', $types, $post );

		print '<span class="addon-data-wrapper type_box hidden"> &mdash; ';
		print '<label for="booking-addon-type">';
		print '<select name="_addon_type" id="booking-addon-type" class="select short">';
		print '<optgroup label="' . esc_attr__( 'Add-on type', 'hotel-booking-for-woocommerce' ) . '">';
		foreach ( $types as $type => $label ) {
			print '<option value="' . esc_attr( $type ) . '" ' . selected( $type, self::get_value( $post, '_addon_type' ), false ) . '>' . esc_html( $label ) . '</option>';
		}
		print '</optgroup>';
		print '</select>';
		print \wc_help_tip( esc_attr__( 'Defines how the add-on price is calculated — as a fixed fee or by user-selected quantity.', 'hotel-booking-for-woocommerce') );
		print '</label>';
		print '</span>';
	}
}

Booking_Addon_Metabox::init();
