<?php
namespace BricksUltimate;

if ( ! defined( 'ABSPATH' ) ) exit;

use BricksUltimate\{Plugin, Helpers};
use BricksUltimate\Admin\License;

class Wishlist {
	public static $instance = null;
	public static $wishlist_ids = [];
	public static $key = 'bu-wishlist';
	public static $inited = false;
	public $base_url = '';
	public static $cookie_key = '';

	/**
	 * Saves product ids in cookie
	 */
	const COOKIE_KEY = 'bu_wishlist';

	public function __construct() {
		if ( License::has_valid_license() ) {
			add_action( 'wp_ajax_bu_get_wishlist', [ $this, 'add_remove_product_to_wishlist' ] );
			add_action( 'wp_ajax_nopriv_bu_get_wishlist', [ $this, 'add_remove_product_to_wishlist' ] );
			add_action( 'wp_ajax_bu_delete_wishlist_item', [ $this, 'bu_delete_wishlist_item' ] );
			add_action( 'wp_ajax_nopriv_bu_delete_wishlist_item', [ $this, 'bu_delete_wishlist_item' ] );
			add_action( 'wp_ajax_bu_clean_wishlist', [ $this, 'bu_clean_wishlist' ] );
			add_action( 'wp_ajax_nopriv_bu_clean_wishlist', [ $this, 'bu_clean_wishlist' ] );
			add_action( 'wp_ajax_bu_mini_wishlist', [ $this, 'bu_mini_wishlist' ] );
			add_action( 'wp_ajax_nopriv_bu_mini_wishlist', [ $this, 'bu_mini_wishlist' ] );
			add_action( 'wp_ajax_bu_add_all_to_cart', [ $this, 'bu_add_all_to_cart' ] );
			add_action( 'wp_ajax_nopriv_bu_add_all_to_cart', [ $this, 'bu_add_all_to_cart' ] );
			
			if( Helpers::isBricksBuilderActive() ) {
				add_filter( "bricks/elements/block/control_groups", array( $this, 'add_mini_wishlist_control_groups' ) );
				add_filter( "bricks/elements/block/controls", [ $this, 'add_mini_wishlist_controls' ] );
			}

			add_filter( 'bricks/element/render_attributes', [ $this, 'bu_add_attributes' ], 1010, 3 );

			$this->init_actions();
		}
	}

	public function bu_add_attributes( $atts, $key, $element ) {
		$settings = $element->settings;
		if( $element->name == 'block' && !empty( $settings['isMiniWishlistWrapper'] ) ) {
			$atts['_root']['data-base-url'] = get_permalink( $element->post_id );
			$atts['_root']['data-element-id'] = $element->id;
			$atts['_root']['data-post-id'] = $element->post_id;
			$atts['_root']['class'][] = 'bu-mini-wishlist';
			if( ! empty( $settings['wslHideContent'] ) ) {
				$atts['_root']['data-hide-content'] = "yes";
				$atts['_root']['data-content-selectors'] = $settings['contentSelectors'] ?? 'no';
			}
		}

		return $atts;
	}

	public function add_mini_wishlist_control_groups( $control_groups ) {
		$control_groups['minwishlist'] = [
			'tab'      => 'style',
			'title'    => esc_html__( 'Mini Wishlist', 'bricksultimate' ),
		];

		return $control_groups;
	}

	public function add_mini_wishlist_controls( $controls ) {
		$controls['isMiniWishlistWrapper'] = [
			'tab' 		=> 'style',
			'group' 	=> 'minwishlist',
			'type'      => 'checkbox',
			'label'     => esc_html__( 'Using for Mini Wishlist Builder?', 'bricksultimate' ),
			'reset' 	=> true,
		];

		$controls['wslHideContent'] = [
			'tab' 		=> 'style',
			'group' 	=> 'minwishlist',
			'type'      => 'checkbox',
			'label'     => esc_html__( 'Hide contents when wishlist is empty', 'bricksultimate' ),
			'reset' 	=> true,
			'inline' 	=> false
		];

		$controls['contentSelectors'] = [
			'tab' 		=> 'style',
			'group' 	=> 'minwishlist',
			'type'        => 'text',
			'label'       => esc_html__( 'Content selectors', 'bricksultimate' ),
			'placeholder' => '.brxe-button',
			'required' 	=> ['wslHideContent', '=', true]
		];

		return $controls;
	}

	public function set_wishlists( $cookie_key = null, $type = 'post', $user_id = null ) {
		$wishlist_ids = [];

		$cached_products = '';
		$user_cached_products = false;

		if ( $user_id ) {
			$cached_products = get_user_meta( $user_id, $cookie_key, true );
			$user_cached_products = true;
		} elseif ( is_user_logged_in() ) {
			$cached_products = get_user_meta( get_current_user_id(), $cookie_key, true );
			$user_cached_products = true;
		}

		if ( !$user_cached_products && isset( $_COOKIE[ $cookie_key ] ) && !empty( $_COOKIE[ $cookie_key ] ) ) {
			$cached_products = $_COOKIE[ $cookie_key ];
		}

		if ( $cached_products != '' ) {

			$items = explode( ',', $cached_products);

			foreach( $items as $key => $product_id ) {
				if( ( 'product_variation' == get_post_type( $product_id ) || 'product' == get_post_type( $product_id ) ) && class_exists('WooCommerce') ) {
					$product = wc_get_product( $product_id );

					if( ! $product )
						continue;

					if( ! $product->exists() || 'trash' === $product->get_status() ) {
						continue;
					}

					$wishlist_ids[ $type ][] = $product_id;
				} elseif ( 'publish' === get_post_status( $product_id ) && $type == get_post_type( $product_id ) ) {
					$wishlist_ids[ $type ][] = $product_id;
				}
			}
		}

		return $wishlist_ids;
	}

	public function get_wishlists($cookie_key = null, $post_type = 'post', $user_id = null) {
		if( $cookie_key ) {
			return $this->set_wishlists( $cookie_key, $post_type );
		} else {
			$postTypes = \Bricks\Helpers::get_registered_post_types();

			if( $postTypes ) {
				$ids = [];
				foreach( $postTypes as $type => $label ) {
					$cookie_key = $this->get_cookie_key( $type );
					if( isset( $_COOKIE[ $cookie_key ] ) && !empty( $_COOKIE[ $cookie_key ] ) ) {
						$ids[ $type ] = isset( $this->set_wishlists( $cookie_key, $type )[ $type ] ) ? $this->set_wishlists( $cookie_key, $type )[ $type ] : [];
					} elseif( is_user_logged_in() && metadata_exists( 'user', get_current_user_id(), $cookie_key )) {
						$ids[ $type ] = isset( $this->set_wishlists( $cookie_key, $type )[ $type ] ) ? $this->set_wishlists( $cookie_key, $type )[ $type ] : [];
					}
				}

				return $ids;
			} else {
				return $this->set_wishlists( $cookie_key, $post_type );
			}
		}
    }

    public function save_user_wishlist( $type = 'post', $user_id = null, $cookie_key = null, $wishlists = [] ) {
    	$saved_products = get_user_meta($user_id, $cookie_key, true);

		if ( $saved_products ) {
			$saved_products = explode(',', $saved_products);
		} else {
			$saved_products = [];
		}

		$ready_products = array_unique( array_merge( $saved_products, $wishlists ) );
		
		foreach( $ready_products as $key => $product_id ) {
			if ( 'publish' !== get_post_status( $product_id ) && $type == get_post_type( $product_id ) ) {
				unset( $ready_products[ $key ] );
			} elseif( ( 'product' == get_post_type( $product_id ) || 'product_variation' == get_post_type( $product_id ) ) && class_exists('WooCommerce') ) {
				
				$product = wc_get_product( $product_id );

				if( ! $product || ! $product->exists() || 'trash' === $product->get_status() ) {
					unset( $ready_products[ $key ] );
				}
			}
		}

		update_user_meta($user_id, $cookie_key, implode(',', (array) $ready_products) );

		Plugin::bu_setcookie($cookie_key, '', time() + ($this->get_days_cache() * WEEK_IN_SECONDS));
		unset( $_COOKIE[$cookie_key] );
		self::$wishlist_ids[ $type ] = (array) $ready_products;
    }

    public function update_products_ids_after_login( $user_login, $user ){
		$products = $this->get_wishlists();
		$postTypes = \Bricks\Helpers::get_registered_post_types();

		if( $postTypes ) {
			foreach( $postTypes as $type => $label ) {
				$cookie_key = $this->get_cookie_key( $type );
				if( isset( $_COOKIE[ $cookie_key ] ) && ! empty( $_COOKIE[ $cookie_key ] ) ) {
					$this->save_user_wishlist( $type, $user->ID, $cookie_key, ( $products[$type] ?? [] ) );
				} elseif ( metadata_exists( 'user', $user->ID, $cookie_key ) ) {
					$this->save_user_wishlist( $type, $user->ID, $cookie_key, ( $products[$type] ?? [] ) );
				}
			}
		}
    }

	public function add_remove_product_to_wishlist() {
		check_ajax_referer( 'wishlist-nonce', 'security' );

		$data = ['success' => false];

		global $postData;

		$postData = [];
		$postId 	= $_POST['productId'];
		$postType 	= $_POST['postType'];

		if ( defined( 'ICL_SITEPRESS_VERSION' ) && function_exists( 'wpml_object_id_filter' ) ) {
			global $sitepress;
			$postId = wpml_object_id_filter( $postId, $postType, true, $sitepress->get_default_language() );
		}
		
		$template_id = intval( $_POST['notice'] );
		$action 	= $_POST['wslaction'];
		$cookie_key = $_POST['cookieKey'];
		$all_products = $this->get_wishlists( $cookie_key, $postType );
		self::$wishlist_ids[ $postType ] = isset( $all_products[ $postType ] ) ? $all_products[ $postType ] : [];

		if( ! in_array( $postId, self::$wishlist_ids[ $postType ] ) && $action == 'add' ) {
			$all_products[ $postType ][] = $postId;
			$data['success'] = true;
			$data['count'] = count( $all_products[ $postType ] );

			if( $template_id > 0 ) {
				$postData['id'] = $postId;
				$postData['filterType'] = 'notice';
				
				add_filter( 'bricks/posts/query_vars', [ '\BricksUltimate\Ajax', 'filter_query_args' ], 10, 3 );

				$elements = get_post_meta( $template_id, BRICKS_DB_PAGE_CONTENT, true );
				$template_inline_css = \Bricks\Templates::generate_inline_css( $template_id, $elements );

				$css = "<style id=\"bricks-inline-css-template-{$template_id}\">{$template_inline_css}</style>";

				$data['notice'] = do_shortcode('[bricks_template id="'. $template_id .'"]') . $css ;
				remove_filter( 'bricks/posts/query_vars', [ '\BricksUltimate\Ajax', 'filter_query_args' ], 10, 3 );
			}
		} elseif( in_array( $postId, self::$wishlist_ids[ $postType ] ) && $action == 'add' ) {
			$data['success'] = true;
			$data['count'] = count( $all_products[ $postType ] );
		}

		if( in_array( $postId, self::$wishlist_ids[ $postType ] ) && $action == 'remove' ) {
			if( ( $key = array_search($postId, $all_products[ $postType ]) ) !== false )
				unset($all_products[ $postType ][$key]);

			$data['success'] = true;
			$data['count'] = ($all_products[ $postType ]) ? count( $all_products[ $postType ] ) : 0;

			$template_id = intval( $_POST['rmnotice'] );
			if( $template_id > 0 ) {
				$postData['id'] = $postId;
				$postData['filterType'] = 'notice';
				
				add_filter( 'bricks/posts/query_vars', [ '\BricksUltimate\Ajax', 'filter_query_args' ], 10, 3 );

				$elements = get_post_meta( $template_id, BRICKS_DB_PAGE_CONTENT, true );
				$template_inline_css = \Bricks\Templates::generate_inline_css( $template_id, $elements );

				$css = "<style id=\"bricks-inline-css-template-{$template_id}\">{$template_inline_css}</style>";

				$data['rmnotice'] = do_shortcode('[bricks_template id="'. $template_id .'"]') . $css ;
				remove_filter( 'bricks/posts/query_vars', [ '\BricksUltimate\Ajax', 'filter_query_args' ], 10, 3 );
			}
		}

		if( $data['success'] ) {
			Plugin::bu_setcookie($cookie_key, implode(',', $all_products[ $postType ]), time() + ($this->get_days_cache() * WEEK_IN_SECONDS) );

			if( is_user_logged_in() ) {
				update_user_meta( get_current_user_id(), $cookie_key, implode(',', $all_products[ $postType ]) );

				Plugin::bu_setcookie($cookie_key, '', time() + ($this->get_days_cache() * WEEK_IN_SECONDS) );
				unset( $_COOKIE[$cookie_key] );
			}

			self::$wishlist_ids[ $postType ] = $all_products[ $postType ];
		}

		wp_send_json( $data );

		wp_die();
	}

	public function bu_clean_wishlist() {
		$data = ['success' => false];

		$postType 	= $_POST['postType'];
		$cookie_key = $this->get_cookie_key( $postType );
		$all_products = $this->get_wishlists( $cookie_key, $postType );
		if( isset( $all_products[ $postType ] ) ) {
			self::$wishlist_ids[ $postType ] = [];
			$data['count'] = 0;
			$data['success'] = true;

			if( is_user_logged_in() ) {
				delete_user_meta( get_current_user_id(), $cookie_key );
			}

			Plugin::bu_setcookie($cookie_key, '', time() + ($this->get_days_cache() * WEEK_IN_SECONDS) );
			unset( $_COOKIE[$cookie_key] );
		}

		wp_send_json( $data );
		wp_die();
	}

	public function bu_delete_wishlist_item() {
		check_ajax_referer( 'wishlist-nonce', 'security' );

		$data = ['success' => true];

		$postId 	= $_POST['postId'];
		$postType 	= $_POST['postType'];
		$cookie_key = $this->get_cookie_key( $postType );
		$all_products = $this->get_wishlists( $cookie_key, $postType );
		self::$wishlist_ids[ $postType ] = isset( $all_products[ $postType ] ) ? $all_products[ $postType ] : [];

		if( in_array( $postId, self::$wishlist_ids[ $postType ] ) ) {
			if( ( $key = array_search($postId, $all_products[ $postType ]) ) !== false )
				unset($all_products[ $postType ][$key]);

			$data['success'] = true;
			$data['count'] = ($all_products[ $postType ]) ? count( $all_products[ $postType ] ) : 0;
		}

		if( $data['success'] ) {
			Plugin::bu_setcookie($cookie_key, implode(',', $all_products[ $postType ]), time() + ($this->get_days_cache() * WEEK_IN_SECONDS) );

			if( is_user_logged_in() ) {
				update_user_meta( get_current_user_id(), $cookie_key, implode(',', $all_products[ $postType ]) );

				Plugin::bu_setcookie($cookie_key, '', time() + ($this->get_days_cache() * WEEK_IN_SECONDS) );
				unset( $_COOKIE[$cookie_key] );
			}

			self::$wishlist_ids[ $postType ] = $all_products[ $postType ];
		}

		wp_send_json( $data );

		wp_die();
	}

	public function bu_add_all_to_cart() {
		$data = ['success' => false];
		$bool = false;
		$postType 	= $_POST['postType'];
		$cookie_key = $this->get_cookie_key( $postType );
		$all_products = $this->get_wishlists( $cookie_key, $postType );
		if( isset( $all_products[ $postType ] ) ) {
			foreach( $all_products[ $postType ] as $key => $product_id ) {
				$product = \wc_get_product( $product_id );

				if( $product === false )
					continue;

				$quantity = 1;
				$product_status = get_post_status( $product_id );

				$cart_id = \WC()->cart->generate_cart_id( $product_id );
				// Find the cart item key in the existing cart.
				$cart_item_key = \WC()->cart->find_product_in_cart( $cart_id );

				if( ( $product->get_type() == 'simple' || $product->get_type() == 'variation' ) && empty( $cart_item_key ) ) {
					$each_passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity );
					if ( $each_passed_validation && false !== \WC()->cart->add_to_cart( $product_id, $quantity ) && 'publish' === $product_status ) {
						do_action( 'woocommerce_ajax_added_to_cart', $product_id );
						\wc_clear_notices();
						$bool = true;
					}
				}
			}
		}

		if( $bool ) {
			$data['success'] = true;
			if( ! empty( $_POST['notice'] ) ) {
				$data['notice'] = '<p class="bu-add-all-cart-notice">' . do_shortcode( $_POST['notice'] ) . '</p>';
			}

			array_merge( $data, self::get_refreshed_fragments() );
		}

		wp_send_json( $data );
		//wp_die();
	}

	public static function get_refreshed_fragments() {
		ob_start();

		woocommerce_mini_cart();

		$mini_cart = ob_get_clean();

		return array(
			'fragments' => apply_filters(
				'woocommerce_add_to_cart_fragments',
				array(
					'div.widget_shopping_cart_content' => '<div class="widget_shopping_cart_content">' . $mini_cart . '</div>',
				)
			),
			'cart_hash' => WC()->cart->get_cart_hash(),
		);
	}

	public function bu_mini_wishlist() {
		check_ajax_referer( 'wishlist-nonce', 'security' );

		$element_id 		= $_POST['element'];
		$post_id 			= isset( $_POST['post'] ) ? $_POST['post'] : 0;
		$this->base_url 	= isset( $_POST['base_url'] ) ? $_POST['base_url'] : '';

		add_filter(
			'bricks/paginate_links_args',
			function( $args ) {
				$args['base'] = $this->base_url . '%_%';
				return $args;
			}
		);

		$data = \Bricks\Helpers::get_element_data( $post_id, $element_id );

		// Prepare flat list of elements for recursive calls
		foreach ( $data['elements'] as $element ) {
			\Bricks\Frontend::$elements[ $element['id'] ] = $element;
		}

		$element_instance = new \Bricks\Element_Block( $data['element'] );
		$wishlist = \Bricks\Frontend::render_children( $element_instance );

		wp_send_json(
			array(
				'fragments' => apply_filters(
					'bu_update_mini_wishlist',
					array(
						'.bu-mini-wishlist' => $wishlist
					)
				),
			)
		);
	}

	public static function get_days_cache() {
		$cache_days = 7;

		$life = ( !empty( Plugin::$bu_settings['wsl_cookie_life'] ) ) ? Plugin::$bu_settings['wsl_cookie_life'] : 'week';

		switch ( $life ) {
			case 'week':
				$cache_days = 7;
				break;
			case 'month':
				$cache_days = 30;
				break;
			case '3months':
				$cache_days = 30*3;
				break;
			case 'year':
				$cache_days = 365;
				break;
		}

		return $cache_days;
	}

	public static function get_wishlist_counter( $post_type ) {
	    return ! empty( self::$wishlist_ids[ $post_type ] ) ? count(self::$wishlist_ids[ $post_type ]) : 0;
    }

	public static function get_cookie_key($post_type = 'post' ){
		self::$cookie_key = self::COOKIE_KEY . "_{$post_type}_" . ( is_multisite() ? get_current_blog_id() : 0 );
		add_filter( 'litespeed_vary_cookies', function($cookies){
			$cookies[] = self::$cookie_key;
			
			return $cookies;
		});
		return self::$cookie_key;
	}

	public static function is_product_in_wishlist( $productId, $post_type ) {
		return in_array($productId, self::$wishlist_ids[ $post_type ]);
	}

	public function init_wishlist_products() {
		self::$wishlist_ids = $this->get_wishlists();
		self::$inited = true;
	}

	public function init_actions() {
		add_action( 'wp_login', [ $this, 'update_products_ids_after_login' ], 10, 2);
		add_action( 'init', function () {
			if ( ! self::$inited ) {
				$this->init_wishlist_products();
			}
		}, 15 );
	}

    public static function get_instance() {
        if ( null == self::$instance ) {
            self::$instance = new self();
        }

        return self::$instance;
    }
}