<?php
/**
 * Calculates server-side addon pricing for PPOM cart items.
 *
 * @package PPOM
 * @subpackage Pricing
 *
 * @see self::price_controller()
 * @see self::get_field_prices()
 * @see self::price_get_product_base()
 * @see self::price_cart_fee()
 */

namespace PPOM\Pricing;

use PPOM\Hooks\Callbacks;
use PPOM\Support\Helpers;

/**
 * @internal
 */
final class Engine {

	// Cart line pricing.

	/**
	 * Recalculates the cart line price for a PPOM cart item.
	 *
	 * @param array $cart_item Cart item restored from the session.
	 * @param array $values    Raw cart item values.
	 *
	 * @return array
	 *
	 * @see self::get_field_prices()
	 * @see self::price_get_product_base()
	 * @see self::price_cart_fee()
	 */
	public static function price_controller( $cart_item, $values ) {

		// ppom_pa($cart_item);
		if ( empty( $cart_item ) ) {
			return $cart_item;
		}

		if ( ! isset( $values['ppom']['fields'] ) ) {
			return $cart_item;
		}

		$wc_product        = $cart_item['data'];
		$product_id        = Helpers::get_product_id( $wc_product );
		$variation_id      = isset( $cart_item['variation_id'] ) ? $cart_item['variation_id'] : '';
		$ppom_fields_post  = $values['ppom']['fields'];
		$product_quantity  = floatval( $cart_item['quantity'] );
		$ppom_field_prices = self::get_field_prices( $ppom_fields_post, $product_id, $product_quantity, $variation_id, $cart_item );
		$ppom_discount     = 0;
		$ppom_pricematrix  = isset( $cart_item['ppom']['price_matrix_found'] ) ? $cart_item['ppom']['price_matrix_found'] : null;
		// ppom_pa($product_quantity);
		// ppom_pa($ppom_fields_post);
		// ppom_pa($ppom_field_prices);

		$total_addon_price    = self::price_get_addon_total( $ppom_field_prices );
		$total_cart_fee_price = self::price_get_cart_fee_total( $ppom_field_prices );

		$product_price = apply_filters( 'ppom_product_price_on_cart', $wc_product->get_price(), $cart_item );

		// return array with: price, source
		$price_info         = self::price_get_product_base(
			$product_price,
			$wc_product,
			$ppom_fields_post,
			$product_quantity,
			$ppom_field_prices,
			$ppom_discount,
			$ppom_pricematrix 
		);
		$product_base_price = $price_info['price'];
		// var_dump("product_base_price ==> ".$product_base_price."<br>");
		// ppom_pa($price_info);
		// var_dump("total_addon_price ==> ".$total_addon_price."<br>");   
		// var_dump("total_cart_fee_price ==> ".$total_cart_fee_price."<br>");   
		// var_dump("ppom_discount ==> ".$ppom_discount."<br>");

		$ppom_total_price = floatval( $total_addon_price ) + floatval( $product_base_price ) - $ppom_discount;
		// var_dump("ppom_total_price ==> ".$ppom_total_price."<br>");

		do_action( 'ppom_before_calculate_cart_total', $ppom_field_prices, $ppom_fields_post, $cart_item );

		$ppom_total_price = apply_filters( 'ppom_cart_line_total', $ppom_total_price, $cart_item, $values );
		$wc_product->set_price( $ppom_total_price );

		return $cart_item;
	}

	public static function before_calculate_totals( $cart_items ) {

		// ppom_pa($cart_items);
		if ( empty( $cart_items ) ) {
			return $cart_items;
		}

		foreach ( $cart_items->cart_contents as $cart_item_key => $cart_item ) {


			if ( ! isset( $cart_item['ppom']['fields'] ) ) {
				continue;
			}
			$product_id        = isset( $cart_item['product_id'] ) ? $cart_item['product_id'] : '';
			$variation_id      = isset( $cart_item['variation_id'] ) ? $cart_item['variation_id'] : '';
			$wc_product        = $cart_item['data'];
			$ppom_fields_post  = $cart_item['ppom']['fields'];
			$product_quantity  = floatval( $cart_item['quantity'] );
			$ppom_field_prices = self::get_field_prices( $ppom_fields_post, $product_id, $product_quantity, $variation_id );
			$ppom_discount     = 0;
			$ppom_pricematrix  = isset( $cart_item['ppom']['price_matrix_found'] ) ? $cart_item['ppom']['price_matrix_found'] : null;
			// ppom_pa($product_quantity);
			// ppom_pa($ppom_fields_post);
			// ppom_pa($ppom_field_prices);

			$total_addon_price    = self::price_get_addon_total( $ppom_field_prices );
			$total_cart_fee_price = self::price_get_cart_fee_total( $ppom_field_prices );

			$product_price = apply_filters( 'ppom_product_price_on_cart', $wc_product->get_price(), $cart_item );

			// $context     = 'cart';
			// $product_price   = Helpers::get_product_price( $product, $variation_id, $context);

			// return array with: price, source
			$price_info = self::price_get_product_base(
				$product_price,
				$wc_product,
				$ppom_fields_post,
				$product_quantity,
				$ppom_field_prices,
				$ppom_discount,
				$ppom_pricematrix 
			);

			$product_base_price = $price_info['price'];
			// var_dump("product_base_price ==> ".$product_base_price."<br>");
			// ppom_pa($cart_item['data']);
			// var_dump("total_addon_price ==> ".$total_addon_price."<br>");   
			// var_dump("total_cart_fee_price ==> ".$total_cart_fee_price."<br>");   
			// var_dump("ppom_discount ==> ".$ppom_discount."<br>");


			$ppom_total_price = $total_addon_price + $product_base_price - $ppom_discount;

			do_action( 'ppom_before_calculate_cart_total', $ppom_field_prices, $ppom_fields_post, $cart_item );
			$ppom_total_price = apply_filters( 'ppom_cart_line_total', $ppom_total_price, $cart_items, $cart_item );
			$cart_item['data']->set_price( $ppom_total_price );
		}
	}


	/**
	 * Resolves price entries for posted PPOM fields.
	 *
	 * Uses submitted field selections to look up field definitions and build the
	 * normalized pricing rows used by cart line pricing and cart fees.
	 *
	 * @param mixed                     $ppom_fields_post Posted PPOM field values.
	 * @param int                       $product_id       Product ID.
	 * @param float|int                 $product_quantity Product quantity.
	 * @param int|string                $variation_id     Variation ID.
	 * @param array<string, mixed>|null $item             Cart item context.
	 *
	 * @return array<string, mixed>
	 *
	 * @see Helpers::get_field_meta_by_dataname()
	 * @see self::price_get_product_base()
	 * @see self::price_cart_fee()
	 */
	public static function get_field_prices( $ppom_fields_post, $product_id, &$product_quantity, $variation_id, $item = null ) {

		$field_prices  = array();
		$ppom_meta_ids = apply_filters( 'ppom_meta_ids_in_cart', null, $item );
		if ( is_array( $ppom_fields_post ) ) {
			$ppom_fields_post = Helpers::filter_posted_ppom_fields_by_active_variation( $ppom_fields_post, $product_id, (int) $variation_id );
		}

		// ppom_pa($item);
		foreach ( $ppom_fields_post as $data_name => $value ) {

			if ( $data_name == 'id' ) {
				continue;
			}

			if ( empty( $value ) ) {
				continue;
			}

			// var_dump($data_name);

			$value = wp_unslash( $value );

			$field_meta = Helpers::get_field_meta_by_dataname( $product_id, $data_name, $ppom_meta_ids );
			$product    = wc_get_product( $product_id );

			$field_type  = isset( $field_meta['type'] ) ? $field_meta['type'] : '';
			$field_title = isset( $field_meta['title'] ) ? $field_meta['title'] : '';

			$charge = isset( $field_meta['onetime'] ) ? $field_meta['onetime'] : '';
			$charge = $charge == 'on' ? 'cart_fee' : 'addon';

			$context       = 'cart';
			$product_price = Helpers::get_product_price( $product, $variation_id, $context );

			$options = array();

			$field_type = apply_filters( 'ppom_field_type_price', $field_type, $ppom_fields_post, $product_id );

			// ppom_pa($field_meta);

			// Getting options
			switch ( $field_type ) {

				case 'bulkquantity':
					$options = isset( $field_meta['options'] ) ? json_decode( wp_unslash( $field_meta['options'] ), true ) : array();
					break;
				case 'image':
					$options = isset( $field_meta['images'] ) ? Helpers::convert_options_to_key_val( $field_meta['images'], $field_meta, $product ) : array();
					break;
				case 'audio':
					$options = isset( $field_meta['audio'] ) ? Helpers::convert_options_to_key_val( $field_meta['audio'], $field_meta, $product ) : array();
					break;
				case 'imageselect':
					$options = isset( $field_meta['images'] ) ? Helpers::convert_options_to_key_val( $field_meta['images'], $field_meta, $product ) : array();
					break;
				case 'eventcalendar':
					$disbl_global_price = isset( $field_meta['disabled_global_price'] ) ? $field_meta['disabled_global_price'] : '';

					if ( isset( $field_meta['global_price'] ) && $field_meta['global_price'] != '' ) {
						$global_price = $field_meta['global_price'];
					} else {
						$global_price = 0;
					}

					$options = isset( $field_meta['options'] ) ? $field_meta['options'] : array();

					$options[] = array(
						'price'  => $global_price,
						'option' => 'Simple',
						'id'     => 'simple',
					);

					break;

				// Note: Variation Matrix Use for only customized clients
				case 'vm':
					$vm_options = array();

					$options = isset( $field_meta['options'] ) ? Helpers::convert_options_to_key_val( $field_meta['options'], $field_meta, $product ) : array();

					$row_options = isset( $field_meta['row_options'] ) ? explode( PHP_EOL, $field_meta['row_options'] ) : array();

					foreach ( $options as $opt_name => $opt ) {

						foreach ( $row_options as $index => $r_opt ) {

							$color_code = apply_filters( 'ppom_vm_row_index', $r_opt, $field_meta );

							$name_k = stripslashes( trim( $opt_name ) ) . '_' . stripslashes( trim( $color_code ) );

							$vm_options[ $name_k ] = $opt['price'];

						}               
					}

					break;


				case 'vqmatrix':
					$vqmatrix_pricemeta = array();

					$priced_options = isset( $field_meta['options'] ) ? $field_meta['options'] : array();
					$simple_options = isset( $field_meta['row_options'] ) ? $field_meta['row_options'] : array();
					$default_price  = ! empty( $field_meta['default_price'] ) ? $field_meta['default_price'] : 0;

					foreach ( $priced_options as $index_1 => $opt_meta_1 ) {

						$the_price     = isset( $opt_meta_1['price'] ) && $opt_meta_1['price'] != '' ? $opt_meta_1['price'] : $default_price;
						$priced_opt_id = ! empty( $opt_meta_1['option_id'] ) ? stripslashes( trim( $opt_meta_1['option_id'] ) ) : '';

						foreach ( $simple_options as $index_2 => $opt_meta_2 ) {

							$simple_opt_id = ! empty( $opt_meta_2['option_id'] ) ? stripslashes( trim( $opt_meta_2['option_id'] ) ) : '';

							$options_key = ucfirst( $priced_opt_id ) . '-' . ucfirst( $simple_opt_id );

							$vqmatrix_pricemeta[ $options_key ] = $the_price;

						}
					}

					break;
				default:
					$options = isset( $field_meta['options'] ) ? Helpers::convert_options_to_key_val( $field_meta['options'], $field_meta, $product ) : array();
					break;
			}

			// ppom_pa($options);


			$field_price     = '';
			$option_quantity = 1;

			if ( Helpers::reset_cart_quantity_to_one( $product_id ) ) {
				$option_quantity = self::price_get_total_quantities( $ppom_fields_post, $product_id );
			}

			switch ( $field_type ) {

				case 'text':
				case 'textarea':
				case 'date':
				case 'email':
					$option      = $value;
					$field_price = isset( $field_meta['price'] ) ? $field_meta['price'] : '';
					if ( $field_price !== '' ) {
						$field_prices[] = self::generate_field_price( $field_price, $field_meta, $charge, $option, $option_quantity );
					}
					break;

				case 'select':
				case 'radio':
					foreach ( $options as $option ) {

						$option_raw = Helpers::wpml_translate( $option['raw'], 'PPOM' );
						if ( $option_raw == wp_unslash( $value ) ) {

							$option_price   = isset( $option['raw_price'] ) ? $option['raw_price'] : '';
							$option_percent = isset( $option['percent'] ) ? $option['percent'] : '';

							if ( $option_price !== '' ) {

								if ( $option_percent !== '' ) {
									$option_price = self::get_amount_after_percentage( $product_price, $option_percent );
								}

								$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $option_quantity );
							}

							// weight
							if ( ! empty( $option['option_weight'] ) ) {
								$field_price    = 0;
								$field_prices[] = self::generate_field_price( $field_price, $field_meta, 'weight', $option );
							}
						}
					}
					break;

				case 'checkbox':
					foreach ( $options as $option ) {

						if ( is_array( $value ) ) {
							foreach ( $value as $val ) {

								$option_raw = Helpers::wpml_translate( $option['raw'], 'PPOM' );
								if ( $option_raw == wp_unslash( $val ) ) {

									$option_price = isset( $option['raw_price'] ) ? $option['raw_price'] : '';

									/**
									 * @since 24.6 discount price added
									 * */
									if ( $option['raw_discount'] > 0 ) {
										$option_price = $option['raw_discount'];
									}

									if ( $option_price !== '' ) {
										if ( strpos( $option_price, '%' ) !== false ) {
											$option_price = self::get_amount_after_percentage( $product_price, $option_price );
										}
										$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $option_quantity );
									}

									// weight
									if ( ! empty( $option['option_weight'] ) ) {
										$field_price    = 0;
										$field_prices[] = self::generate_field_price( $field_price, $field_meta, 'weight', $option );
									}
								}
							}
						}
					}
					break;

				case 'multiple_select':
					foreach ( $value as $opt_index => $opt_label ) {

						foreach ( $options as $option ) {

							$option_raw = Helpers::wpml_translate( $option['raw'], 'PPOM' );

							if ( $option_raw == $opt_label ) {

								$option_price   = isset( $option['raw_price'] ) ? $option['raw_price'] : '';
								$option_percent = isset( $option['percent'] ) ? $option['percent'] : '';

								if ( $option_price !== '' ) {

									if ( $option_percent !== '' ) {
										$option_price = self::get_amount_after_percentage( $product_price, $option_percent );
									}

									$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $option_quantity );
								}
							}
						}
					}
					break;

				case 'cropper':
					// ppom_pa($options);

					// Checking if ratio found with cropping
					if ( isset( $value['ratio'] ) && $value['ratio'] !== '' ) {
						$ratio_found = $value['ratio'];
						// Getting option
						foreach ( $options as $option ) {
							if ( $option['option_id'] === $ratio_found ) {

								$option_price   = isset( $option['raw_price'] ) ? $option['raw_price'] : '';
								$option_percent = isset( $option['percent'] ) ? $option['percent'] : '';

								if ( $option_price !== '' ) {

									if ( $option_percent !== '' ) {
										$option_price = self::get_amount_after_percentage( $product_price, $option_percent );
									}

									$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $option_quantity );
								}
							}
						}
					}

					break;

				case 'fancycropper':
					foreach ( $value as $popupID => $image_data ) {

						$fomatted_data = json_decode( stripcslashes( $image_data ), true );

						$cropped_price = isset( $fomatted_data['cartPrice'] ) ? $fomatted_data['cartPrice'] : 0;
						if ( $cropped_price > 0 ) {

							$field_prices[] = self::generate_field_price( $cropped_price, $field_meta, $charge, $image_data, $option_quantity );
						}
					}

					break;

				case 'palettes':
					foreach ( $options as $option ) {

						if ( is_array( $value ) ) {
							foreach ( $value as $color ) {

								if ( $option['raw'] == $color ) {

									$option_price   = isset( $option['raw_price'] ) ? $option['raw_price'] : '';
									$option_percent = isset( $option['percent'] ) ? $option['percent'] : '';

									if ( $option_price !== '' ) {

										if ( $option_percent !== '' ) {
											$option_price = self::get_amount_after_percentage( $product_price, $option_percent );
										}

										$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $option_quantity );
									}                           
								}
							}
						}
					}
					break;

				case 'imageselect':
					foreach ( $options as $option ) {
						$image_id = isset( $option['image_id'] ) ? $option['image_id'] : 0;
						if ( $image_id == $value ) {

							$option_price = isset( $option['raw_price'] ) ? $option['raw_price'] : '';
							if ( $option_price !== '' ) {
								if ( strpos( $option_price, '%' ) !== false ) {
									$option_price = self::get_amount_after_percentage( $product_price, $option_price );
								}
								$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $option_quantity );
							}
						}
					}
					break;

				case 'image':
					foreach ( $options as $option ) {
						if ( is_array( $value ) ) {
							foreach ( $value as $images_meta ) {

								$images_meta     = json_decode( stripslashes( $images_meta ), true );
								$image_id        = $images_meta['image_id'];
								$image_price     = $images_meta['price'];
								$image_option_id = $images_meta['option_id'];


								if ( $option['option_id'] == $image_option_id ) {

									$option_price   = isset( $option['raw_price'] ) ? $option['raw_price'] : '';
									$option_percent = isset( $option['percent'] ) ? $option['percent'] : '';

									// var_dump($option_price);
									if ( $option_price !== '' ) {
										if ( strpos( $option_price, '%' ) !== false ) {
											$option_price = self::get_amount_after_percentage( $product_price, $option_price );
										}
										$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $option_quantity );
									}
								}
							}
						}
					}
					// $field_prices[] = self::generate_field_price($option_price, $field_meta, $charge, $option);
					break;

				case 'audio':
					foreach ( $options as $option ) {

						if ( is_array( $value ) ) {
							foreach ( $value as $images_meta ) {

								$images_meta = json_decode( stripslashes( $images_meta ), true );
								$image_id    = $images_meta['id'];
								$image_price = $images_meta['price'];
								$image_title = $images_meta['title'];

								if ( $option['raw'] == $image_title ) {

									$option_price   = isset( $option['raw_price'] ) ? $option['raw_price'] : '';
									$option_percent = isset( $option['percent'] ) ? $option['percent'] : '';

									if ( $option_price !== '' ) {
										if ( strpos( $option_price, '%' ) !== false ) {
											$option_price = self::get_amount_after_percentage( $product_price, $option_price );
										}
										$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $option_quantity );
									}
								}
							}
						}
					}
					// $field_prices[] = self::generate_field_price($option_price, $field_meta, $charge, $option);
					break;

				case 'file':
					$file_cost   = isset( $field_meta['file_cost'] ) ? floatval( $field_meta['file_cost'] ) : 0;
					$total_files = count( $value );
					$field_price = $file_cost * $total_files;

					if ( $field_price > 0 ) {
						$option         = $value; // files array from post
						$field_prices[] = self::generate_field_price( $field_price, $field_meta, $charge, $option, 1 );
					}
					break;


				case 'quantities':
				case 'qtypack':
					// ppom_pa(self::is_field_has_price($field_meta));

					if ( self::is_field_has_price( $field_meta ) ) {
						foreach ( $options as $option ) {
							$quantities_total = 0;

							foreach ( $value as $val => $quantity ) {

								$quantity          = intval( $quantity );
								$quantities_total += $quantity;
								// Important: need to convert browser data into html_entity_decode
								$val = html_entity_decode( $val );

								if ( $option['raw'] == $val && $quantity > 0 ) {
									$option_price = isset( $option['raw_price'] ) ? $option['raw_price'] : '';

									$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $quantity );

									// weight
									if ( ! empty( $option['option_weight'] ) ) {
										$field_price    = 0;
										$field_prices[] = self::generate_field_price( $field_price, $field_meta, 'weight', $option, $quantity );
									}
								}
							}
						}

						if ( $quantities_total > 0 ) {
							$product_quantity = $quantities_total;
						}
					} else {

						// Check if matrix used
						$option_price      = $product_price;
						$option            = array();
						$pricematrix_field = Helpers::has_field_by_type( Helpers::get_product_id( $product ), 'pricematrix' );
						if ( $pricematrix_field ) {
							$matrix_found = self::price_matrix_chunk( $product, $pricematrix_field, $product_quantity );

							if ( $matrix_found ) {
								// $option_price = $matrix_found['matrix_price'];
								$charge         = 'matrix_quantities';
								$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $product_quantity );
							}
						}               
					}

					break;


				case 'selectqty':
					if ( self::is_field_has_price( $field_meta ) ) {
						foreach ( $options as $option ) {
							$quantities_total = 0;

							$val      = $value['option'];
							$quantity = $value['qty'];

							// var_dump($val, $option); 
							$quantity          = intval( $quantity );
							$quantities_total += $quantity;

							if ( $option['raw'] == $val && $quantity > 0 ) {
								$option_price = isset( $option['raw_price'] ) ? $option['raw_price'] : '';

								$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $quantity );

								// weight
								if ( ! empty( $option['option_weight'] ) ) {
									$field_price    = 0;
									$field_prices[] = self::generate_field_price( $field_price, $field_meta, 'weight', $option, $quantity );
								}
							}
						}

						if ( $quantities_total > 0 ) {
							$product_quantity = $quantities_total;
						}
					}
					break;


				// Note: Variation Matrix Use for only customized clients
				case 'vm':
					if ( self::is_field_has_price( $field_meta ) ) {

						foreach ( $vm_options as $vm_key => $vm_price ) {
							$quantities_total = 0;

							foreach ( $value as $val => $quantity ) {

								$quantities_total += $quantity;
								// Important: need to convert browser data into html_entity_decode
								$val = html_entity_decode( $val );

								if ( $val === $vm_key && $quantity > 0 ) {
									$option_price = $vm_price;

									$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $options, $quantity );
								}
							}
						}

						if ( $quantities_total > 0 ) {
							$product_quantity = $quantities_total;
						}
					}

					break;

				case 'vqmatrix':
					if ( self::is_field_has_price( $field_meta ) ) {

						foreach ( $vqmatrix_pricemeta as $vm_key => $vm_price ) {
							$quantities_total = 0;

							foreach ( $value as $val => $quantity ) {

								$quantities_total += $quantity;

								// Important: need to convert browser data into html_entity_decode
								$val = html_entity_decode( $val );

								if ( $val === $vm_key && $quantity > 0 ) {
									$option_price   = $vm_price;
									$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $options, $quantity );
								}
							}
						}

						if ( $quantities_total > 0 ) {
							$product_quantity = $quantities_total;
						}
					} else {

						// Check if matrix used
						$option_price      = $product_price;
						$option            = array();
						$pricematrix_field = Helpers::has_field_by_type( Helpers::get_product_id( $product ), 'pricematrix' );
						if ( $pricematrix_field ) {
							$matrix_found = self::price_matrix_chunk( $product, $pricematrix_field, $product_quantity );

							if ( $matrix_found ) {
								// $option_price = $matrix_found['matrix_price'];
								$charge         = 'matrix_quantities';
								$field_prices[] = self::generate_field_price( $option_price, $field_meta, $charge, $option, $product_quantity );
							}
						}
					}

					break;


				case 'bulkquantity':
					// THIS SHOULD BE CHECK ON TOP AFTER FOREACH LOOP
					$conditionally_hidden = isset( $item['ppom']['conditionally_hidden'] ) ? $item['ppom']['conditionally_hidden'] : array();
					if ( Helpers::is_field_hidden_by_condition( $data_name, $conditionally_hidden ) ) {
						continue 2;
					}

					$product_quantity = $value['qty'];
					$bq_value         = $value['option'];
					// $option              = null;

					$bq_found     = self::price_bulkquantity_chunk( $product, $options, $product_quantity );
					$option_price = isset( $bq_found[ $bq_value ] ) ? floatval( $bq_found[ $bq_value ] ) : null;
					if ( $option_price ) {
						$single_quantity = 1;
						$field_prices[]  = self::generate_field_price( $option_price, $field_meta, $charge, $bq_found, $single_quantity );
					}
					// ppom_pa($bq_found);
					break;

				case 'fixedprice':
					$fp_found   = self::price_fixedprice_chunk( $product, $options, $product_quantity );
					$unit_price = PPOM_FPP()->get_unit_price( $fp_found, $field_meta );
					if ( $unit_price ) {
						$field_prices[] = self::generate_field_price( $unit_price, $field_meta, $charge, $fp_found, 1 );
					}
					break;

				case 'measure':
					// var_dump($value);
					$product_quantity    = $value;
					$unit_price          = 0;
					$measure_price_field = self::generate_field_price( $unit_price, $field_meta, $charge, $options, $product_quantity );

					if ( isset( $field_meta['price-multiplier'] ) && is_numeric( $field_meta['price-multiplier'] ) ) {
						$measure_price_field['price-multiplier'] = floatval( $field_meta['price-multiplier'] );
					} 

					$field_prices[] = $measure_price_field;
					break;

				case 'eventcalendar':
					// if( self::is_field_has_price($field_meta) ) { // Waite & Watch Party
					if ( 1 ) {
						foreach ( $options as $ticket ) {

							$quantities_total = 0;
							$ticket_label     = isset( $ticket['option'] ) ? $ticket['option'] : '';

							foreach ( $value as $date => $ticket_meta ) {


								foreach ( $ticket_meta as $label => $qty ) {

									$quantities_total += $qty;

									if ( $ticket_label == $label ) {
										$ticket_price   = isset( $ticket['raw_price'] ) ? $ticket['raw_price'] : '';
										$field_prices[] = self::generate_field_price( $ticket_price, $field_meta, $charge, $options, $qty );
									}
								}
							}

							if ( $quantities_total > 0 ) {
								$product_quantity = $quantities_total;
							}
						}
					}

					break;

				case 'textcounter':
					// ppom_pa($field_meta);
					if ( ! is_array( $field_meta ) || ! isset( $field_meta['count_type'] ) ) {
						break;
					}
					$count_type    = $field_meta['count_type'];
					$enabled_space = isset( $field_meta['enabled_space'] ) ? $field_meta['enabled_space'] : false;

					switch ( $count_type ) {
						case 'character':
							if ( $enabled_space == 'on' ) {
								$length = preg_match_all( '/[^\.]/', $value, $matches );
							} else {
								$length = preg_match_all( '/[^ \.]/', $value, $matches );
							}
							break;
						case 'word':
						default:
							$length = str_word_count( $value );

					}

					if ( ! empty( $field_meta['count_price'] ) ) {

						$price          = $field_meta['count_price'] * $length;
						$field_prices[] = self::generate_field_price( $price, $field_meta, $charge, $options, 1 );
					}

					break;

			}   
		}

		// ppom_pa($field_prices);

		return apply_filters( 'ppom_fields_prices', $field_prices, $ppom_fields_post, $product_id );
	}

	public static function generate_field_price( $field_price, $field_meta, $apply, $option = array(), $qty = 0 ) {

		// ppom_pa($option);

		$data_name    = isset( $field_meta['data_name'] ) ? $field_meta['data_name'] : '';
		$field_title  = isset( $field_meta['title'] ) ? stripslashes( $field_meta['title'] ) : '';
		$field_type   = isset( $field_meta['type'] ) ? $field_meta['type'] : '';
		$taxable      = ( isset( $field_meta['onetime_taxable'] ) && $field_meta['onetime_taxable'] == 'on' ) ? true : false;
		$option_label = isset( $option['raw'] ) ? $option['raw'] : '';
		$without_tax  = isset( $option['without_tax'] ) ? $option['without_tax'] : '';

		$field_price = apply_filters( 'ppom_option_price', $field_price );

		$label_price = "{$field_title} - " . wc_price( $field_price );
		// For bulkquantity
		$base_price = isset( $option['Base Price'] ) ? $option['Base Price'] : '';
		$option_id  = isset( $option['option_id'] ) ? $option['option_id'] : '';

		if ( $field_type == 'file' ) {
			// translators: %d: the number of files options.
			$option_label = sprintf( __( '%d Files', 'woocommerce-product-addon' ), count( $option ) );
		}

		return apply_filters(
			'ppom_price_option_meta',
			array(
				'type'         => $field_type,
				'option_id'    => $option_id,
				'label'        => $field_title,
				'label_price'  => $label_price,
				'price'        => $field_price,
				'apply'        => $apply,
				'data_name'    => $data_name,
				'taxable'      => $taxable,
				'without_tax'  => $without_tax,
				'option_label' => $option_label,
				'quantity'     => $qty,
				'base_price'   => $base_price,
			),
			$field_meta,
			$field_price,
			$option,
			$qty
		);
	}

	// Get total addon price of given Price Array
	public static function price_get_addon_total( $price_array ) {

		$total_addon = 0;

		if ( $price_array ) {
			foreach ( $price_array as $price ) {

				if ( $price['apply'] != 'addon' ) {
					continue;
				}
				if ( ! isset( $price['price'] ) ) {
					continue;
				}

				$the_price = self::normalize_price_value( $price['price'] );
				$qty       = isset( $price['quantity'] ) ? self::normalize_price_value( $price['quantity'] ) : 0;

				$total_addon += ( $the_price * $qty );

				/*
				if( $price['type'] == 'quantities' || $price['type'] == 'bulkquantity' ) {
				$total_addon += ($price['price'] * $price['quantity']);
				} else {
				$total_addon += $price['price'];
				}*/
			}
		}

		return $total_addon;
	}

	// Get total cart_fee price of given Price Array
	public static function price_get_cart_fee_total( $price_array ) {

		$total_cart_fee = 0;

		if ( $price_array ) {
			foreach ( $price_array as $price ) {

				if ( $price['apply'] == 'cart_fee' ) {
					$total_cart_fee += self::normalize_price_value( $price['price'] );
				}
			}
		}

		return $total_cart_fee;
	}

	/**
	 * Coerce a raw addon price value to a float.
	 *
	 * Admins occasionally type currency symbols, spaces, or trailing labels
	 * into the price field (e.g. "$10", "10 USD"). PHP 8+ raises a fatal
	 * TypeError if such a value is added to an int, so any value that flows
	 * into pricing arithmetic must be normalized first.
	 *
	 * Delegates to wc_format_decimal() so locale separators (e.g. "1.000,50"
	 * on European stores) and currency symbols are stripped consistently with
	 * the rest of WooCommerce's price handling.
	 *
	 * @param mixed $value Raw price value as stored in field meta.
	 * @return float
	 */
	private static function normalize_price_value( $value ) {

		if ( is_int( $value ) || is_float( $value ) ) {
			return (float) $value;
		}

		if ( ! is_scalar( $value ) ) {
			return 0.0;
		}

		return (float) wc_format_decimal( (string) $value );
	}

	// Get total quantities
	public static function price_get_total_quantities( $ppom_fields_post, $product_id ) {

		$total_quantities = 0;

		foreach ( $ppom_fields_post as $data_name => $value ) {

			if ( $data_name == 'id' ) {
				continue;
			}

			if ( empty( $value ) ) {
				continue;
			}

			$field_meta = Helpers::get_field_meta_by_dataname( $product_id, $data_name );
			$field_type = isset( $field_meta['type'] ) ? $field_meta['type'] : '';

			switch ( $field_type ) {

				case 'quantities':
					// $total_quantities = 0;
					foreach ( $value as $option => $qty ) {
						$total_quantities += intval( $qty );
					}
					break;

				case 'vm':
					// $total_quantities = 0;
					foreach ( $value as $option => $qty ) {
						$total_quantities += intval( $qty );
					}
					break;

				case 'vqmatrix':
					// $total_quantities = 0;
					foreach ( $value as $option => $qty ) {
						$total_quantities += intval( $qty );
					}
					break;

				case 'bulkquantity':
					$total_quantities = 0;
					foreach ( $value as $option => $qty ) {
						// ppom_pa($qty);
						$total_quantities += intval( $qty );
					}
					break;

				case 'eventcalendar':
					$total_quantities = 0;
					foreach ( $value as $date => $ticket_meta ) {
						foreach ( $ticket_meta as $option => $qty ) {
							$total_quantities += intval( $qty );
						}
					}
					break;

			}
		}

		return apply_filters( 'ppom_prices_total_quantities', $total_quantities, $ppom_fields_post, $product_id );
	}

	// Get total bulkquantities
	public static function price_get_total_bulkquantities( $price_array, $product, $ppom_fields_post ) {

		$total_bulkquantities = 0;
		$total_bq_baseprice   = 0;
		if ( $price_array ) {
			foreach ( $price_array as $price ) {

				if ( $price['type'] == 'bulkquantity' ) {
					$total_bulkquantities += intval( $price['quantity'] );
				}
				$total_bq_baseprice += floatval( $price['base_price'] );
			}
		}

		// checking for base price
		$product_price = 0;
		foreach ( $ppom_fields_post as $dataname => $val ) {
			$meta = Helpers::get_field_meta_by_dataname( $product->get_id(), $dataname );
			if ( isset( $meta['type'] ) && $meta['type'] == 'bulkquantity' ) {
				$includeprice = apply_filters( 'ppom_bulkquantity_includeprice', '', $meta, $product );
				if ( $includeprice === 'on' ) {
					$product_price = $product->get_price();
				}
			}
		}


		$bq_data = array(
			'quantity'            => $total_bulkquantities,
			'base_price'          => $total_bq_baseprice,
			'includeproductprice' => $product_price,
		);

		return $bq_data;
	}

	// Get total fixedprice
	public static function price_get_total_fixedprice( $price_array ) {

		$total_fixedprice = 0;
		$total_fp_qty     = 0;

		if ( $price_array ) {
			foreach ( $price_array as $price ) {

				if ( $price['type'] == 'fixedprice' ) {
					$total_fixedprice += $price['price'];
					$total_fp_qty     += $price['quantity'];
				}
			}
		}

		$fixedprice_data = array(
			'quantity'   => $total_fp_qty,
			'base_price' => $total_fixedprice,
		);

		return $fixedprice_data;
	}

	// Get total fixedprice
	public static function price_get_total_measure( $price_array ) {
		$total_measure = 0;

		if ( $price_array ) {
			foreach ( $price_array as $price ) {
				if ( $price['type'] !== 'measure' ) {
					continue;
				}

				$measure = $price['quantity'];
				if ( isset( $price['price-multiplier'] ) && is_numeric( $price['price-multiplier'] ) ) {
					$measure *= floatval( $price['price-multiplier'] );
				}
			
				if ( $total_measure == 0 ) {
					$total_measure = $measure;
				} else {
					$total_measure *= $measure;
				}
			}
		}

		return $total_measure;
	}

	/**
	 * Resolves the base product price for a PPOM cart item.
	 *
	 * Applies matrix, quantity, fixed-price, and measure pricing before returning
	 * the base amount used in the final cart line total.
	 *
	 * @param float      $product_price      Product price before PPOM adjustments.
	 * @param WC_Product $product            Product object.
	 * @param array      $ppom_fields_post   Posted PPOM field values.
	 * @param float|int  $product_quantity   Product quantity.
	 * @param array      $ppom_field_prices  Normalized PPOM price rows.
	 * @param float|int  $ppom_discount      Discount accumulator passed by reference.
	 * @param array|null $ppom_pricematrix   Matched price matrix data.
	 *
	 * @return array
	 *
	 * @see self::get_field_prices()
	 * @see self::parse_price_matrix()
	 * @see self::price_controller()
	 */
	public static function price_get_product_base(
		$product_price,
		$product,
		$ppom_fields_post,
		$product_quantity,
		$ppom_field_prices,
		&$ppom_discount,
		$ppom_pricematrix = null
	) {

		// converting back to org price if Currency Switcher is used
		$base_price = Callbacks::convert_price_back( $product_price );
		// $base_price  = $product->get_price();
		// $base_price = floatval($base_price);
		// $base_price  = $product->get_price();
		// ppom_pa($product);   
		// var_dump($product_quantity);
		$product_id = Helpers::get_product_id( $product );
		// var_dump('varia',$product_id);

		$total_addon_price    = self::price_get_addon_total( $ppom_field_prices );
		$total_cart_fee_price = self::price_get_cart_fee_total( $ppom_field_prices );

		$source = 'product';

		$matrix_found = null;
		if ( $ppom_pricematrix ) {
			$matrix_found = self::parse_price_matrix( $ppom_pricematrix, $product, $product_quantity, $base_price, $total_addon_price, $total_cart_fee_price );
		}


		$quantities_found     = self::price_get_total_quantities( $ppom_fields_post, $product_id );
		$bulkquantities_found = self::price_get_total_bulkquantities( $ppom_field_prices, $product, $ppom_fields_post );
		$fixedprice_found     = self::price_get_total_fixedprice( $ppom_field_prices );
		$measure_found        = self::price_get_total_measure( $ppom_field_prices );
		// If price matrix found
		// ppom_pa($matrix_found);
		if ( $matrix_found ) {
			if ( $matrix_found['matrix_price'] > 0 ) {

				$base_price = $matrix_found['matrix_price'];
				$source     = 'matrix';
			} /*
			else if( isset($matrix_found['matrix_discount']) && $matrix_found['matrix_discount'] != '' ) {
			var_dump($total_addon_price);
			$matrix_discount = $matrix_found['matrix_discount'];
			if( $matrix_found['apply'] == 'both' ) {
				$base_price = ($base_price + $total_addon_price);
			}
			$base_price = floatval($base_price) - $matrix_discount;
			$source     = 'matrix_discount';
			}*/

		}

		// var_dump($quantities_found);
		// If quantities found
		if ( $quantities_found > 0 ) {

			if ( ! Helpers::is_cart_quantity_updatable( $product_id ) ) {
				// if quantities has price then no need to multiply with total quantities
				// just use 1
				$qty        = 1;
				$base_price = $base_price * $qty;
			}
		}

		// ppom_pa($bulkquantities_found);
		// If Bulkquantities found, no base price is effective
		if ( $bulkquantities_found['quantity'] > 0 ) {
			$base_price = $bulkquantities_found['base_price'] + $bulkquantities_found['includeproductprice'];
			$source     = 'bulkquantities';
		}

		// If Fixedprice found, Set base price
		if ( $fixedprice_found['quantity'] > 0 ) {
			$base_price = 0;
			$source     = 'fixedprice';
		}

		// If Measure found, Set base price
		if ( $measure_found > 0 ) {
			$base_price *= $measure_found;
			$source      = 'measure';
		}

		$price_info = array(
			'price'  => $base_price,
			'source' => $source,
		);

		return apply_filters( 'ppom_price_info', $price_info, $product, $ppom_fields_post, $ppom_field_prices );
	}

	// If price set by pricematrix in cart return matrix
	public static function price_matrix_chunk( $product, $pricematrix_fields, $product_quantity ) {

		$matrix_found = array();
		$pm_applied   = array();


		if ( count( $pricematrix_fields ) > 0 ) {

			foreach ( $pricematrix_fields as $pm ) {

				$pm_dataname = isset( $pm['data_name'] ) ? $pm['data_name'] : '';
				// var_dump($pm_dataname, Helpers::is_field_hidden_by_condition( $pm_dataname ));

				if ( Helpers::is_field_hidden_by_condition( $pm_dataname ) ) {
					continue;
				}

				$pm_applied = $pm;
				break;
			}
			$matrix_found = Helpers::extract_matrix_by_quantity( $pm_applied, $product, $product_quantity );
			// ppom_pa($matrix_found); exit;
		}

		return apply_filters( 'ppom_price_matrix_chunk_cart', $matrix_found, $product, $pm_applied );
	}

	// If Bulkquantity add-on is used, get it's chunk
	public static function price_bulkquantity_chunk( $product, $bulkquantity_options, $product_quantity ) {

		$bq_found = array();

		if ( count( $bulkquantity_options ) > 0 ) {

			foreach ( $bulkquantity_options as $bq ) {

				// ppom_pa($bq);
				$range       = $bq['Quantity Range'];
				$range_array = explode( '-', $range );
				$range_start = intval( $range_array[0] );
				$range_end   = intval( $range_array[1] );

				// var_dump($bq);
				$quantity = intval( $product_quantity );
				if ( $quantity >= $range_start && $quantity <= $range_end ) {
					$bq_found = $bq;
					break;
				}
			}
		}

		return apply_filters( 'ppom_price_bulkquantity_chunk_cart', $bq_found, $product );
	}


	// If Bulkquantity add-on is used, get it's chunk
	public static function price_fixedprice_chunk( $product, $fixedprice_options, $product_quantity ) {

		$fixedprice_found = array();

		if ( count( $fixedprice_options ) > 0 ) {

			foreach ( $fixedprice_options as $fp ) {

				$fp_dataname = isset( $fp['data_name'] ) ? $fp['data_name'] : '';
				if ( Helpers::is_field_hidden_by_condition( $fp_dataname ) ) {
					continue;
				}

				if ( $fp['raw'] == $product_quantity ) {
					$fixedprice_found = $fp;
					break;
				}
			}
		}

		return apply_filters( 'ppom_price_fixedprice_chunk_cart', $fixedprice_found, $product );
	}

	// Cart fees.

	/**
	 * Adds PPOM cart fees and discounts to the WooCommerce cart.
	 *
	 * @param WC_Cart $cart WooCommerce cart.
	 *
	 * @return void
	 *
	 * @see self::get_field_prices()
	 * @see self::price_has_discount_matrix()
	 * @see self::price_controller()
	 */
	public static function price_cart_fee( $cart ) {
		$fee_no       = 1;
		$cart_counter = 1;
		foreach ( $cart->get_cart() as $item ) {

			if ( ! isset( $item['ppom']['fields'] ) ) {
				continue;
			}

			$product           = $item['data'];
			$ppom_fields_post  = $item['ppom']['fields'];
			$product_id        = $item['product_id'];
			$variation_id      = isset( $item['variation_id'] ) ? $item['variation_id'] : '';
			$quantity          = $item['quantity'];
			$ppom_field_prices = self::get_field_prices( $ppom_fields_post, $product_id, $quantity, $variation_id, $item );
			// ppom_pa($ppom_field_prices);

			// Thing to remember:
			// This is not product price, it will be price in cart item
			$cart_item_price = floatval( $product->get_price() );

			if ( $matrix_found = self::price_has_discount_matrix( $product, $quantity ) ) {

				// $price_tobe_discount = $cart_item_price * $quantity; NOTE: This has to be check
				$native_product      = wc_get_product( $product_id );
				$price_tobe_discount = Helpers::get_product_price( $native_product ) * $quantity;
				if ( $matrix_found['discount'] == 'both' ) {
					$total_addon_price    = self::price_get_addon_total( $ppom_field_prices );
					$total_cart_fee_price = self::price_get_cart_fee_total( $ppom_field_prices );
					$price_tobe_discount  = ( $cart_item_price * $quantity ) + $total_cart_fee_price;
				}

				// var_dump($price_tobe_discount);


				if ( ! empty( $matrix_found['percent'] ) ) {
					$matrix_discount = self::get_amount_after_percentage( $price_tobe_discount, $matrix_found['percent'] );
				} else {
					$matrix_discount = $matrix_found['raw_price'];
				}
				$discount_label   = $matrix_found['label'];
				$matrix_discount  = floatval( $matrix_discount );
				$discount_taxable = apply_filters( 'ppom_matrix_discount_taxable', false, $item, $cart );
				$cart->fees_api()->add_fee(
					array(
						'id'        => 'ppom_matrix_fee_' . $cart_counter,
						'name'      => esc_html( $discount_label ),
						'amount'    => -abs( (float) $matrix_discount ),
						'taxable'   => $discount_taxable,
						'tax_class' => '',
					)
				);
				// ppom_pa($discount_label);
			}

			foreach ( $ppom_field_prices as $fee ) {

				if ( $fee['apply'] != 'cart_fee' ) {
					continue;
				}

				$label        = $fee['label'];
				$option_label = isset( $fee['option_label'] ) ? $fee['option_label'] : '';
				$fee_price    = apply_filters( 'ppom_option_price', $fee['price'] );
				$taxable      = $fee['taxable']; // deprecated soon

				$label = "{$label}";
				if ( $option_label ) {
					$label .= " ({$option_label})";
				}
				$label = apply_filters( 'ppom_fixed_fee_label', $label, $fee, $item );


				if ( ! empty( $fee['without_tax'] ) ) {
					$fee_price = $fee['without_tax'];
				}

				$taxable = Helpers::get_option( 'ppom_taxable_fixed_price' );
				$taxable = $taxable == 'yes' ? true : false;
				// var_dump($taxable);

				$fee_price = apply_filters( 'ppom_cart_fixed_fee', $fee_price, $fee, $cart );
				$taxable   = apply_filters( 'ppom_cart_fixed_fee_taxable', $taxable, $fee, $cart );

				if ( $fee_price != 0 ) {
					$tax_class = $product->get_tax_class( 'unfiltered' );

					// if wc prices include tax: substract the tax from additional fixed fee since already WC will add tax.
					if ( wc_prices_include_tax() ) {
						$tax = \WC_Tax::calc_tax( $fee_price, \WC_Tax::get_rates( $tax_class ), true );

						$total_tax = array_sum( $tax );
						$fee_price = $fee_price - $total_tax;
					}

					$cart->fees_api()->add_fee(
						array(
							'id'        => 'ppom_fee_' . $fee_no,
							'name'      => esc_html( $label ),
							'amount'    => (float) $fee_price,
							'taxable'   => $taxable,
							'tax_class' => $tax_class,
						)
					);
					++$fee_no;
				}
			}

			++$cart_counter;
		}
	}

	// Check if price is being pulled by matrix
	public static function price_is_matrix_found( $product, $product_quantity, $base_price, $addon_price, $cart_fee ) {

		$matrix_discount = 0.0;
		$matrix_price    = 0.0;
		// Check if Price Matrix is used
		$pricematrix_field = Helpers::has_field_by_type( Helpers::get_product_id( $product ), 'pricematrix' );
		if ( ! $pricematrix_field ) {
			return null;
		}

		$matrix_found = self::price_matrix_chunk( $product, $pricematrix_field, $product_quantity );
		// ppom_pa($matrix_found);

		if ( isset( $matrix_found['discount'] ) ) {
			if ( ! empty( $matrix_found['percent'] ) ) {

				// If discount only on BASE Price
				$price_tobe_discount = $base_price;
				// If discount only on BASE Price + Options
				if ( $matrix_found['discount'] == 'both' ) {
					$price_tobe_discount += $addon_price + $cart_fee;
				}

				$matrix_discount = self::get_amount_after_percentage( $price_tobe_discount, $matrix_found['percent'] );
				$matrix_discount = floatval( $matrix_discount );
				// var_dump($price_tobe_discount);
			} else {
				$matrix_discount = isset( $matrix_found['raw_price'] ) ? floatval( $matrix_found['raw_price'] ) : 0;
			}
		} else {
			$matrix_price = isset( $matrix_found['raw_price'] ) ? $matrix_found['raw_price'] : $base_price;
		}
		$matrix = array(
			'matrix_price'    => $matrix_price,
			'matrix_discount' => $matrix_discount,
		);

		return apply_filters( 'ppom_price_is_matrix_found', $matrix, $product );
	}

	public static function parse_price_matrix( $ppom_pricematrix, $product, $product_quantity, $base_price, $addon_price, $cart_fee ) {

		$matrix_discount = 0.0;
		$matrix_price    = 0.0;
		$matrix_found    = Helpers::extract_matrix_by_quantity( $ppom_pricematrix, $product, $product_quantity );
		// ppom_pa($matrix_found);
		if ( isset( $matrix_found['discount'] ) ) {
			if ( ! empty( $matrix_found['percent'] ) ) {

				// If discount only on BASE Price
				$price_tobe_discount = $base_price;
				// If discount only on BASE Price + Options
				if ( $matrix_found['discount'] == 'both' ) {
					$price_tobe_discount += $addon_price + $cart_fee;
				}

				$matrix_discount = self::get_amount_after_percentage( $price_tobe_discount, $matrix_found['percent'] );
				$matrix_discount = floatval( $matrix_discount );
				// var_dump($price_tobe_discount);
			} else {
				$matrix_discount = isset( $matrix_found['raw_price'] ) ? floatval( $matrix_found['raw_price'] ) : 0;
			}
		} elseif ( isset( $matrix_found['matrix_fixed'] ) ) {
			$matrix_price = isset( $matrix_found['raw_price'] ) ? $matrix_found['raw_price'] / $product_quantity : $base_price;
		} else {
			$matrix_price = isset( $matrix_found['raw_price'] ) ? $matrix_found['raw_price'] : $base_price;
		}

		$matrix = array(
			'matrix_price'    => $matrix_price,
			'matrix_discount' => $matrix_discount,
		);

		return apply_filters( 'ppom_price_is_matrix_found', $matrix, $product );
	}

	public static function is_field_has_price( $meta ) {

		$type      = isset( $meta['type'] ) ? $meta['type'] : '';
		$has_price = false;
		switch ( $type ) {

			case 'selectqty':
			case 'vqmatrix':
			case 'quantities':
			case 'qtypack':
				if ( isset( $meta['default_price'] ) && $meta['default_price'] != '' ) {
					$has_price = true;
					break;
				}

				if ( isset( $meta['options'] ) ) {
					foreach ( $meta['options'] as $option ) {
						if ( isset( $option['price'] ) && $option['price'] != '' ) {
							$has_price = true;
							break;
						}
					}
				}
				break;

			case 'eventcalendar':
				if ( isset( $meta['options'] ) ) {
					foreach ( $meta['options'] as $option ) {
						if ( isset( $option['price'] ) && $option['price'] != '' ) {
							$has_price = true;
							break;
						}
					}
				}
				break;

			case 'file':
				if ( isset( $meta['file_cost'] ) && $meta['file_cost'] != '' ) {
					$has_price = true;
				}
				break;

			default:
				if ( isset( $meta['options'] ) ) {
					foreach ( $meta['options'] as $option ) {
						if ( isset( $option['price'] ) && $option['price'] != '' ) {
							$has_price = true;
							break;
						}
					}
				}
				break;

		}

		return apply_filters( 'ppom_field_has_price', $has_price, $meta );
	}

	// Check if product has discount price matrix
	// Return percent
	public static function price_has_discount_matrix( $product, $quantity ) {

		$pricematrix_field = Helpers::has_field_by_type( Helpers::get_product_id( $product ), 'pricematrix' );
		if ( ! $pricematrix_field ) {
			return false;
		}

		$matrix_found = self::price_matrix_chunk( $product, $pricematrix_field, $quantity );
		// ppom_pa($matrix_found);

		if ( ! isset( $matrix_found['discount'] ) ) {
			return false;
		}

		return $matrix_found;
	}

	// Return ammount after apply percent
	public static function get_amount_after_percentage( $base_amount, $percent ) {

		$base_amount    = floatval( $base_amount );
		$percent_amount = 0;
		$percent        = substr( $percent, 0, - 1 );
		$percent_amount = wc_format_decimal( ( floatval( $percent ) / 100 ) * $base_amount, wc_get_price_decimals() );

		return $percent_amount;
	}

	// Checking the price matrix
	public static function price_check_price_matrix( $cart_items, $values ) {

		if ( ! isset( $cart_items['ppom'] ) ) {
			return $cart_items;
		}
		// ppom_pa($cart_items);

		$wc_product = $cart_items['data'];
		$product_id = Helpers::get_product_id( $wc_product );

		$pricematrix_field = Helpers::has_field_by_type( $product_id, 'pricematrix' );
		if ( ! $pricematrix_field ) {
			return $cart_items;
		}

		$matrix_found = array();
		foreach ( $pricematrix_field as $pm ) {

			$pm_dataname          = isset( $pm['data_name'] ) ? $pm['data_name'] : '';
			$conditionally_hidden = isset( $cart_items['ppom']['conditionally_hidden'] )
				? $cart_items['ppom']['conditionally_hidden']
				: '';
			if ( Helpers::is_field_hidden_by_condition( $pm_dataname, $conditionally_hidden ) ) {
				continue;
			}

			$matrix_found = $pm;
			break;
		}

		// ppom_pa($pm_applied);
		// $matrix_found = Helpers::extract_matrix_by_quantity($pm_applied, $wc_product, $product_quantity);
		$cart_items['ppom']['price_matrix_found'] = apply_filters( 'ppom_price_marix_found', $matrix_found, $cart_items );

		return $cart_items;
	}

	public static function option_price_handle_vat( $option_price, $product ) {

		if ( ! function_exists( 'wc_get_price_excluding_tax' ) || $option_price == '' ) {
			return $option_price;
		}
		
		$taxable_option_price = Helpers::get_option( 'ppom_taxable_option_price' );

		if ( 'yes' !== $taxable_option_price ) {
			if ( false === $taxable_option_price || null === $taxable_option_price ) {
				if ( ! wc_tax_enabled() ) {
					return $option_price;
				}
			} else {
				return $option_price;
			}
		}

		if ( $option_price >= 0 && ( ! is_product() && apply_filters( 'ppom_handle_option_price_vat_in_cart', true ) === true ) ) {
			$vat_type = get_option( 'woocommerce_tax_display_cart' );
			$args     = array(
				'price'    => $option_price,
				'quantity' => 1,
			);
			if ( $vat_type == 'excl' ) {
				$option_price = wc_get_price_excluding_tax( $product, $args );
			} else {
				$option_price = wc_get_price_including_tax( $product, $args );
			}
		}

		if ( $option_price >= 0 && ( is_product() && apply_filters( 'ppom_handle_option_price_vat_in_product', true ) === true ) ) {
			$vat_type = get_option( 'woocommerce_tax_display_shop' );
			$args     = array(
				'price'    => $option_price,
				'quantity' => 1,
			);
			if ( $vat_type == 'excl' ) {
				$option_price = wc_get_price_excluding_tax( $product, $args );
			} else {
				$option_price = wc_get_price_including_tax( $product, $args );
			}
		}

		return $option_price;
	}

	// Wholesale (WWP) plugin: Cart price handling
	public static function wwp_product_cart_price( $product_price, $cart_content ) {

		// Wholesale price
		if ( isset( $cart_content['data']->wwp_data['wholesale_priced'] ) && $cart_content['data']->wwp_data['wholesale_priced'] == 'yes' ) {
			$product_price = $cart_content['data']->get_price();
		}

		return $product_price;
	}
}
