<?php
/**
 * All functions related to extra actions
 */

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

add_action( 'wp_ajax_sg_extra_action_check', 'giveasap_extra_action_check_ajax' );
add_action( 'wp_ajax_nopriv_sg_extra_action_check', 'giveasap_extra_action_check_ajax' );

/**
 * Checking for Action when clicked.
 */
function giveasap_extra_action_check_ajax() {
	check_ajax_referer( 'giveaway', 'nonce', true );

	$data = false;
	parse_str( isset( $_REQUEST['data'] ) ? \Simple_Giveaways\Helpers::clean( $_REQUEST['data'] ) : '', $data );

	if ( isset( $_REQUEST['value'] ) ) {
		$data['action_check_value'] = \Simple_Giveaways\Helpers::unslash_and_clean( $_REQUEST['value'] );
	}

	$action = isset( $data['extra_action'] ) ? $data['extra_action'] : false;

	if ( ! $action ) {
		wp_send_json_error( __( 'No Action selected', 'giveasap' ) );
		wp_die();
	}

	$instance_id = isset( $data['instance'] ) ? absint( $data['instance'] ) : 0;

	if ( ! $instance_id ) {
		wp_send_json_error( __( 'This action is invalid. No instance.', 'giveasap' ) );
		wp_die();
	}

	$subscriber_id = isset( $data['subscriber_id'] ) ? absint( $data['subscriber_id'] ) : 0;

	if ( ! $subscriber_id ) {
		wp_send_json_error( __( 'No subscriber found.', 'giveasap' ) );
		wp_die();
	}

	$actions = giveasap_get_registered_actions();

	$action_class = isset( $actions[ $action ] ) ? $actions[ $action ] : false;

	if ( ! $action_class ) {
		wp_send_json_error( __( 'Action could not be checked.', 'giveasap' ) );
		wp_die();
	}

	if ( ! class_exists( $action_class ) ) {
		wp_send_json_error( __( 'Action is not available anymore.', 'giveasap' ) );
		wp_die();
	}

	$action_object = new $action_class();
	$validation    = $action_object->validate( $instance_id, $subscriber_id, $data );

	if ( is_wp_error( $validation ) ) {
		wp_send_json_error( $validation->get_error_message() );
		wp_die();
	}

	wp_send_json_success( $validation );
	exit;
}

add_action( 'wp_ajax_sg_extra_action_complete', 'giveasap_extra_action_complete_ajax' );
add_action( 'wp_ajax_nopriv_sg_extra_action_complete', 'giveasap_extra_action_complete_ajax' );

/**
 * Completing the Action when clicked.
 */
function giveasap_extra_action_complete_ajax() {
	check_ajax_referer( 'giveaway', 'nonce', true );

	$data = false;
	parse_str( isset( $_REQUEST['data'] ) ? \Simple_Giveaways\Helpers::unslash_and_clean( urldecode( $_REQUEST['data'] ) ) : array(), $data );

	$action = isset( $data['extra_action'] ) ? $data['extra_action'] : false;

	if ( ! $action ) {
		wp_send_json_error( __( 'No Action selected', 'giveasap' ) );
		wp_die();
	}

	$instance_id = isset( $data['instance'] ) ? absint( $data['instance'] ) : 0;

	if ( ! $instance_id ) {
		wp_send_json_error( __( 'This action is invalid. No instance.', 'giveasap' ) );
		wp_die();
	}

	$subscriber_id = isset( $data['subscriber_id'] ) ? absint( $data['subscriber_id'] ) : 0;

	if ( ! $subscriber_id ) {
		wp_send_json_error( __( 'No subscriber found.', 'giveasap' ) );
		wp_die();
	}

	$actions = giveasap_get_registered_actions();

	$action_class = isset( $actions[ $action ] ) ? $actions[ $action ] : false;

	if ( ! $action_class ) {
		wp_send_json_error( __( 'Action could not be completed.', 'giveasap' ) );
		wp_die();
	}

	if ( ! class_exists( $action_class ) ) {
		wp_send_json_error( __( 'Action is not available anymore.', 'giveasap' ) );
		wp_die();
	}

	$action_object = new $action_class();
	$complete      = $action_object->complete( $instance_id, $subscriber_id, $data );

	if ( is_wp_error( $complete ) ) {
		wp_send_json_error( $complete->get_error_message() );
		wp_die();
	}

	$subscriber = giveasap_get_subscriber( $subscriber_id );

	$html = false;
	if ( $action_object->reload_html() ) {
		ob_start();
		$action_object->form_public_content();
		if ( $action_object->has_action_button() ) {
			$action_object->action_button();
		}
		$html = ob_get_clean();
	}

	$success_data = array(
		'html'              => $html,
		'complete_mark'     => $action_object->complete_mark(),
		'entries'           => $subscriber->get_entries(),
		'actions_completed' => count( giveasap_get_public_completed_actions_for_subscriber( $subscriber_id ) ),
	);

	wp_send_json_success( $success_data );
	wp_die();
}

/**
 * Return all the registered actions.
 *
 * was sg_get_registered_actions
 *
 * @return array
 */
function giveasap_get_registered_actions() {
	$actions = array(
		'subscribe'             => '\Simple_Giveaways\SG_Action_Subscribe',
		'referred'              => '\Simple_Giveaways\SG_Action_Referred',
		'visit'                 => '\Simple_Giveaways\SG_Action_Visit',
		'register'              => '\Simple_Giveaways\SG_Action_Register',
		'comment'               => '\Simple_Giveaways\SG_Action_Comment',
		'facebook_visit'        => '\Simple_Giveaways\SG_Action_Premium_Dummy_Facebook_Visit',
		'twitter_visit'         => '\Simple_Giveaways\SG_Action_Premium_Dummy_Twitter_Visit',
		'instagram_visit'       => '\Simple_Giveaways\SG_Action_Premium_Dummy_Instagram_Visit',
		'twitter_follow'        => '\Simple_Giveaways\SG_Action_Premium_Dummy_Twitter_Follow',
		'twitter_tweet'         => '\Simple_Giveaways\SG_Action_Premium_Dummy_Twitter_Tweet',
		'image'                 => '\Simple_Giveaways\SG_Action_Image',
		'question'              => '\Simple_Giveaways\SG_Action_Premium_Dummy_Question',
		'secret_code'           => '\Simple_Giveaways\SG_Action_Premium_Dummy_Secret_Code',
		'woocommerce_purchased' => '\Simple_Giveaways\SG_Action_Business_Dummy_WooCommerce_Purchased',
		'edd_purchased'         => '\Simple_Giveaways\SG_Action_Business_Dummy_EDD_Purchased',
		'invent_own'            => '\Simple_Giveaways\SG_Action_Premium_Dummy_Invent_Own',
		'youtube_watch'         => '\Simple_Giveaways\SG_Action_Premium_Dummy_Watch_Youtube',
		'mailchimp_signup'      => '\Simple_Giveaways\SG_Action_Premium_MailChimp_Signup',
		'give_donated'          => '\Simple_Giveaways\SG_Action_Business_Dummy_Give_Purchased',
		'specific_give_donated' => '\Simple_Giveaways\SG_Action_Business_Dummy_Specific_Give_Purchased',
		'mailerlite_signup'     => '\Simple_Giveaways\SG_Action_Premium_Mailerlite_Signup',
	);

	return apply_filters( 'giveasap_registered_actions', $actions );
}

/**
 * Return the Action object.
 *
 * was sg_get_action_object
 *
 * @param $slug
 *
 * @return boolean|\Simple_Giveaways\SG_Extra_Action False if it does not exist.
 */
function giveasap_get_action_object( $slug ) {
	$actions = giveasap_get_registered_actions();

	if ( isset( $actions[ $slug ] ) ) {
		$class = $actions[ $slug ];
		if ( class_exists( $class ) ) {
			return new $class();
		}
	}

	return false;
}

/**
 * Return the categories for actions
 *
 * was sg_get_actions_categories
 *
 * @return array
 */
function giveasap_get_actions_categories() {

	$categories = array(
		'general'     => __( 'General', 'giveasap' ),
		'twitter'     => __( 'X (Twitter)', 'giveasap' ),
		'woocommerce' => __( 'WooCommerce', 'giveasap' ),
		'edd'         => __( 'Easy Digital Downloads', 'giveasap' ),
		'give'        => __( 'GiveWP', 'giveasap' ),
		'newsletter'  => __( 'Newsletter', 'giveasap' ),
	);

	return apply_filters( 'giveasap_actions_categories', $categories );
}

/**
 * Get all the extra actions for the current giveaway.
 *
 * @param integer $giveaway_id Giveaway ID (Post ID).
 */
function giveasap_get_extra_actions( $giveaway_id ) {
	$extra = get_post_meta( $giveaway_id, 'giveasap_extra_entries', true );
	return isset( $extra['entries_actions'] ) ? $extra['entries_actions'] : array();
}

add_action( 'giveasap_the_form_end', 'giveasap_show_extra_actions', 20, 2 );

/**
 * Show extra actions on the form.
 *
 * was sg_show_extra_actions
 *
 * @param GiveASAP_Front $front
 * @param array          $settings
 */
function giveasap_show_extra_actions( $front, $settings = array() ) {
	$giveaway_id = $front->get_giveaway_id();
	if ( ! $giveaway_id ) {
		return; }

	$actions            = giveasap_get_extra_actions( $giveaway_id );
	$registered_actions = giveasap_get_registered_actions();

	if ( ! $actions ) {
		return; }

	$completed_actions   = giveasap_get_public_completed_actions_for_subscriber( $front->user->id );
	$completed_instances = wp_list_pluck( $completed_actions, 'instance' );

	?>
	<script>
		window.giveasap_completed_actions = window.giveasap_completed_actions || {};
		window.giveasap_completed_actions[<?php echo $giveaway_id; ?>] = window.giveasap_completed_actions[<?php echo $giveaway_id; ?>] || [];
		<?php
		foreach ( $completed_instances as $completed_instance ) {
			?>
				window.giveasap_completed_actions[<?php echo $giveaway_id; ?>].push( <?php echo $completed_instance; ?> );
				<?php
		}
		?>

	</script>
	<h3 class="giveasap-entries-title"><?php esc_html_e( 'Complete These Actions for Additional Entries', 'giveasap' ); ?></h3>
	<ul class="giveasap_extra_actions row">
		<?php

		foreach ( $actions as $index => $action ) {
			$action_class = isset( $registered_actions[ $action['action'] ] ) ? $registered_actions[ $action['action'] ] : false;

			if ( false === $action_class ) {
				continue;
			}

			$action_object = new $action_class();

			if ( $action_object->is_internal_only() ) {
				continue;
			}

			$action_object->set_admin_data( $action );
			$action_object->set_subscriber_id( $front->user->id );
			$action_object->set_giveaway_id( $giveaway_id );

			if ( $action_object->get_mandatory() && $action_object->get_mandatory() > count( $completed_actions ) ) {
				$action_object->set_locked();
			}

			do_action( 'giveasap_extra_action_before_public_render', $action_object, $completed_actions );

			echo '<li>';
			$action_object->form_public();
			echo '</li>';
		}
		?>
	</ul>
	<?php
}

/**
 * Get Extra Actions for Subscriber
 *
 * @param          $subscriber_id
 * @param string[]      $status
 *
 * @return array|object|null
 */
function giveasap_get_extra_actions_for_subscriber( $subscriber_id, $status = array( 'completed' ) ) {
	global $wpdb;

	if ( ! is_array( $status ) ) {
		$status = array( $status );
	}

	return $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->giveasap_actions . " WHERE subscriber_id=%d AND status IN ('%s') ORDER BY datetime DESC", absint( $subscriber_id ), implode( "','", $status ) ), ARRAY_A );
}

/**
 * Get public actions for subscribers (ignore internal).
 *
 * was sg_get_public_completed_actions_for_subscriber
 *
 * @param int $subscriber_id Subscriber ID for the giveaway.
 *
 * @return array|object|null
 */
function giveasap_get_public_completed_actions_for_subscriber( $subscriber_id ) {
	$actions = giveasap_get_extra_actions_for_subscriber( $subscriber_id, array( 'completed' ) );

	if ( ! $actions ) {
		return array();
	}

	// Removing internal only for now.
	$actions = array_filter(
		$actions,
		function( $item ) {
			return ! in_array( $item['action'], array( 'subscribe', 'referred' ) );
		}
	);

	return $actions;
}
