<?php
/**
 * TI WooCommerce Wishlist integration with:
 *
 * @name WooCommerce Gravity Forms Product Add-Ons
 *
 * @version 3.3.26
 *
 * @slug woocommerce-gravityforms-product-addons
 *
 * @url https://woocommerce.com/products/gravity-forms-add-ons/
 *
 */

// If this file is called directly, abort.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// Load integration depends on current settings.
global $tinvwl_integrations;

$slug = "woocommerce-gravityforms-product-addons";

$name = "WooCommerce Gravity Forms Product Add-Ons";

$available = class_exists( 'WC_GFPA_Main' );

$tinvwl_integrations = is_array( $tinvwl_integrations ) ? $tinvwl_integrations : [];

$tinvwl_integrations[ $slug ] = array(
	'name'      => $name,
	'available' => $available,
);

if ( ! tinv_get_option( 'integrations', $slug ) ) {
	return;
}

if ( ! $available ) {
	return;
}

if ( ! function_exists( 'tinv_wishlist_metasupport_wc_gf_addons' ) ) {

	/**
	 * Set description for meta WooCommerce - Gravity Forms Product Add-Ons
	 *
	 * @param array $meta Meta array.
	 *
	 * @return array
	 */
	function tinv_wishlist_metasupport_wc_gf_addons( $meta ) {
		if ( array_key_exists( 'wc_gforms_form_id', $meta ) && class_exists( 'RGFormsModel' ) ) {
			$form_meta = RGFormsModel::get_form_meta( $meta['wc_gforms_form_id']['display'] );

			if ( array_key_exists( 'fields', $form_meta ) ) {
				$_meta = array();
				foreach ( $form_meta['fields'] as $field ) {

					if ( isset( $field['displayOnly'] ) && $field['displayOnly'] ) {
						continue;
					}

					$field_name = $field->get_first_input_id( array( 'id' => 0 ) );

					if ( array_key_exists( $field_name, $meta ) ) {

						if ( $field['type'] == 'product' ) {
							$inputs = $field instanceof GF_Field ? $field->get_entry_inputs() : rgar( $field, 'inputs' );
							if ( is_array( $inputs ) ) {
								$value = array();
								foreach ( $inputs as $input ) {
									$full_name = 'input_' . str_replace( '.', '_', $input['id'] );
									if ( $field_name == $full_name ) {
										continue;
									}
									if ( array_key_exists( $full_name, $meta ) ) {
										$value[] = $field->inputs[ array_search( $input['id'], array_column( $field->inputs, 'id' ) ) ]['label'] . ': ' . $meta[ $full_name ]['display'];
									}
								}

								$meta[ $field_name ]['display'] = ( is_array( $value ) ) ? implode( ', ', $value ) : '-';
							}
						}

						$meta[ $field_name ]['key'] = $field->label;
						$_meta[ $field_name ]       = $meta[ $field_name ];

					}
				}
				$meta = $_meta;
			}
		}

		return $meta;
	}

	add_filter( 'tinvwl_wishlist_item_meta_post', 'tinv_wishlist_metasupport_wc_gf_addons' );
}

if ( ! function_exists( 'tinvwl_wishlist_item_url_wc_gf_addons' ) ) {

	function tinvwl_wishlist_item_url_wc_gf_addons( $url, $wl_product, $product ) {

		$gravity_form_data = wc_gfpa()->get_gravity_form_data( $product->get_id() );

		if ( isset( $gravity_form_data['enable_cart_edit'] ) && $gravity_form_data['enable_cart_edit'] !== 'no' ) {
			$url = add_query_arg( array( 'wc_gforms_wishlist_product_id' => $wl_product['ID'] ), $product->get_permalink() );
		}

		return $url;
	}

	add_filter( 'tinvwl_wishlist_item_url', 'tinvwl_wishlist_item_url_wc_gf_addons', 10, 3 );
}

if ( ! function_exists( 'tinvwl_item_price_wc_gf_addons' ) ) {

	/**
	 * Modify price for WooCommerce - Gravity Forms Product Add-Ons
	 *
	 * @param string $price Returned price.
	 * @param array $wl_product Wishlist Product.
	 * @param \WC_Product $product Woocommerce Product.
	 *
	 * @return string
	 */
	function tinvwl_item_price_wc_gf_addons( $price, $wl_product, $product, $raw ) {
		if ( array_key_exists( 'wc_gforms_form_id', $wl_product['meta'] ) && class_exists( 'RGFormsModel' ) ) {
			$form = RGFormsModel::get_form_meta( $wl_product['meta']['wc_gforms_form_id'] );

			if ( empty( $form ) ) {
				return $price;
			}

			$lead       = array(
				'form_id' => $wl_product['meta']['wc_gforms_form_id']
			);
			$lead['id'] = uniqid() . time() . rand();

			foreach ( $wl_product['meta'] as $key => $meta ) {
				if ( strpos( $key, 'input_' ) === 0 ) {
					$lead[ str_replace( '_', '.', substr( $key, strlen( 'input_' ) ) ) ] = $meta;
				}
			}

			$use_choice_text = false;
			$use_admin_label = false;
			$products        = array();
			$total           = 0;

			foreach ( $form["fields"] as $field ) {
				$id         = $field["id"];
				$lead_value = RGFormsModel::get_lead_field_value( $lead, $field );

				$quantity_field = GFCommon::get_product_fields_by_type( $form, array( "quantity" ), $id );
				$quantity       = sizeof( $quantity_field ) > 0 ? RGFormsModel::get_lead_field_value( $lead, $quantity_field[0] ) : 1;

				switch ( $field["type"] ) {

					case "product" :

						//if single product, get values from the multiple inputs
						if ( is_array( $lead_value ) ) {
							$product_quantity = sizeof( $quantity_field ) == 0 && ! rgar( $field, "disableQuantity" ) ? rgget( $id . ".3", $lead_value ) : $quantity;
							if ( empty( $product_quantity ) ) {
								break;
							}

							if ( ! rgget( $id, $products ) ) {
								$products[ $id ] = array();
							}

							$products[ $id ]["name"]     = $use_admin_label && ! rgempty( "adminLabel", $field ) ? $field["adminLabel"] : $lead_value[ $id . ".1" ];
							$products[ $id ]["price"]    = rgar( $lead_value, $id . ".2" );
							$products[ $id ]["quantity"] = $product_quantity;
						} else if ( ! empty( $lead_value ) ) {

							if ( empty( $quantity ) ) {
								break;
							}

							if ( ! rgar( $products, $id ) ) {
								$products[ $id ] = array();
							}

							if ( $field["inputType"] == "price" ) {
								$name  = $field["label"];
								$price = $lead_value;
							} else {
								list( $name, $price ) = explode( "|", $lead_value );
							}

							$products[ $id ]["name"]     = ! $use_choice_text ? $name : RGFormsModel::get_choice_text( $field, $name );
							$products[ $id ]["price"]    = $price;
							$products[ $id ]["quantity"] = $quantity;
							$products[ $id ]["options"]  = array();
						}

						if ( isset( $products[ $id ] ) ) {
							$options = GFCommon::get_product_fields_by_type( $form, array( "option" ), $id );
							foreach ( $options as $option ) {
								$option_value = RGFormsModel::get_lead_field_value( $lead, $option );
								$option_label = empty( $option["adminLabel"] ) ? $option["label"] : $option["adminLabel"];
								if ( is_array( $option_value ) ) {
									foreach ( $option_value as $value ) {
										$option_info = GFCommon::get_option_info( $value, $option, $use_choice_text );
										if ( ! empty( $option_info ) ) {
											$products[ $id ]["options"][] = array(
												"field_label"  => rgar( $option, "label" ),
												"option_name"  => rgar( $option_info, "name" ),
												"option_label" => $option_label . ": " . rgar( $option_info, "name" ),
												"price"        => rgar( $option_info, "price" )
											);
										}
									}
								} else if ( ! empty( $option_value ) ) {
									$option_info                  = GFCommon::get_option_info( $option_value, $option, $use_choice_text );
									$products[ $id ]["options"][] = array(
										"field_label"  => rgar( $option, "label" ),
										"option_name"  => rgar( $option_info, "name" ),
										"option_label" => $option_label . ": " . rgar( $option_info, "name" ),
										"price"        => rgar( $option_info, "price" )
									);
								}
							}
						}
						break;
				}
			}

			$shipping_field = GFCommon::get_fields_by_type( $form, array( "shipping" ) );
			$shipping_price = $shipping_name = "";

			if ( ! empty( $shipping_field ) && ! RGFormsModel::is_field_hidden( $form, $shipping_field[0], array(), $lead ) ) {
				$shipping_price = RGFormsModel::get_lead_field_value( $lead, $shipping_field[0] );
				$shipping_name  = $shipping_field[0]["label"];
				if ( $shipping_field[0]["inputType"] != "singleshipping" ) {
					list( $shipping_method, $shipping_price ) = explode( "|", $shipping_price );
					$shipping_name = $shipping_field[0]["label"] . " ($shipping_method)";
				}
			}

			$shipping_price = GFCommon::to_number( $shipping_price );

			$product_info = array(
				"products" => $products,
				"shipping" => array( "name" => $shipping_name, "price" => $shipping_price )
			);

			$products = apply_filters( "gform_product_info_{$form["id"]}", apply_filters( "gform_product_info", $product_info, $form, $lead ), $form, $lead );

			if ( ! empty( $products["products"] ) ) {

				foreach ( $products["products"] as $_product ) {
					$price = GFCommon::to_number( $_product["price"] );
					if ( is_array( rgar( $_product, "options" ) ) ) {
						$index = 1;
						foreach ( $_product["options"] as $option ) {
							$price += GFCommon::to_number( $option["price"] );
							$index ++;
						}
					}
					$subtotal = floatval( $_product["quantity"] ) * $price;
					$total    += $subtotal;
				}

				$total += floatval( $products["shipping"]["price"] );
			}
			$price = $product->get_price( 'edit' );
			$price += (float) $total;
			if ( $raw ) {
				return $price;
			}

			return wc_price( $price );
		}

		return $price;
	}

	add_filter( 'tinvwl_wishlist_item_price', 'tinvwl_item_price_wc_gf_addons', 10, 4 );
} // End if().

if ( ! function_exists( 'tinvwl_wc_gf_addons_edit_link' ) ) {
	function tinvwl_wc_gf_addons_edit_link( $form ) {

		if ( isset( $_GET['wc_gforms_wishlist_product_id'] ) && empty( $_POST ) ) {

			$wl_product_id = $_GET['wc_gforms_wishlist_product_id'];
			$wlp           = new TInvWL_Product();
			$wl_product    = $wlp->get( array( 'ID' => $wl_product_id ) );
			$wl_product    = array_shift( $wl_product );

			if ( empty( $wl_product ) ) {
				return $form;
			}
			if ( array_key_exists( 'wc_gforms_form_id', $wl_product['meta'] ) ) {

				$entry       = array(
					'form_id' => $wl_product['meta']['wc_gforms_form_id']
				);
				$entry['id'] = uniqid() . time() . rand();

				foreach ( $wl_product['meta'] as $key => $meta ) {
					if ( strpos( $key, 'input_' ) === 0 ) {
						$entry[ str_replace( '_', '.', substr( $key, strlen( 'input_' ) ) ) ] = $meta;
					}
				}

				$exclude_fields = array();
				foreach ( $form['fields'] as &$field ) {
					if ( in_array( $field['id'], $exclude_fields ) ) {
						$field['cssClass']   = 'gform_hidden';
						$field['isRequired'] = false;
					} else {
						$value = null;
						if ( $field['type'] == 'checkbox' || ( $field['type'] == 'option' && $field['inputType'] == 'checkbox' ) ) { // handle checkbox fields
							// only pull the field values from the entry that match the form field we are evaluating
							$field_values = array();

							foreach ( $entry as $key => $value ) {
								$entry_key = explode( '.', $key );
								if ( $entry_key[0] == $field['id'] ) {
									$v              = explode( '|', $value );
									$field_values[] = $v[0];
								}
							}
							foreach ( $field->choices as &$choice ) {
								$choice['isSelected'] = ( in_array( $choice['value'], $field_values, true ) ) ? true : '';
							}
						} elseif ( is_array( $field->inputs ) ) { // handle other multi-input fields (address, name, time, etc.)

							// for time field, parse entry string to get individual parts of time string
							if ( $field['type'] == 'time' ) {
								// separate time string from entry into individual parts
								list( $HH, $time_end_part ) = explode( ':', $entry[ strval( $field['id'] ) ] );
								list( $MM, $AMPM ) = explode( ' ', $time_end_part );
								// save the time parts into individual array elements within the entry for our loop
								$entry[ $field['id'] . '.1' ] = $HH;
								$entry[ $field['id'] . '.2' ] = $MM;
								$entry[ $field['id'] . '.3' ] = $AMPM;
							}

							// loop each field input and set the default value from the entry
							foreach ( $field->inputs as $key => &$input ) {
								$value = '';
								if ( isset( $entry[ strval( $input['id'] ) ] ) ) {
									$value = $entry[ strval( $input['id'] ) ];
								} elseif ( isset( $entry[ $field['id'] ] ) ) {
									$value = $entry[ $field['id'] ];
								} elseif ( isset( $entry[ $field['id'] . '1' ] ) ) {
									$value = $entry[ $field['id'] ] . '.1';
								}

								$input['defaultValue'] = $value;
							}
						} else { // handle remaining single input fields
							if ( isset( $entry[ $field['id'] ] ) ) {
								$value = $entry[ $field['id'] ];
							}
						}

						// if we have a value for the field from the provided entry, set the default value for the field
						if ( ! empty( $value ) ) {
							$field['defaultValue'] = $value;
						}
					}
				}

			}

		}

		return $form;

	}

	add_filter( 'gform_pre_render', 'tinvwl_wc_gf_addons_edit_link', 99, 1 );
}

if ( ! function_exists( 'tinv_wishlist_metaprepare_wc_gf_addons' ) ) {

	/**
	 * Prepare save meta for WooCommerce - Gravity Forms Product Add-Ons
	 *
	 * @param array $meta Meta array.
	 *
	 * @return array
	 */
	function tinv_wishlist_metaprepare_wc_gf_addons( $meta ) {
		if ( array_key_exists( 'wc_gforms_form_id', $meta ) && class_exists( 'RGFormsModel' ) ) {
			foreach ( $meta as $key => $value ) {
				if ( strpos( $key, 'input_' ) === 0 ) {
					unset( $meta[ $key ] );
					$meta[ 'input_' . str_replace( '.', '_', substr( $key, strlen( 'input_' ) ) ) ] = $value;
				}
			}
		}

		return $meta;
	}

	add_filter( 'tinvwl_product_prepare_meta', 'tinv_wishlist_metaprepare_wc_gf_addons' );
}

function tinv_add_to_wishlist_wc_gf_addons() {
	wp_add_inline_script( 'tinvwl', "
						jQuery('body').on('tinvwl_add_to_wishlist_button_click', function(e, el){
							jQuery(el).closest('form.cart').each(function(){
								if (jQuery(this).find('.gform_variation_wrapper').length) {

								jQuery(this).on('change input', function(){
									tinv_add_to_wishlist_wc_gf_addons(jQuery(this), jQuery(el));
								});

								tinv_add_to_wishlist_wc_gf_addons(jQuery(this), jQuery(el));

								}
							});
					});

					function tinv_add_to_wishlist_wc_gf_addons(form, el){

									form.find('*[aria-required]').attr('required', true);

									if (!form[0].checkValidity()){
										el.addClass('disabled-add-wishlist');
										form[0].reportValidity();
									} else {
										el.removeClass('disabled-add-wishlist');
									}

									form.find('*[aria-required]').removeAttr('required');

					}
			" );
}

add_action( 'wp_enqueue_scripts', 'tinv_add_to_wishlist_wc_gf_addons', 100, 1 );
