<?php
/**
 * Sifency Addons Widget Duplication Feature
 *
 * Enables easy duplication of widgets in Elementor editor.
 *
 * @package Sifency_Addons
 * @subpackage Features
 */

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

class Sifency_Addons_Widget_Duplication {

	/**
	 * Initialize widget duplication feature
	 */
	public static function init() {
		add_action( 'elementor/element/after_add_attributes', array( __CLASS__, 'add_duplicate_control' ) );
		add_action( 'wp_ajax_sifency_duplicate_widget', array( __CLASS__, 'ajax_duplicate_widget' ) );
	}

	/**
	 * Add duplicate control to all widgets
	 */
	public static function add_duplicate_control( $element ) {
		$selector = $element->get_unique_selector();
		if ( null === $selector ) {
			return;
		}

		$element->start_injection(
			array(
				'of' => '_title',
				'at' => 'after',
			)
		);

		// We'll handle duplication via JS context menu
		$element->end_injection();
	}

	/**
	 * AJAX handler to duplicate widget
	 */
	public static function ajax_duplicate_widget() {
		// Verify nonce properly
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'sifency_duplicate_widget' ) ) {
			wp_send_json_error( array( 'message' => 'Security verification failed.' ) );
		}

		if ( ! isset( $_POST['post_id'] ) || ! isset( $_POST['element_id'] ) ) {
			wp_send_json_error( array( 'message' => 'Missing required parameters' ) );
		}

		$post_id    = intval( $_POST['post_id'] );
		$element_id = sanitize_text_field( $_POST['element_id'] );

		if ( ! current_user_can( 'edit_post', $post_id ) ) {
			wp_send_json_error( array( 'message' => 'Insufficient permissions' ) );
		}

		if ( ! class_exists( '\Elementor\Plugin' ) ) {
			wp_send_json_error( 'Elementor not active' );
		}

		$elementor = \Elementor\Plugin::instance();
		$document  = $elementor->documents->get( $post_id );

		if ( ! $document ) {
			wp_send_json_error( 'Document not found' );
		}

		$elements   = $document->get_elements_data();
		$duplicated = false;

		$updated_elements = self::duplicate_element( $elements, $element_id, $duplicated );

		if ( $duplicated ) {
			$document->save( array( 'elements' => $updated_elements ) );
			wp_send_json_success(
				array(
					'message'  => 'Widget duplicated successfully',
					'elements' => $updated_elements,
				)
			);
		} else {
			wp_send_json_error( 'Widget not found' );
		}
	}

	/**
	 * Recursively find and duplicate element
	 */
	private static function duplicate_element( &$elements, $target_id, &$duplicated ) {
		$new_elements = array();

		foreach ( $elements as $element ) {
			$new_elements[] = $element;

			if ( isset( $element['id'] ) && $element['id'] === $target_id ) {
				$duplicate       = $element;
				$duplicate['id'] = 'element-' . uniqid();

				if ( isset( $duplicate['elements'] ) ) {
					foreach ( $duplicate['elements'] as &$inner ) {
						$inner['id'] = 'element-' . uniqid();
					}
				}

				$new_elements[] = $duplicate;
				$duplicated     = true;
			}

			if ( isset( $element['elements'] ) && ! $duplicated ) {
				$element['elements']                                    = self::duplicate_element( $element['elements'], $target_id, $duplicated );
				$new_elements[ count( $new_elements ) - 1 ]['elements'] = $element['elements'];
			}
		}

		return $new_elements;
	}

	/**
	 * Enqueue widget duplication script
	 */
	public static function enqueue_scripts() {
		wp_enqueue_script(
			'sifency-widget-duplication',
			SIFENCY_ADDONS_URL . 'assets/js/admin/widget-duplication.js',
			array( 'jquery' ),
			SIFENCY_ADDONS_VERSION,
			true
		);

		wp_localize_script(
			'sifency-widget-duplication',
			'sifencyWidgetDuplication',
			array(
				'nonce'   => wp_create_nonce( 'sifency_duplicate_widget' ),
				'ajaxurl' => admin_url( 'admin-ajax.php' ),
			)
		);
	}

	/**
	 * Get widget favorites from user meta
	 */
	public static function get_widget_favorites( $user_id = null ) {
		if ( ! $user_id ) {
			$user_id = get_current_user_id();
		}

		return get_user_meta( $user_id, 'sifency_widget_favorites', true ) ?: array();
	}

	/**
	 * Add widget to favorites
	 */
	public static function add_to_favorites( $widget_name, $user_id = null ) {
		if ( ! $user_id ) {
			$user_id = get_current_user_id();
		}

		$favorites = self::get_widget_favorites( $user_id );

		if ( ! in_array( $widget_name, $favorites, true ) ) {
			$favorites[] = $widget_name;
			update_user_meta( $user_id, 'sifency_widget_favorites', $favorites );
		}

		return $favorites;
	}

	/**
	 * Remove widget from favorites
	 */
	public static function remove_from_favorites( $widget_name, $user_id = null ) {
		if ( ! $user_id ) {
			$user_id = get_current_user_id();
		}

		$favorites = self::get_widget_favorites( $user_id );
		$favorites = array_filter(
			$favorites,
			function( $name ) use ( $widget_name ) {
				return $name !== $widget_name;
			}
		);

		update_user_meta( $user_id, 'sifency_widget_favorites', array_values( $favorites ) );

		return $favorites;
	}

	/**
	 * AJAX handler for favorite toggle
	 */
	public static function ajax_toggle_favorite() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'sifency_widget_favorite' ) ) {
			wp_send_json_error( array( 'message' => 'Security verification failed.' ) );
		}

		if ( ! isset( $_POST['widget_name'] ) ) {
			wp_send_json_error( array( 'message' => 'Missing widget name' ) );
		}

		$widget_name = sanitize_text_field( $_POST['widget_name'] );
		$user_id     = get_current_user_id();

		$favorites   = self::get_widget_favorites( $user_id );
		$is_favorite = in_array( $widget_name, $favorites, true );

		if ( $is_favorite ) {
			$favorites = self::remove_from_favorites( $widget_name, $user_id );
		} else {
			$favorites = self::add_to_favorites( $widget_name, $user_id );
		}

		wp_send_json_success(
			array(
				'is_favorite' => ! $is_favorite,
				'favorites'   => $favorites,
			)
		);
	}
}

add_action( 'elementor/editor/after_enqueue_scripts', array( 'Sifency_Addons_Widget_Duplication', 'enqueue_scripts' ) );
add_action( 'wp_ajax_sifency_widget_favorite', array( 'Sifency_Addons_Widget_Duplication', 'ajax_toggle_favorite' ) );

Sifency_Addons_Widget_Duplication::init();
