<?php

/**
 * The file that defines the WooCommerce quote plugin integration class
 *
 * @link       https://wpconfiguratorbuilder.com
 * @since      1.0.0
 *
 * @package    wcb-configurator-builder
 * @subpackage wcb-configurator-builder/includes
 */

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

/**
 * The plugin WooCommerce quote class.
 *
 * This is used to define support for WooCommerce Quotes plugins and maintain its data.
 *
 * @since      1.0.0
 * @package    wcb-configurator-builder
 * @subpackage wcb-configurator-builder/includes/woocommerce
 * @author     WPCB <support@wpconfiguratorbuilder.com>
 */

class WPCB_Quote {

	public function __construct() {

		add_action( 'ywraq_before_request_quote_view_item', function( $raq_data, $key ) {
			global $key;
		}, 10, 2 );

		add_action( 'ywraq_from_cart_to_order_item', array( $this, 'add_order_item_meta' ), 10, 3 );
		add_action( 'ywraq_quote_adjust_price', array( $this, 'adjust_ywraq_quote_item_price' ), 10, 2 );

		add_filter( 'ywraq_add_item',  array( $this, 'add_ywraq_item_to_quote' ), 10, 2 );
		add_filter( 'ywraq_item_data', array( $this, 'get_ywraq_quote_item_data' ), 10, 2 );
		add_filter( 'ywraq_request_quote_view_item_data', array( $this, 'get_ywraq_quote_item_data' ), 10, 2 );
		add_filter( 'ywraq_product_image', array( $this,'get_ywraq_quote_item_image' ), 10, 2 );
		add_filter( 'ywraq_quote_item_thumbnail', array( $this, 'change_ywraq_quote_item_image' ), 10, 3 );
		add_action( 'ywraq_request_quote_email_view_item_after_title', array( $this, 'display_ywraq_quote_item_data' ), 10, 3 );
		add_filter( 'woocommerce_admin_order_item_thumbnail', array( $this, 'change_ywraq_quote_item_image' ), 10, 3 );

		add_filter( 'addify_quote_item_thumbnail',  array( $this, 'show_addify_quote_image' ), 10, 3 );
		add_filter( 'woocommerce_admin_order_item_thumbnail',  array( $this, 'show_addify_quote_image_admin' ), 10, 3 );

		add_filter( 'addify_add_quote_item_data', array( $this, 'add_addify_quote_data' ), 10, 5 );
		add_filter( 'addify_quote_item_product', array( $this, 'modify_addify_product_data' ), 10, 3 );
		add_filter( 'woocommerce_get_item_data', array( $this,'get_addify_quote_item_data' ), 10, 3 );

	}

	/**
	 * Show custom WCB quote image in admin page
	 *
	 * @since    1.1.0
	 */
	public function show_addify_quote_image_admin( $image, $item_id, $item ) {
		if ( isset( $item['wpcb_image'] ) ) {
			global $wp_smiliessearch;
			$wp_smiliessearch = null;

			$image_src = $item['wpcb_image'];
            $image_src = apply_filters( 'wpcb_quote_thumbnail_image_url', $image_src, $item );

			return '<img src="' . $image_src . '" />';
		}

		return $image;
	}

	/**
	 * Show custom WCB quote image on frontend
	 *
	 * @since    1.1.0
	 */
	public function show_addify_quote_image( $image, $quote_item, $quote_item_key ) {
		if ( isset( $quote_item['wpcb_image'] ) ) {
			$image_url = $quote_item['wpcb_image'];
            $image_url = apply_filters( 'wpcb_quote_thumbnail_image_url', $image_url, $quote_item );

			return '<img src="' . $image_url . '" />';
		}

		return $image;
	}

	/**
	 * Add custom WCB configuration data to quote item
	 *
	 * @since    1.1.0
	 */
	public function add_addify_quote_data( $quote_item_data, $product_id, $variation_id, $quantity, $form_data ) {
		if ( wpcb_product_has_configurator( $product_id ) ) {
			$configuration_json = array();

			if ( isset( $form_data['wpcb_configuration_data'] ) ) {
				$json = base64_decode( wp_unslash( $form_data['wpcb_configuration_data'] ) );
				$configuration_json = json_decode( $json, true );
			}

			$quote_item_data = $this->format_quote_data( $quote_item_data, $configuration_json, $product_id );
		}

		return $quote_item_data;
	}

	/**
	 * Modify custom WCB quote product data
	 *
	 * @since    1.1.0
	 */
	public function modify_addify_product_data( $product, $quote_item, $quote_item_key ) {
		if ( isset( $quote_item['wpcb_price'] ) ) {
			$product->set_price( $quote_item['wpcb_price'] );
		}
		if ( isset( $quote_item['wpcb_sku'] ) ) {
			$product->set_sku( $quote_item['wpcb_sku'] );
		}
		return $product;
	}

	/**
	 * Display custom WCB quote item product meta
	 *
	 * @since    1.1.0
	 */
	public function get_addify_quote_item_data( $item_data, $quote_item ) {
		if ( isset( $quote_item['wpcb_item_data'] ) ) {
			foreach ( $quote_item['wpcb_item_data'] as $value ) {
				$item_data[] = $value;
			}
		}
		return $item_data;
	}

	/**
	 * Add custom WCB configuration data to quote item
	 *
	 * @since    1.1.0
	 */
	public function add_ywraq_item_to_quote( $raq, $post_data ) {
		$product_id = $post_data['product_id'];

		if ( wpcb_product_has_configurator( $product_id ) ) {
			$configuration_json = array();

			if ( isset( $post_data['wpcb_configuration_data'] ) ) {
				$json = base64_decode( wp_unslash( $post_data['wpcb_configuration_data'] ) );
				$configuration_json = json_decode( $json, true );
			}

			$raq = $this->format_quote_data( $raq, $configuration_json, $product_id );
		}

		return $raq;
	}

	/**
	 * Show addon image replaced on product page
	 *
	 * @param string  $image   The image URL.
	 * @param Object  $raq     The RAQ content.
	 *
	 * @return mixed|string
	 */
	public function get_ywraq_quote_item_image( $image, $raq ) {
		if ( isset( $raq['wpcb_image'] ) ) {
			global $wp_smiliessearch;
			$wp_smiliessearch = null;

			$image_url = $raq['wpcb_image'];
            $image_src = apply_filters( 'wpcb_quote_thumbnail_image_url', $raq['wpcb_image'], $raq );

			$image = '<img src="' . $image_url . '" />';
		}

		global $key;
		if ( $key && isset( $raq['raq_content'][ $key ]['wpcb_image'] ) ) {
			// Email. return src.
			if ( strpos( $raq['raq_content'][ $key ]['wpcb_image'], 'http' ) !== -1 ) {
				$image_src = urldecode( $raq['raq_content'][ $key ]['image'] );
			} else {
				$image_src = $raq['raq_content'][ $key ]['wpcb_image'];
			}
			return $image_src;
		}

		return $image;
	}

	/**
	 * Set custom WCB price for quote product
	 *
	 * @param array      $values
	 * @param WC_Product $_product
	 */
	public function adjust_ywraq_quote_item_price( $values, $_product ) {
		if ( isset( $values['wpcb_price'] ) && ! empty( $values['wpcb_price'] ) ) {
			$_product->set_price( $values['wpcb_price'] );
		}

		if ( isset( $values['wpcb_sku'] ) && $values['wpcb_sku'] ) {
			$_product->set_sku( $values['wpcb_sku'] );
		}
	}

	/**
	 * Get custom configuration item options in quote item
	 *
	 * @since    1.1.0
	 */
	public function get_ywraq_quote_item_data( $item_data, $raq ) {
		if ( isset( $raq['wpcb_item_data'] ) ) {
			foreach ( $raq['wpcb_item_data'] as $value ) {
				$item_data[] = $value;
			}
		}
		return $item_data;
	}

	/**
	 * Show custom configuration item options in quote item
	 *
	 * @since    1.1.0
	 */
	public function display_ywraq_quote_item_data( $item, $raq, $key ) {
		$show_price = ! ( 'yes' === get_option( 'ywraq_quote_my_account_hide_price_new_quote', 'yes' ) || 'yes' === get_option( 'ywraq_hide_price' ) );

		if ( isset( $raq['raq_content'][$key]['wpcb_item_data'] ) ) {
			echo yith_ywraq_get_product_meta( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				$raq['raq_content'][$key],
				true,
				$show_price
			);
		}
	}

	/**
	 * Add order item meta when creating the order
	 *
	 * @param array  $values        .
	 * @param string $cart_item_key Cart item key.
	 * @param int    $item_id       Item id.
	 */
	public function add_order_item_meta( $values, $cart_item_key, $item_id ) {
		if ( isset( $values['item_data'] ) && ! empty( $values['item_data'] ) ) {
			foreach ( $values['item_data'] as $label => $val ) {
				$name = $label;
				$value = $val;

				wc_add_order_item_meta( $item_id, $name, $value );
			}
		}

		if ( isset( $values['wpcb_product_selections'] ) ) {
			$product_data = [
				'selection' => $values['wpcb_product_selections'],
			];
			$data = [];
			$data = $this->format_quote_data( $data, $product_data, $values['data']->get_id() );

			foreach ( $data['wpcb_item_data'] as $val ) {
				wc_add_order_item_meta( $item_id, $val['key'], $val['value'] );
			}
		}

		if ( isset( $values['wpcb_price'] ) ) {
			wc_add_order_item_meta( $item_id, '_wpcb_price', $values['wpcb_price'] );
		}

		if ( isset( $values['wpcb_product_price'] ) ) {
			wc_add_order_item_meta( $item_id, '_wpcb_price', $values['wpcb_product_price'] );
		}

		if ( isset( $values['wpcb_image'] ) ) {
			wc_add_order_item_meta( $item_id, '_wpcb_image', $values['wpcb_image'] );
		}
		
		if ( isset( $values['wpcb_product_image'] ) ) {
			wc_add_order_item_meta( $item_id, '_wpcb_image', $values['wpcb_product_image'] );
		}
	}

	/**
	 * See product image on admin order page
	 *
	 * @param string $product_image The product image HTML.
	 * @param int    $item_id       The cart item array.
	 * @param bool   $item          The cart item key.
	 */
	public function change_ywraq_quote_item_image( $product_image, $item_id, $item ) {
		$image_url = urldecode( wc_get_order_item_meta( $item_id, '_wpcb_image' ) );

		if ( $image_url ) {
			global $wp_smiliessearch;
			$wp_smiliessearch = null;

			$product_image = '<img src="' . $image_url . '" />';
		}

		return $product_image;
	}

	/**
	 * Find correct image url in saved order meta data
	 *
	 * @since    1.1.0
	 */
	public function display_quote_product_image( $thumb_url ) {
		global $item;

		if ( $item && $meta_data = $item->get_meta_data() ) {
			$image_url = false;
			foreach ( $meta_data as $meta_obj ) {
				if ( $meta_obj->key == '_wpcb_image' ) {
					$image_url = $meta_obj->value;
					break;
				}

				if ( $meta_obj->key == '_wpcb_product_image' ) {
					$image_url = $meta_obj->value;
					break;
				}
			}

			if ( $image_url ) {
				$thumb_url = $image_url;
			}
		}

		return $thumb_url;
	}

	/**
	 * Helper function to convert configuration to quote data
	 *
	 * @since    1.1.0
	 */
	private function format_quote_data( $quote_item_data, $configuration_json, $product_id ) {

		// Set custom image
		if ( isset( $configuration_json['renders'] ) && is_array( $configuration_json['renders'] ) && count( $configuration_json['renders'] ) > 0 ) {
			$imagedata = $configuration_json['renders'][0];

			if ( wpcb_get_option( 'wpcb_checkout_show_image' ) || wpcb_get_option( 'wpcb_checkout_order_show_image' ) || wpcb_get_option( 'wpcb_checkout_email_show_image' ) ) {
				$config_name = wpcb_generate_configuration_name();
				$imagedata = wpcb_store_configuration_image( $config_name, $imagedata );
			}

			$quote_item_data['wpcb_image'] = $imagedata;
		}

		// Set options array.
		$configurator_id = isset( $configuration_json['configurator_id'] ) ? sanitize_key( $configuration_json['configurator_id'] ) : 0;
		$product_selections = isset( $configuration_json['selection'] ) ? filter_var_array( $configuration_json['selection'] ) : array();
		if ( is_array( $product_selections ) && count( $product_selections ) > 0 ) {
			$item_data = array();

			$forbidden_labels = array();
			if ( wpcb_get_option( 'wpcb_checkout_forbidden_option_labels' ) ) {
				$forbidden_labels = array_map( 'trim', explode( ',', wpcb_get_option( 'wpcb_checkout_forbidden_option_labels' ) ) );
			}

			foreach ( $product_selections as $selection ) {
				if ( ! isset( $selection['label'] ) || '' === $selection['label'] ) {
					continue;
				}
				if ( in_array( $selection['label'], $forbidden_labels ) ) {
					continue;
				}
				if ( ! isset( $selection['values'] ) || ! is_array( $selection['values'] ) ) {
					continue;
				}

				if ( isset( $selection['format'] ) && '' !== $selection['format'] ) {
					$format_value = $selection['value'];

					$item_data[] = array(
						'key'  => $selection['label'],
						'value' => $format_value,
					);
				}
				else if ( count( $selection['values'] ) > 1 ) {
					$subvalues   = '';
					$value_count = count( $selection['values'] );

					foreach ( $selection['values'] as $option_index => $option_value ) {
						if ( isset( $option_value['values'] ) && count( $option_value['values'] ) > 0 ) {
							if ( count( $option_value['values'] ) > 1 ) {
								$subvalues .= '<br><span class="subitem">' . $option_value['label'] . ': ';
								$subval_count = count( $option_value['values'] );

								foreach ( $option_value['values'] as $subkey => $subval ) {
									if ( isset( $subval['product_id'] ) && is_numeric( $subval['product_id'] ) ) {
										$subvalues .= $subval['label'] . ': ' . $subval['value'];
									} 
									else if ( isset( $subval['input_type'] ) && 'file' === $subval['input_type'] ) {
										$subvalues .= $subval['label'];
									}
									else {
										$subvalues .= $subval['value'];
									}

									if ( $subkey + 1 < $subval_count ) {
										$subvalues .= ', ';
									}
								}
							} else {
								if ( isset( $option_value['values'][0]['product_id'] ) && is_numeric( $option_value['values'][0]['product_id'] ) ) {
									$subvalues .= '<br><span class="subitem">' . $option_value['values'][0]['label'] . ': ' . $option_value['values'][0]['value'] . '</span>';
								} 
								else if ( 'file' === $option_value['values'][0]['input_type'] ) {
									$subvalues .= '<br><span class="subitem">' . $option_value['label'] . ': ' . $option_value['values'][0]['label'] . '</span>';
								} 
								else {
									$subvalues .= '<br><span class="subitem">' . $option_value['label'] . ': ' . $option_value['values'][0]['value'] . '</span>';
								}

								if ( $option_index + 1 < $value_count ) {
									$subvalues .= ', ';
								}
							}
						} else {
							if ( isset( $option_value['product_id'] ) && is_numeric( $option_value['product_id'] ) ) {
								$subvalues .= $option_value['label'] . ': ' . $option_value['value'];
							} 
							else if ( 'file' === $option_value['input_type'] ) {
								$subvalues .= $option_value['label'];
							}
							else {
								$subvalues .= $option_value['value'];
							}

							if ( $option_index + 1 < $value_count ) {
								$subvalues .= ', ';
							}
						}
					}

					$item_data[] = array(
						'key'  => $selection['label'],
						'value' => $subvalues,
					);

				} else if ( count( $selection['values'] ) > 0 ) {
					
					$select_val = '';
					foreach ( $selection['values'] as $meta_index => $meta_value ) {
						if ( isset( $meta_value['product_id'] ) && is_numeric( $meta_value['product_id'] ) ) {
							$option_val = $meta_value['label'] . ': ' . $meta_value['value'];
						} 
						else if ( isset( $meta_value['input_type'] ) && 'file' === $meta_value['input_type'] ) {
							$option_val = $meta_value['label'];
						}
						else {
							$option_val = $meta_value['value'];
						}

						$select_val .= $option_val;
						if ( sizeof( $selection['values'] ) > $meta_index + 1) {
							$select_val .= ', ';
						}
					}

					$item_data[] = array(
						'key'  => $selection['label'],
						'value' => $select_val,
					);
				}
			}

			$quote_item_data['wpcb_item_data'] = $item_data;
		}

		// Set custom totals
		if ( isset( $configuration_json['totals']['total_price'] ) ) {
			// Recalculate pricings and set final price
			$configurator_totals = wpcb_get_configurator_cart_totals( $configurator_id, $product_id, $product_selections, $configuration_json['totals'] );

			// Set correct price for cart to prevent duplicate taxes.
			$include_tax = get_option( 'woocommerce_prices_include_tax' );
			$tax_display = get_option( 'woocommerce_tax_display_shop' );

			if ( ( 'no' === $include_tax && 'incl' === $tax_display ) || ( 'yes' === $include_tax && 'excl' === $tax_display ) ) { 
				$quote_item_data['wpcb_price'] = $configurator_totals['subtotal_price'];

				if ( $configurator_totals['subtotal_sale'] && $configurator_totals['subtotal_sale'] < $configurator_totals['subtotal_price'] ) {
					$quote_item_data['wpcb_price'] = $configurator_totals['subtotal_sale'];
				}
			} else {
				$quote_item_data['wpcb_price'] = $configurator_totals['total_price'];
				if ( $configurator_totals['sale_price'] && $configurator_totals['sale_price'] < $configurator_totals['total_price'] ) {
					$quote_item_data['wpcb_price'] = $configurator_totals['sale_price'];
				}
			}
		}

		if ( isset( $configuration_json['totals']['product_sku'] ) ) {
			$quote_item_data['wpcb_sku'] = $configuration_json['totals']['product_sku'];
		}

		if ( function_exists( 'wpcb_collect_configuration_item_stats' ) && isset( $configuration_json['configurator_id']) ) {
			wpcb_collect_configuration_item_stats( $configuration_json['configurator_id'], $product_selections );
		}

		return $quote_item_data;
	}
}
