<?php
/**
 * Class for extending WooCommerce Core Bookable Product Exports.
 *
 * @package WooCommerce Bookings
 */

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

/**
 * WC_Booking_Products_Export class.
 *
 * Handles exporting of bookable products.
 */
class WC_Booking_Products_Export {
	/**
	 * The data properties we'd like to include in the export.
	 *
	 * @deprecated 3.6.0 Use WC_Booking_Products_Export::get_column_labels() instead.
	 *
	 * @var array
	 */
	protected $properties = array();

	/**
	 * Merges booking product data into the parent object.
	 *
	 * @param int|WC_Product|object $product Product to init.
	 */
	public function __construct( $product = 0 ) {
		add_filter( 'woocommerce_product_export_row_data', array( $this, 'add_person_types' ), 20, 2 );
		add_filter( 'woocommerce_product_export_product_default_columns', array( $this, 'add_column_names' ), 20, 2 );
	}

	/**
	 * Set up the bookable properties that should also be exported.
	 *
	 * @deprecated 3.6.0 Labels now live in WC_Booking_Products_Export::get_column_labels().
	 */
	public function set_default_properties() {
		wc_deprecated_function( __METHOD__, '3.6.0', 'WC_Booking_Products_Export::get_column_labels' );
		$this->properties = self::get_column_labels();
	}

	/**
	 * Canonical bookable-product CSV columns: internal key => display label.
	 *
	 * Single source of truth shared with WC_Booking_Products_Import so that
	 * exported headers and import auto-detection can never drift. Labels are
	 * literal strings so they are picked up for translation, and the method is
	 * called lazily from filter callbacks (which run after `init`) so the text
	 * domain is loaded by the time `__()` runs.
	 *
	 * @since 3.6.0
	 *
	 * @return array
	 */
	public static function get_column_labels() {
		return array(
			'apply_adjacent_buffer'      => __( 'Apply adjacent buffer', 'woocommerce-bookings' ),
			'availability'               => __( 'Availability', 'woocommerce-bookings' ),
			'block_cost'                 => __( 'Block cost', 'woocommerce-bookings' ),
			'buffer_period'              => __( 'Buffer period', 'woocommerce-bookings' ),
			'calendar_display_mode'      => __( 'Calendar display mode', 'woocommerce-bookings' ),
			'cancel_limit_unit'          => __( 'Cancel limit unit', 'woocommerce-bookings' ),
			'cancel_limit'               => __( 'Cancel limit', 'woocommerce-bookings' ),
			'check_start_block_only'     => __( 'Check start block only', 'woocommerce-bookings' ),
			'cost'                       => __( 'Cost', 'woocommerce-bookings' ),
			'default_date_availability'  => __( 'Default date availability', 'woocommerce-bookings' ),
			'display_cost'               => __( 'Display cost', 'woocommerce-bookings' ),
			'duration_type'              => __( 'Duration type', 'woocommerce-bookings' ),
			'duration_unit'              => __( 'Duration unit', 'woocommerce-bookings' ),
			'duration'                   => __( 'Duration', 'woocommerce-bookings' ),
			'enable_range_picker'        => __( 'Enable range picker', 'woocommerce-bookings' ),
			'first_block_time'           => __( 'First block time', 'woocommerce-bookings' ),
			'has_person_cost_multiplier' => __( 'Has person cost multiplier', 'woocommerce-bookings' ),
			'has_person_qty_multiplier'  => __( 'Has person quantity multiplier', 'woocommerce-bookings' ),
			'has_person_types'           => __( 'Has person types', 'woocommerce-bookings' ),
			'has_persons'                => __( 'Has persons', 'woocommerce-bookings' ),
			'has_resources'              => __( 'Has resources', 'woocommerce-bookings' ),
			'has_restricted_days'        => __( 'Has restricted days', 'woocommerce-bookings' ),
			'max_date_unit'              => __( 'Max date unit', 'woocommerce-bookings' ),
			'max_date_value'             => __( 'Max date value', 'woocommerce-bookings' ),
			'max_duration'               => __( 'Max duration', 'woocommerce-bookings' ),
			'max_persons'                => __( 'Max persons', 'woocommerce-bookings' ),
			'min_date_unit'              => __( 'Min date unit', 'woocommerce-bookings' ),
			'min_date_value'             => __( 'Min date value', 'woocommerce-bookings' ),
			'min_duration'               => __( 'Min duration', 'woocommerce-bookings' ),
			'min_persons'                => __( 'Min persons', 'woocommerce-bookings' ),
			'person_types'               => __( 'Person types', 'woocommerce-bookings' ),
			'pricing'                    => __( 'Pricing', 'woocommerce-bookings' ),
			'qty'                        => __( 'Quantity', 'woocommerce-bookings' ),
			'requires_confirmation'      => __( 'Requires confirmation', 'woocommerce-bookings' ),
			'resource_label'             => __( 'Resource label', 'woocommerce-bookings' ),
			'resource_base_costs'        => __( 'Resource base costs', 'woocommerce-bookings' ),
			'resource_block_costs'       => __( 'Resource block costs', 'woocommerce-bookings' ),
			'resource_ids'               => __( 'Resource IDs', 'woocommerce-bookings' ),
			'resources_assignment'       => __( 'Resources assignment', 'woocommerce-bookings' ),
			'restricted_days'            => __( 'Restricted days', 'woocommerce-bookings' ),
			'user_can_cancel'            => __( 'User can cancel', 'woocommerce-bookings' ),
		);
	}

	/**
	 * When exporting  WC core uses columns to decided which properties to export.
	 * Add the bookings properties  to this list to ensure that we export those values.
	 *
	 * @since 1.11.0
	 *
	 * @param array $default_columns
	 *
	 * @return array
	 */
	public function add_column_names( $default_columns ) {
		return $default_columns + self::get_column_labels();
	}

	/**
	 * Add person types to the booking export.
	 *
	 * @since 1.11.0
	 *
	 * @param array $row
	 * @param WC_Product
	 *
	 * @return array
	 */
	public function add_person_types( $row, $product ) {
		if ( ! is_wc_booking_product( $product ) ) {
			return $row;
		}
		$types = $product->get_person_types();
		$types_to_export = $this->convert_types_for_export( $types );
		$row[ 'person_types' ] = $types_to_export;
		return $row;
	}

	/**
	 * Convert array of type WC_Product_Booking_Person_Type to array of array
	 * representing the data from the given objects. This ensures that don't export
	 * objects.
	 *
	 * @since 1.11.0
	 *
	 * @param array $types
	 *
	 * @return string|boolean
	 */
	public function convert_types_for_export( $types = array() ) {
		$converted_types = array();
		foreach ( $types as $person_type ){
			$converted_type = array(
				'block_cost'  => $person_type->get_block_cost(),
				'cost'        => $person_type->get_cost(),
				'description' => $person_type->get_description(),
				'max'         => $person_type->get_max(),
				'min'         => $person_type->get_min(),
				'name'        => $person_type->get_name(),
				'parent_id'   => $person_type->get_parent_id(),
				'sort_order'  => $person_type->get_sort_order(),
		   	);
			$converted_types[] = $converted_type;
		}
		return wp_json_encode( $converted_types );
	}
}
