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

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

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

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

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

    if ( isset( $_REQUEST['value'] ) ) {
        $data['action_check_value'] = sanitize_text_field( $_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 = sg_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', 'sg_extra_action_complete_ajax' );
add_action( 'wp_ajax_nopriv_sg_extra_action_complete', 'sg_extra_action_complete_ajax' );

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

	$data = false;
	parse_str( isset( $_REQUEST['data'] ) ? $_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 = sg_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 = sg_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( sg_get_public_completed_actions_for_subscriber( $subscriber_id ) )
    );

	wp_send_json_success( $success_data );
	wp_die();
}

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

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

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

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

    return false;
}

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

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

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

/**
 * Get all the extra actions for the current giveaway.
 *
 * @param integer $giveaway_id Giveaway ID (Post ID).
 */
function sg_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', 'sg_show_extra_actions', 20, 2 );

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

	$actions = sg_get_extra_actions( $giveaway_id );
    $registered_actions = sg_get_registered_actions();

	if ( ! $actions ) { return; }

	$completed_actions = sg_get_public_completed_actions_for_subscriber( $front->user->id );

	?>
	<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 );
		    if ( $action_object->get_mandatory() && $action_object->get_mandatory() > count( $completed_actions ) ) {
		        $action_object->set_locked();
		    }
		    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 sg_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).
 * @param int $subscriber_id Subscriber ID for the giveaway.
 *
 * @return array|object|null
 */
function sg_get_public_completed_actions_for_subscriber( $subscriber_id ) {
    $actions = sg_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;
}