<?php
/**
 * Functions file
 *
 * @package YITH\GiftCards\Classes
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
} // Exit if accessed directly


/**
 * Returns the product cost (int)
 *
 * @param object $product Product.
 *
 * @return int
 */
if ( ! function_exists( 'get_cost' ) ) {

	function get_cost( $product ) {

		$product = is_numeric( $product ) ? wc_get_product( $product ) : $product;

		if ( ! $product instanceof WC_Product ) {
			return;
		}
		// get the product cost.
		if ( $product->is_type( 'variable' ) ) {
			$cost = get_post_meta( $product->get_id(), 'yith_cog_cost_variable', true );
		} else {
			$cost = get_post_meta( $product->get_id(), 'yith_cog_cost', true );
		}
		// if no cost set for product variation.
		if ( '' === $cost && $product->is_type( 'variation' ) ) {
			$parent_product = wc_get_product( $product->get_parent_id() );

			if ( is_object( $parent_product ) ) {
				$cost = get_post_meta( $parent_product->get_id(), 'yith_cog_cost_variable', true );
			}
		}

		/**
		 * APPLY_FILTERS: yith_cog_product_cost
		 *
		 * Filter the Getter of the product total cost.
		 *
		 * @param float $cost the product cost
		 * @param object $product the product object
		 *
		 * @return float
		 */
		return apply_filters( 'yith_cog_product_cost', $cost, $product );
	}


}
/**
 * Returns the product cost with html format
 *
 * @param object $product Product.
 */
if ( ! function_exists( 'get_cost_html' ) ) {

	function get_cost_html( $product ) {

		$product = is_numeric( $product ) ? wc_get_product( $product ) : $product;

		if ( $product->get_type() === 'variable' ) {

			list( $min_variation_cost, $max_variation_cost ) = get_variable_product_min_max_costs( $product );

			if ( '' === $min_variation_cost ) {
				$variable_cost = get_post_meta( $product->get_id(), 'yith_cog_cost_variable', true );

				if ( '' !== $variable_cost ) {
					if ( 'no' === get_option( 'yith_cog_currency_report' ) ) {
						$cost = (float) $variable_cost;
					} else {
						$cost = wc_price( (float) $variable_cost );
					}
				} else {
					/**
					 * APPLY_FILTERS: yith_cog_variable_empty_cost_html
					 *
					 * Filter the string to display when a variable product has empty cost.
					 *
					 * @param string string to display for the empty cost
					 * @param object $product the product object
					 *
					 * @return string
					 */
					$cost = apply_filters( 'yith_cog_variable_empty_cost_html', '', $product );
				}
			} else {
				if ( $min_variation_cost !== $max_variation_cost ) {
					if ( 'no' === get_option( 'yith_cog_currency_report' ) ) {
						$cost = (float) $min_variation_cost . ' – ' . (float) $max_variation_cost;
					} else {
						$cost = wc_price( (float) $min_variation_cost ) . ' – ' . wc_price( (float) $max_variation_cost );
					}
				} else {
					if ( 'no' === get_option( 'yith_cog_currency_report' ) ) {
						$cost = $min_variation_cost;
					} else {
						$cost = wc_price( (float) $min_variation_cost );
					}
				}
			}
			/**
			 * APPLY_FILTERS: yith_cog_variable_cost_html
			 *
			 * Filter the HTML to display the cost of a variable product.
			 *
			 * @param string $cost the cost in HTML
			 * @param object $product the product object
			 *
			 * @return string
			 */
			$cost = apply_filters( 'yith_cog_variable_cost_html', $cost, $product );
		} else {
			$cost = get_cost( $product );

			if ( '' === $cost ) {
				/**
				 * APPLY_FILTERS: yith_cog_empty_cost_html
				 *
				 * Filter the string to display when a simple product has empty cost.
				 *
				 * @param string string to display for the empty cost
				 * @param object $product the product object
				 *
				 * @return string
				 */
				$cost = apply_filters( 'yith_cog_empty_cost_html', '', $product );
			} else {
				if ( 'no' === get_option( 'yith_cog_currency_report' ) ) {
					/**
					 * APPLY_FILTERS: yith_cog_cost_html
					 *
					 * Filter the HTML to display the cost of a simple product.
					 *
					 * @param string $cost the cost in HTML
					 * @param object $product the product object
					 *
					 * @return string
					 */
					$cost = apply_filters( 'yith_cog_cost_html', (float) $cost, $product );
				} else {
					$cost = apply_filters( 'yith_cog_cost_html', wc_price( (float) $cost ), $product );
				}
			}
		}

		/**
		 * APPLY_FILTERS: yith_cog_get_cost_html
		 *
		 * Filter the Getter return of the cost in HTML.
		 *
		 * @param string $cost the cost in HTML
		 * @param object $product the product object
		 *
		 * @return string
		 */
		return apply_filters( 'yith_cog_get_cost_html', $cost, $product );
	}
}


/**
 * Returns the minimum/maximum variations cost
 *
 * @param object $product Product.
 */
if ( ! function_exists( 'get_variable_product_min_max_costs' ) ) {

	function get_variable_product_min_max_costs( $product ) {

		$product_id = is_object( $product ) ? $product->get_id() : $product;

		$children = get_posts(
			array(
				'post_parent'    => $product_id,
				'posts_per_page' => -1,
				'post_type'      => 'product_variation',
				'fields'         => 'ids',
				'post_status'    => 'publish',
			)
		);

		$min_variation_cost = '';
		$max_variation_cost = '';

		if ( $children ) {
			foreach ( $children as $child_product_id ) {
				$child_cost = get_cost( $child_product_id );
				if ( '' === $child_cost ) {
					continue;
				}
				$min_variation_cost = '' === $min_variation_cost ? $child_cost : min( $min_variation_cost, $child_cost );
				$max_variation_cost = '' === $max_variation_cost ? $child_cost : max( $max_variation_cost, $child_cost );
			}
		}
		return array( $min_variation_cost, $max_variation_cost );
	}

}

if ( ! function_exists( 'yith_cog_get_view' ) ) {
	/**
	 * Get the view
	 *
	 * @param string $file_name Name of the file to get in views.
	 * @param array  $args      Arguments.
	 *
	 * @return string
	 */
	function yith_cog_get_view( $file_name, $args = array() ) {
		$file_path = trailingslashit( YITH_COG_VIEWS ) . $file_name;

		extract( $args ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract

		if ( file_exists( $file_path ) ) {
			include $file_path;
		}
	}
}

if ( ! function_exists( 'yith_cog_get_view_html' ) ) {
	/**
	 * Get a view HTML
	 *
	 * @param string $view The view.
	 * @param array  $args Arguments.
	 *
	 * @return string
	 * @since 2.0.0
	 */
	function yith_cog_get_view_html( $view, $args = array() ): string {
		ob_start();

		yith_cog_get_view( $view, $args );

		return ob_get_clean();
	}
}

add_action( 'init', 'yith_cog_version_2_migration' );


/**
 * Migrate the cost data from previous versions to the 2.0
 */
function yith_cog_version_2_migration() {

	$check_option = get_option( 'yith_cog_data_migrated_2', 'no' );

	if ( 'no' === $check_option ){

		global $wpdb;

		$product_lookup_table = $wpdb->prefix . 'wc_order_product_lookup';
		$plugin_data_table    = $wpdb->prefix . 'yith_cog_sales_report_data';

		if (  $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $plugin_data_table ) ) !== $plugin_data_table ){
			// Create a custom table, copy of the wc_order_product_lookup
			$wpdb->query( "CREATE TABLE IF NOT EXISTS {$plugin_data_table} LIKE {$product_lookup_table}");
			$wpdb->query( "INSERT INTO {$plugin_data_table} SELECT * FROM {$product_lookup_table}" );
			// add a new column to the plugin new table to store the item cost from orders
			$create_ddl = "ALTER TABLE {$plugin_data_table} ADD item_cost DOUBLE NOT NULL DEFAULT 0;";
			cog_maybe_add_column( $plugin_data_table, 'item_cost', $create_ddl );
		} else {
			$item_ids = $wpdb->get_results("SELECT order_item_id FROM {$plugin_data_table}");

			$wpdb->query( "ALTER TABLE {$plugin_data_table} MODIFY item_cost DOUBLE NOT NULL DEFAULT 0;");

			foreach ( $item_ids as $item ) {
				$item_cost = wc_get_order_item_meta( $item->order_item_id, '_yith_cog_item_cost' );

				if ( $item_cost > 0 ){
					$wpdb->update( $plugin_data_table, array( 'item_cost' => $item_cost ), array( 'order_item_id' => $item->order_item_id) );
				}
			}
		}

		update_option( 'yith_cog_data_migrated_2', 'yes' );

	}

}

if ( ! function_exists( 'cog_maybe_add_column' ) ) {
	function cog_maybe_add_column( $table_name, $column_name, $create_ddl ) {
		global $wpdb;

		foreach ( $wpdb->get_col( "DESC $table_name", 0 ) as $column ) {
			if ( $column === $column_name ) {
				return true;
			}
		}

		// Didn't find it, so try to create it.
		$wpdb->query( $create_ddl );

		// We cannot directly tell that whether this succeeded!
		foreach ( $wpdb->get_col( "DESC $table_name", 0 ) as $column ) {
			if ( $column === $column_name ) {
				return true;
			}
		}

		return false;
	}
}

if ( ! function_exists( 'yith_cog_date_format' ) ) {
	/**
	 * Accepts any date that ca be successfully passed to {@see strtotime} and converts it to current date_format
	 * Returns an array containing formatted date and a format string that describes currently applied format for jQuery extensions
	 *
	 * This function is especially useful when we need to print a datepicker input: it will require a formatted default date,
	 * and a format to pass to jQuery script, in order to format all picked dates the same as the default one.
	 *
	 * @param  string $date Date in a format accepted by {@see strtotime}.
	 *
	 * @return array An array formatted as follows:
	 * [
	 *     'date'   => 'Jan 01, 2022',
	 *     'format' => 'M dd, yy',
	 * ]
	 */
	function yith_cog_js_date_format( $date ) {
		$date_format = wc_date_format();
		$format      = yith_cog_convert_jquery_date_format( $date_format, YITH_COG_CONVERT_DATE_PHP_TO_JQUERY );
		$date        = $date ? date_i18n( $date_format, strtotime( $date ) ) : '';

		return compact( 'date', 'format' );
	}
}

if ( ! function_exists( 'yith_cog_jquery_to_php_date_format' ) ) {
	/**
	 * Define flags to use in $flags field of \yith_wcaf_convert_jquery_date_format function.
	 */
	! defined( 'YITH_COG_CONVERT_DATE_PHP_TO_JQUERY' ) && define( 'YITH_COG_CONVERT_DATE_PHP_TO_JQUERY', 0 );
	! defined( 'YITH_COG_CONVERT_DATE_JQUERY_TO_PHP' ) && define( 'YITH_COG_CONVERT_DATE_JQUERY_TO_PHP', 1 );

	/**
	 * Converts date format from PHP to jQuery or vice versa
	 *
	 * @param string $format Format to convert.
	 * @param int    $mode   Mode for conversion (falsy => PHP -> jQuery; truthy => jQuery -> PHP).
	 *
	 * @return string Converted date format.
	 */
	function yith_cog_convert_jquery_date_format( $format, $mode = YITH_COG_CONVERT_DATE_JQUERY_TO_PHP ) {
		$replacements = array(
			'dd' => 'd',
			'd'  => 'j',
			'oo' => 'z',
			'o'  => 'z',
			'DD' => 'l',
			'mm' => 'm',
			'm'  => 'n',
			'MM' => 'F',
			'yy' => 'Y',
			'@'  => 'U',
		);

		$search  = $mode ? array_keys( $replacements ) : array_values( $replacements );
		$replace = $mode ? array_values( $replacements ) : array_keys( $replacements );

		return str_replace( $search, $replace, $format );
	}
}

if ( ! function_exists( 'yith_cog_price' ) ) {
	/**
	 * Fromat the price the same way WooCommerce does but checking our plugin options to know if we need
	 * to include the currency within the output or not
	 *
	 * @param  int   $price Upcoming value to be formatted.
	 * @param  array $args  Arguments we can define when calling the method.
	 *
	 * @return mixed Formatted value with or without currency.
	 */
	function yith_cog_price( $price, $args = array() ) {

		$args = apply_filters(
			'wc_price_args',
			wp_parse_args(
				$args,
				array(
					'ex_tax_label'       => false,
					'currency'           => '',
					'decimal_separator'  => wc_get_price_decimal_separator(),
					'thousand_separator' => wc_get_price_thousand_separator(),
					'decimals'           => wc_get_price_decimals(),
					'price_format'       => get_woocommerce_price_format(),
				)
			)
		);

		$option = get_option( 'yith_cog_currency_report', false );

		$original_price = $price;

		// Convert to float to avoid issues on PHP 8.
		$price = (float) $price;

		$unformatted_price = $price;
		$negative          = $price < 0;

		/**
		 * Filter raw price.
		 *
		 * @param float        $raw_price      Raw price.
		 * @param float|string $original_price Original price as float, or empty string. Since 5.0.0.
		 */
		$price = apply_filters( 'raw_woocommerce_price', $negative ? $price * -1 : $price, $original_price );

		/**
		 * Filter formatted price.
		 *
		 * @param float        $formatted_price    Formatted price.
		 * @param float        $price              Unformatted price.
		 * @param int          $decimals           Number of decimals.
		 * @param string       $decimal_separator  Decimal separator.
		 * @param string       $thousand_separator Thousand separator.
		 * @param float|string $original_price     Original price as float, or empty string. Since 5.0.0.
		 */
		$price = apply_filters( 'formatted_woocommerce_price', number_format( $price, $args['decimals'], $args['decimal_separator'], $args['thousand_separator'] ), $price, $args['decimals'], $args['decimal_separator'], $args['thousand_separator'], $original_price );

		if ( apply_filters( 'woocommerce_price_trim_zeros', false ) && $args['decimals'] > 0 ) {
			$price = wc_trim_zeros( $price );
		}

		if ( 'yes' === $option ) {
			$currency = '<span class="woocommerce-Price-currencySymbol">' . get_woocommerce_currency_symbol( $args['currency'] ) . '</span>';
		} else {
			$currency = '';
		}

		$formatted_price = ( $negative ? '-' : '' ) . sprintf( $args['price_format'], $currency, $price );
		$return          = '<span class="woocommerce-Price-amount amount"><bdi>' . $formatted_price . '</bdi></span>';

		if ( $args['ex_tax_label'] && wc_tax_enabled() ) {
			$return .= ' <small class="woocommerce-Price-taxLabel tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
		}

		/**
		 * Filters the string of price markup.
		 *
		 * @param string       $return            Price HTML markup.
		 * @param string       $price             Formatted price.
		 * @param array        $args              Pass on the args.
		 * @param float        $unformatted_price Price as float to allow plugins custom formatting. Since 3.2.0.
		 * @param float|string $original_price    Original price as float, or empty string. Since 5.0.0.
		 */
		return apply_filters( 'yith_cog_price', $return, $price, $args, $unformatted_price, $original_price );
	}
}
