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

// any operations with variations only
final class WOOBE_BULKOPERATIONS extends WOOBE_EXT {

	protected $slug = 'bulkoperations'; // unique

	// protected $is = 'external';

	public function __construct() {
		add_action( 'woobe_ext_scripts', array( $this, 'woobe_ext_scripts' ), 1 );
		add_action( 'woobe_tools_panel_buttons', array( $this, 'woobe_tools_panel_buttons' ), 1 );
		add_action( 'woobe_page_end', array( $this, 'woobe_page_end' ), 1 );

		// ajax
		add_action( 'wp_ajax_woobe_bulkoperations_get_att_terms', array( $this, 'woobe_bulkoperations_get_att_terms' ), 1 );
		add_action( 'wp_ajax_woobe_bulkoperations_get_possible_combos', array( $this, 'woobe_bulkoperations_get_possible_combos' ), 1 );
		add_action( 'wp_ajax_woobe_bulkoperations_get_prod_count', array( $this, 'woobe_bulkoperations_get_prod_count' ), 1 );
		add_action( 'wp_ajax_woobe_bulkoperations_apply_combinations', array( $this, 'woobe_bulkoperations_apply_combinations' ), 1 );
		add_action( 'wp_ajax_woobe_bulkoperations_apply_default_combination', array( $this, 'woobe_bulkoperations_apply_default_combination' ), 1 );
		add_action( 'wp_ajax_woobe_bulkoperations_get_product_variations', array( $this, 'woobe_bulkoperations_get_product_variations' ), 1 );
		add_action( 'wp_ajax_woobe_bulkoperations_delete', array( $this, 'woobe_bulkoperations_delete' ), 1 );
		add_action( 'wp_ajax_woobe_bulkoperations_ordering', array( $this, 'woobe_bulkoperations_ordering' ), 1 );
		add_action( 'wp_ajax_woobe_bulkoperations_swap', array( $this, 'woobe_bulkoperations_swap' ), 1 );
		add_action( 'wp_ajax_woobe_bulkoperations_attaching', array( $this, 'woobe_bulkoperations_attaching' ), 1 );
		add_action( 'wp_ajax_woobe_bulkoperations_visibility', array( $this, 'woobe_bulkoperations_visibility' ), 1 );
	}

	public function woobe_ext_scripts() {
		wp_enqueue_script( 'woobe_ext_' . $this->slug, $this->get_ext_link() . 'assets/js/' . $this->slug . '.js', array(), WOOBE_VERSION, false );
		wp_enqueue_script( 'woobe_ext_' . $this->slug . '-2', $this->get_ext_link() . 'assets/js/' . $this->slug . '-2.js', array(), WOOBE_VERSION, false );
		wp_enqueue_script( 'woobe_ext_' . $this->slug . '-3', $this->get_ext_link() . 'assets/js/' . $this->slug . '-3.js', array(), WOOBE_VERSION, false );
		wp_enqueue_script( 'woobe_ext_' . $this->slug . '-4', $this->get_ext_link() . 'assets/js/' . $this->slug . '-4.js', array(), WOOBE_VERSION, false );
		wp_enqueue_script( 'woobe_ext_' . $this->slug . '-5', $this->get_ext_link() . 'assets/js/' . $this->slug . '-5.js', array(), WOOBE_VERSION, false );
		wp_enqueue_script( 'woobe_ext_' . $this->slug . '-6', $this->get_ext_link() . 'assets/js/' . $this->slug . '-6.js', array(), WOOBE_VERSION, false );
		wp_enqueue_script( 'woobe_ext_' . $this->slug . '-7', $this->get_ext_link() . 'assets/js/' . $this->slug . '-7.js', array(), WOOBE_VERSION, false );
		wp_enqueue_style( 'woobe_ext_' . $this->slug, $this->get_ext_link() . 'assets/css/' . $this->slug . '.css', array(), WOOBE_VERSION, false );
		?>
		<script>
			lang.<?php echo esc_attr( $this->slug ); ?> = {};
			lang.<?php echo esc_attr( $this->slug ); ?>.going = '<?php esc_html_e( 'ATTENTION: Variations Advanced Bulk Operation is going', 'woo-bulk-editor' ); ?>';
			lang.<?php echo esc_attr( $this->slug ); ?>.finished = '<?php esc_html_e( 'Variations Advanced Bulk Operation is finished', 'woo-bulk-editor' ); ?>';
			lang.<?php echo esc_attr( $this->slug ); ?>.finished2 = '<?php esc_html_e( 'Attaching of the default combination for the products variations is finished!', 'woo-bulk-editor' ); ?>';
			lang.<?php echo esc_attr( $this->slug ); ?>.finished3 = '<?php esc_html_e( 'Deleting of the products variations is finished', 'woo-bulk-editor' ); ?>';
			lang.<?php echo esc_attr( $this->slug ); ?>.finished4 = '<?php esc_html_e( 'Ordering of the products variations is finished', 'woo-bulk-editor' ); ?>';
			lang.<?php echo esc_attr( $this->slug ); ?>.finished5 = '<?php esc_html_e( 'Swap of variations is finished', 'woo-bulk-editor' ); ?>';
			lang.<?php echo esc_attr( $this->slug ); ?>.finished6 = '<?php esc_html_e( 'Attaching of the products variations is finished', 'woo-bulk-editor' ); ?>';
			lang.<?php echo esc_attr( $this->slug ); ?>.generating = '<?php esc_html_e( 'Generating possible combinations', 'woo-bulk-editor' ); ?>';
			lang.<?php echo esc_attr( $this->slug ); ?>.generated = '<?php esc_html_e( 'Possible combinations been generated.', 'woo-bulk-editor' ); ?>';
			lang.<?php echo esc_attr( $this->slug ); ?>.no_combinations = '<?php esc_html_e( 'Combination(s) not selected!', 'woo-bulk-editor' ); ?>';
			lang.<?php echo esc_attr( $this->slug ); ?>.not_selected_var = '<?php esc_html_e( 'variation is not selected', 'woo-bulk-editor' ); ?>';
			lang.<?php echo esc_attr( $this->slug ); ?>.no_vars = '<?php esc_html_e( 'the product has no variations', 'woo-bulk-editor' ); ?>';
		</script>
		<?php
	}

	public function woobe_tools_panel_buttons() {
		?>
		<a href="#" class="button button-secondary woobe_tools_panel_newvars_btn" title="<?php esc_html_e( 'Variations Advanced Bulk Operations', 'woo-bulk-editor' ); ?>"></a>
		<?php
	}

	public function woobe_page_end() {
		$data               = array();
		$data['attributes'] = wc_get_attribute_taxonomies();
		WOOBE_HELPER::render_html_e( $this->get_ext_path() . 'views/panel.php', $data );
	}

	// ajax
	public function woobe_bulkoperations_get_att_terms() {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		die( json_encode( WOOBE_HELPER::get_taxonomies_terms_hierarchy( sanitize_text_field( $_REQUEST['attribute'] ) ) ) );
	}

	// ajax
	public function woobe_bulkoperations_get_possible_combos() {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		try {
			$res = '';
			if ( isset( $_REQUEST['arrays'] ) ) {
				// no db writing, ajax to DOM
				die( json_encode( $this->generate_combinations( $_REQUEST['arrays'] ) ) );
			}
		} catch ( Exception $e ) {
			// +++
		}

		die( '' );
	}

	// https://gist.github.com/fabiocicerchia/4556892
	private function generate_combinations( $data, &$all = array(), array $group = array(), $value = null, $i = 0 ) {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		if ( ! is_array( $data ) ) {
			$data = array();
		}
		$keys = array_keys( $data );
		if ( isset( $value ) === true ) {
			array_push( $group, intval( $value ) );
		}

		if ( $i >= count( $data ) ) {
			array_push( $all, $group );
		} else {
			$currentKey     = $keys[ $i ];
			$currentElement = $data[ $currentKey ];
			foreach ( $currentElement as $val ) {
				$this->generate_combinations( $data, $all, $group, $val, $i + 1 );
			}
		}

		return $all;
	}

	// ajax
	public function woobe_bulkoperations_get_prod_count() {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		if ( ! current_user_can( 'manage_woocommerce' ) ) {
			die( '0' );
		}

		// ***

		$products = $this->products->gets(
			array(
				'fields'        => 'ids',
				'no_found_rows' => true,
			)
		);
		echo json_encode( $products->posts );

		exit;
	}

	// ajax
	public function woobe_bulkoperations_apply_combinations() {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		if ( ! isset( $_REQUEST['products_ids'] ) ) {
			die( '0' );
		}

		// ***

		$products_ids = array_map(
			function ( $item ) {
				return intval( $item ); // sanitize intval
			},
			$_REQUEST['products_ids']
		);

		$combinations = WOOBE_HELPER::sanitize_array( (array) $_REQUEST['combinations'] );

		$possible_attributes = array();
		// for set_product_attributes
		$set_product_attributes = array();

		// ***

		if ( ! empty( $products_ids ) and ! empty( $combinations ) ) {

			// lets prepare combinations for applying
			$terms = array();
			foreach ( $combinations as $comb ) {
				if ( ! empty( $comb ) ) {
					foreach ( $comb as $term_id ) {
						$terms[ $term_id ] = get_term( $term_id, '', ARRAY_A );
					}
				}
			}

			// ***

			foreach ( $terms as $t ) {
				$set_product_attributes[ $t['taxonomy'] ][] = $t['term_id'];
			}

			foreach ( $combinations as $k => $comb ) {
				if ( ! empty( $comb ) ) {
					foreach ( $comb as $term_id ) {
						$possible_attributes[ $k ][ strtolower( urlencode( $terms[ $term_id ]['taxonomy'] ) ) ] = $terms[ $term_id ]['slug'];
					}
				}
			}

			// ***
			// wp-content\plugins\woocommerce\includes\class-wc-ajax.php -> public static function link_all_variations
			wc_maybe_define_constant( 'WC_MAX_LINKED_VARIATIONS', 50 );
			wc_set_time_limit( 0 );

			/*
			 * Leaved as an example of data structure
				$possible_attributes = array(
				'pa_color' => array('black', 'blue', 'green'),
				'pa_size' => array('xl', '2xxl')
				);

				$set_product_attributes = array(
				'pa_color' => array(1, 2, 3),
				'pa_size' => array(4, 5)
				);
			 */

			if ( ! empty( $possible_attributes ) ) {

				foreach ( $products_ids as $product_id ) {

					$product_id = intval( $product_id );
					$product    = $this->products->get_product( $product_id );

					// if product is not variable - no variations!!
					if ( ! $product->is_type( 'variable' ) ) {
						continue;
					}

					// attach attributes if they not been attached
					foreach ( $set_product_attributes as $field_key => $value ) {
						$this->products->set_product_attributes( $product_id, $field_key, $value, 'append', array( 'set_variation' ) );

					}

					// ***
					// Get existing variations so we don't create duplicates.
					$existing_variations = array_map( 'wc_get_product', $product->get_children() );
					$parent_sku          = $product->get_sku();
					$existing_attributes = array();

					foreach ( $existing_variations as $existing_variation ) {
						if ( $existing_variation ) {
							$existing_attributes[] = $existing_variation->get_attributes();
						}
					}

					$regular_price = get_post_meta( $product_id, '_regular_price', true );
					$sale_price    = get_post_meta( $product_id, '_sale_price', true );
					// ***

					foreach ( $possible_attributes as $possible_attribute ) {

						if ( in_array( $possible_attribute, $existing_attributes ) ) {
							continue;
						}

						$variation = new WC_Product_Variation();
						$variation->set_parent_id( $product_id );
						$variation->set_attributes( $possible_attribute );

						$variation->set_status( apply_filters( 'woobe_new_variation_product_status', 'publish' ) );

						if ( $regular_price ) {
							$variation->set_regular_price( $regular_price );
						}
						if ( $sale_price ) {
							$variation->set_sale_price( $sale_price );
						}

						// do_action('product_variation_linked', $variation->save());
						$variation->save();

						// to avoid the same SKU as in the parent
						if ( empty( $parent_sku ) ) {
							$variation->set_sku( 'sku-' . $variation->get_id() );
						} else {
							$variation->set_sku( $parent_sku . '-' . $variation->get_id() );
						}
						$variation->set_manage_stock( 0 );
						$variation->set_stock_quantity( 0 );
						$variation->save();

						// clean_post_cache($variation->get_id());
						// wp_cache_flush();
					}

					// ***
					// set order of variations
					$data_store = $product->get_data_store();
					$data_store->sort_all_product_variations( $product->get_id() );
				}
			}
		}

		die( 'done' );
	}

	// ************ TAB 2
	// ajax
	public function woobe_bulkoperations_apply_default_combination() {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		if ( ! isset( $_REQUEST['products_ids'] ) ) {
			die( '0' );
		}

		// ***

		$products_ids = array_map(
			function ( $item ) {
				return intval( $item ); // sanitize intval
			},
			$_REQUEST['products_ids']
		);

		$combination = WOOBE_HELPER::sanitize_array( (array) $_REQUEST['combination'] );

		if ( ! empty( $combination ) and ! empty( $products_ids ) ) {
			foreach ( $products_ids as $product_id ) {
				$product = $this->products->get_product( $product_id );
				$product->set_props(
					array(
						'default_attributes' => $combination,
					)
				);
				$product->save();

				// *** also lets set order of attributes which customer will see on the product page
				$meta = get_post_meta( $product_id, '_product_attributes', true );

				$new_meta = array();
				$counter  = 0;
				foreach ( array_keys( $combination ) as $meta_key ) {
					if ( isset( $meta[ $meta_key ] ) ) {
						$new_meta[ $meta_key ]             = $meta[ $meta_key ];
						$new_meta[ $meta_key ]['position'] = $counter;
						unset( $meta[ $meta_key ] );
						++$counter;
					}
				}

				// if we have more attributes than trying to save in order
				if ( ! empty( $meta ) ) {
					foreach ( $meta as $meta_key => $value ) {
						$new_meta[ $meta_key ]             = $value;
						$new_meta[ $meta_key ]['position'] = $counter;
						++$counter;
					}
				}

				update_post_meta( $product_id, '_product_attributes', $new_meta );

				// woocommerce\includes\admin\meta-boxes\class-wc-meta-box-product-data.php
				// public static function save($post_id, $post)
				do_action( 'woocommerce_process_product_meta_' . $product->get_type(), $product_id );
			}
		}

		exit;
	}

	// ************ TAB 3
	// ajax
	public function woobe_bulkoperations_delete() {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		if ( ! isset( $_REQUEST['products_ids'] ) ) {
			die( '0' );
		}

		// ***

		$removed_ids  = array();
		$products_ids = array_map(
			function ( $item ) {
				return intval( $item ); // sanitize intval
			},
			$_REQUEST['products_ids']
		);

		$combination = array();
		if ( isset( $_REQUEST['combination'] ) ) {
			$combination = WOOBE_HELPER::sanitize_array( (array) $_REQUEST['combination'] );
		}

		if ( ! empty( $products_ids ) ) {
			foreach ( $products_ids as $product_id ) {
				$product = $this->products->get_product( $product_id );

				if ( method_exists( $product, 'is_type' ) and $product->is_type( 'variable' ) ) {
					$vars = $product->get_children();

					if ( ! empty( $vars ) ) {
						foreach ( $vars as $var_id ) {

							$var = $this->products->get_product( $var_id );
							$av  = $product->get_available_variation( $var );

							if ( $_REQUEST['delete_how'] == 'combo' ) {

								if ( ! empty( $combination ) ) {
									if ( count( $av['attributes'] ) === count( $combination ) ) {
										$is         = false;
										$attributes = array();

										// fix for non-latin symbols
										if ( ! empty( $av['attributes'] ) ) {
											foreach ( $av['attributes'] as $k => $v ) {
												$attributes[ urldecode( $k ) ] = urldecode( $v );
											}
										}

										foreach ( $combination as $comb_key => $comb_value ) {
											if ( isset( $attributes[ 'attribute_' . urldecode( $comb_key ) ] ) and $attributes[ 'attribute_' . urldecode( $comb_key ) ] == urldecode( $comb_value ) ) {
												$is = true;
											} else {
												$is = false;
												break;
											}
										}

										// removing
										if ( $is ) {
											$var_prod      = $this->products->get_product( $av['variation_id'] );
											$removed_ids[] = $av['variation_id'];
											$var_prod->delete( true );
										}
									}
								}
							} else {
								// all
								$var_prod      = $this->products->get_product( $av['variation_id'] );
								$removed_ids[] = $av['variation_id'];
								if ( $var_prod ) {
									$var_prod->delete( true );
								}
							}
						}
					}
				}

				// ***
			}
		}

		// ***
		die( json_encode( $removed_ids ) );
	}

	// ************ TAB 4
	// ajax
	public function woobe_bulkoperations_get_product_variations() {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		$product_id           = intval( $_REQUEST['product_id'] );
		$available_variations = array();

		if ( $product_id > 0 ) {
			try {
				$product = $this->products->get_product( $product_id );

				if ( is_object( $product ) and $product->is_type( 'variable' ) ) {
					$vars = $product->get_children();

					if ( ! empty( $vars ) ) {
						foreach ( $vars as $var_id ) {
							$var                                      = $this->products->get_product( $var_id );
							$av                                       = $product->get_available_variation( $var );
							$available_variations[ $var_id ]['title'] = str_replace( $product->get_title(), '', $this->products->generate_product_title( $var ) );
							$available_variations[ $var_id ]['attributes'] = $av['attributes'];
						}
					}
				}
			} catch ( Exception $e ) {
				// ***
			}
		}

		die( json_encode( $available_variations ) );
	}

	// ajax
	public function woobe_bulkoperations_ordering() {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		$products_ids = array_map(
			function ( $item ) {
				return intval( $item ); // sanitize intval
			},
			$_REQUEST['products_ids']
		);

		$combination = WOOBE_HELPER::sanitize_array( (array) $_REQUEST['combination'] );

		// ***

		if ( ! empty( $products_ids ) and ! empty( $combination ) ) {
			foreach ( $products_ids as $product_id ) {
				$available_variations = array();
				$product              = $this->products->get_product( $product_id );
				$childrens            = $product->get_children();

				if ( ! empty( $childrens ) ) {
					foreach ( $childrens as $child_id ) {
						$variation              = $this->products->get_product( $child_id );
						$available_variations[] = $product->get_available_variation( $variation );
					}

					// ***

					if ( ! empty( $available_variations ) ) {
						foreach ( $available_variations as $var ) {
							$att = $var['attributes'];
							$num = -1;
							foreach ( $combination as $n => $comb_var ) {
								// lets look is it the same set of attributes as in $var
								$ak_att = array_keys( $att );
								$ak_cv  = array_keys( $comb_var );
								sort( $ak_att );
								sort( $ak_cv );
								if ( $ak_att === $ak_cv ) {
									$av_att = array_values( $att );
									$av_cv  = array_values( $comb_var );
									sort( $av_att );
									sort( $av_cv );
									if ( $av_att === $av_cv ) {
										$num = $n;
										break;
									}
								}
							}

							// ***
							if ( $num > -1 ) {
								$this->products->update_page_field( intval( $var['variation_id'] ), 'menu_order', $num );
							}
						}
					}
				}
			}
		}

		exit;
	}

	// ************ TAB 5 swap
	// ajax
	public function woobe_bulkoperations_swap() {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		$do = true;
		if ( ! empty( $_REQUEST['from'] ) and ! empty( $_REQUEST['to'] ) ) {
			if ( $_REQUEST['from']['attribute'] == $_REQUEST['to']['attribute'] ) {
				if ( $_REQUEST['from']['term'] == $_REQUEST['to']['term'] ) {
					$do = false;
				}
			}
		} else {
			$do = false;
		}

		// ***

		if ( $do ) {
			$from_att = sanitize_text_field( $_REQUEST['from']['attribute'] );
			$to_att   = sanitize_text_field( $_REQUEST['to']['attribute'] );

			// ***

			if ( ! empty( $_REQUEST['products_ids'] ) ) {
				foreach ( $_REQUEST['products_ids'] as $product_id ) {
					$product_id = intval( $product_id );
					$product    = $this->products->get_product( $product_id );

					// ***

					if ( ! in_array( $product->get_type(), array( 'variable', 'variation' ) ) ) {
						continue;
					}

					// ***

					if ( $product->is_type( 'variable' ) ) {
						$childrens      = $product->get_children();
						$parent_id      = $product_id;
						$parent_product = $product;
					} else {
						$childrens      = array( $product_id );
						$parent_id      = $product->get_parent_id();
						$parent_product = $this->products->get_product( $parent_id );
					}

					$parent_terms = wc_get_product_terms( $parent_id, $to_att, array( 'fields' => 'slugs' ) );

					if ( ! empty( $childrens ) ) {
						foreach ( $childrens as $child_id ) {
							$variation            = $this->products->get_product( $child_id );
							$available_variations = $parent_product->get_available_variation( $variation );

							// ***

							if ( isset( $available_variations['attributes'] ) and ! empty( $available_variations['attributes'] ) ) {
								if ( isset( $available_variations['attributes'][ 'attribute_' . $from_att ] ) ) {
									if ( $available_variations['attributes'][ 'attribute_' . $from_att ] === sanitize_text_field( $_REQUEST['from']['term'] ) ) {

										$possible_attributes = $available_variations['attributes'];

										if ( $from_att !== $to_att ) {
											unset( $possible_attributes[ 'attribute_' . $from_att ] );
										}

										$possible_attributes[ 'attribute_' . $to_att ] = sanitize_text_field( $_REQUEST['to']['term'] );

										// if such attribute not selected in the parent product Attributes tab lets attach it here
										if ( ! in_array( $_REQUEST['to']['term'], $parent_terms ) ) {
											$p_terms = array();
											foreach ( $parent_terms as $t_slug ) {
												$t_term = get_term_by( 'slug', sanitize_text_field( $t_slug ), $to_att );
												if ( $t_term ) {
													$p_terms[] = $t_term->term_id;
												}
											}
											$t         = get_term_by( 'slug', sanitize_text_field( $_REQUEST['to']['term'] ), $to_att );
											$p_terms[] = $t->term_id;

											$this->products->update_page_field( $parent_id, $to_att, $p_terms );
										}

										$variation->set_attributes( $possible_attributes );
										$variation->save();
									}
								}
							}
						}
					}
				}
			}
		}

		die( 'done' );
	}

	// ************ TAB 6 attaching
	// ajax
	public function woobe_bulkoperations_attaching() {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		$selected_attribute = sanitize_text_field( $_REQUEST['selected_attribute'] );
		$attaching_att      = $_REQUEST['attaching_att']; // sanitizing in cycle
		$products_ids       = $_REQUEST['products_ids']; // sanitizing in cycle
		// ***

		if ( ! empty( $products_ids ) ) {
			if ( ! empty( $selected_attribute ) and $attaching_att ) {
				foreach ( $products_ids as $product_id ) {
					$product_id = intval( $product_id ); // sanitizing

					$product = $this->products->get_product( $product_id );

					if ( $product->is_type( 'variable' ) ) {
						$childrens = $product->get_children();
						// ***
						if ( ! empty( $childrens ) ) {
							foreach ( $childrens as $child_id ) {
								$variation            = $this->products->get_product( $child_id );
								$available_variations = $product->get_available_variation( $variation );

								// ***

								if ( isset( $available_variations['attributes'] ) and ! empty( $available_variations['attributes'] ) ) {

									// if its empty - will be filled up, if not empty will be replaced if not selected 'ignore'
									$possible_attributes = $available_variations['attributes'];

									// ***

									foreach ( $attaching_att as $set ) {

										if ( isset( $possible_attributes[ 'attribute_' . $selected_attribute ] ) ) {
											unset( $possible_attributes[ 'attribute_' . $selected_attribute ] );
										}

										if ( isset( $set['attributes'][ 'attribute_' . $selected_attribute ] ) ) {
											unset( $set['attributes'][ 'attribute_' . $selected_attribute ] );
										}

										// ***

										$att_set_now_keys = array_keys( $possible_attributes );
										$set_keys         = array_keys( $set['attributes'] );
										sort( $att_set_now_keys );
										sort( $set_keys );

										if ( $att_set_now_keys === $set_keys ) {
											$att_set_now_vals = array_values( $possible_attributes );
											$set_vals         = array_values( $set['attributes'] );
											sort( $att_set_now_vals );
											sort( $set_vals );
											if ( $att_set_now_vals === $set_vals and $set['value'] !== 'woobe-ignore' ) {
												$possible_attributes[ 'attribute_' . $selected_attribute ] = sanitize_text_field( $set['value'] );

												// if such attribute not selected in the parent product Attributes tab lets attach it here
												$parent_terms = wc_get_product_terms( $product_id, $selected_attribute, array( 'fields' => 'ids' ) );
												if ( ! in_array( $set['value'], $parent_terms ) ) {
													$t              = get_term_by( 'slug', sanitize_text_field( $set['value'] ), $selected_attribute );
													$parent_terms[] = $t->term_id;
													$this->products->update_page_field( $product_id, $selected_attribute, $parent_terms, '', array( 'set_variation' ) );

												}

												$variation->set_attributes( $possible_attributes );
												$variation->save();
												break;
											}
										}
									}
								}
							}
						}

						// fix  visibility
						$meta = get_post_meta( $product_id, '_product_attributes', true );
						if ( is_array( $meta ) ) {
							foreach ( $meta as $pa_key => $item ) {
								if ( $item['name'] == $selected_attribute ) {
									$meta[ $pa_key ]['is_visible']   = 1;
									$meta[ $pa_key ]['is_variation'] = 1;
								}
							}
						}
						update_post_meta( $product_id, '_product_attributes', $meta );
					}
				}
			}
		}

		// ***

		die( 'done' );
	}

	// ************ TAB 7 visibility
	// ajax
	public function woobe_bulkoperations_visibility() {
		if ( ! isset( $_REQUEST['bulkoperations_nonce'] ) || ! wp_verify_nonce( $_REQUEST['bulkoperations_nonce'], 'woobe_bulkoperations_nonce' ) ) {
			die( '0' );
		}
		if ( isset( $_REQUEST['products_ids'] ) ) {
			$products_ids = $_REQUEST['products_ids']; // sanitizing in cycle
			$vis_data     = $_REQUEST['vis_data']; // sanitizing in cycle

			if ( ! empty( $products_ids ) and ! empty( $vis_data ) ) {
				foreach ( $products_ids as $product_id ) {
					$product_id = intval( $product_id );

					$product = $this->products->get_product( $product_id );
					if ( $product->is_type( 'variable' ) ) {
						$meta = get_post_meta( $product_id, '_product_attributes', true );

						foreach ( $vis_data as $vis ) {
							if ( is_array( $meta ) ) {
								foreach ( $meta as $pa_key => $item ) {
									if ( $item['name'] == $vis['attribute'] ) {
										$meta[ $pa_key ]['is_visible']   = intval( $vis['is_visible'] );
										$meta[ $pa_key ]['is_variation'] = intval( $vis['is_variation'] );
									}
								}
							}
						}
						update_post_meta( $product_id, '_product_attributes', $meta );
					}
				}
			}
		}

		die( 'done' );
	}
}
