<?php
/**
 * Defines Data Export page functionality
 *
 * @link https://personalizewp.com/
 * @since 3.3.0
 *
 * @package PersonalizeWP
 * @subpackage PersonalizeWP/Admin
 */

namespace PersonalizeWP\Admin;

use PersonalizeWP\Admin\Admin_Base_Page;

defined( 'ABSPATH' ) || exit; // Exit if accessed directly.

/**
 * Defines Data Export page functionality
 */
class PageDataExport extends Admin_Base_Page {

	/**
	 * Slug for data export admin page
	 */
	const SLUG = 'personalizewp/data-export';

	/**
	 * URL for main data export admin page (listing)
	 *
	 * @var string
	 */
	public static $index_url = 'admin.php?page=' . self::SLUG;

	/**
	 * URL for processing an export request
	 *
	 * @var string
	 */
	public static $request_export = 'admin.php?page=' . self::SLUG . '&' . Admin::URL_ACTION . '=request_export';

	/**
	 * URL for triggering an export request email
	 *
	 * @var string
	 */
	public static $export_email_url = 'admin.php?page=' . self::SLUG . '&' . Admin::URL_ACTION . '=export_email&id=';

	/**
	 * URL for downloading an export
	 *
	 * @var string
	 */
	public static $download_url = 'admin.php?page=' . self::SLUG . '&' . Admin::URL_ACTION . '=download&id=';

	/**
	 * URL for deleting an export
	 *
	 * @var string
	 */
	public static $delete_export_url = 'admin.php?page=' . self::SLUG . '&' . Admin::URL_ACTION . '=delete_export&id=';

	/**
	 * Store the path for Data Export templates
	 *
	 * @var string
	 */
	public $template_path;

	/**
	 * Used to store the current page from the URL, shared between process/route actions
	 *
	 * @var string
	 */
	protected $current_page;

	/**
	 * Constructor
	 */
	protected function __construct() {
		parent::__construct();

		$this->page_title    = __( 'Data Export', 'personalizewp' );
		$this->template_path = plugin_dir_path( __DIR__ ) . 'admin/partials/activities/';

		add_action( 'admin_init', array( $this, 'process' ) );
		add_filter( 'parent_file', [ $this, 'switch_active_menu_item' ] );
		add_filter( 'set-screen-option', [ $this, 'set_screen_options' ], 10, 3 );
	}

	/**
	 * Display the Dashboard screen options.
	 */
	public function dashboard_screen_options() {
		$screen = get_current_screen();

		$is_screen = is_object( $screen ) && str_ends_with( $screen->id, self::SLUG );
		if ( ! $is_screen ) {
			return;
		}
		// Re-trigger core WP, as admins' call runs way too early IMHO.
		set_screen_options();

		$args = array(
			'label'   => __( 'Number of Export Requests per page (max 100):', 'personalizewp' ),
			'default' => 20,
			'option'  => 'edit_pwp_export_requests_per_page',
		);
		add_screen_option( 'per_page', $args );
	}

	/**
	 * Store the screen options.
	 *
	 * @param mixed  $screen_option The value to save instead of the option value.
	 *                              Default false (to skip saving the current option).
	 * @param string $option        The option name.
	 * @param int    $value         The option value.
	 */
	public function set_screen_options( $screen_option, $option, $value ) {
		if ( 'edit_pwp_export_requests_per_page' === $option ) {
			return min( max( (int) $value, 1 ), 100 );
		}
		return $screen_option;
	}

	/**
	 * Modifies admin menu of PersonalizeWP
	 * Sets active page for sub-sections which are invisible in the menu.
	 *
	 * @param string $parent_file The parent file.
	 *
	 * @return string
	 */
	public function switch_active_menu_item( $parent_file ) {
		global $plugin_page;

		if ( self::SLUG === $plugin_page ) {
			// Pretend to be on Recent Events, for highlighted menu item.
			$plugin_page = PageActivities::SLUG;
		}

		return $parent_file;
	}

	/**
	 * Process the current Data Export request, typically POST/GET, followed by a redirect.
	 *
	 * @return void
	 */
	public function process(): void {
		// Double check for user caps before any possible processing of data.
		if ( ! current_user_can( Admin::CAP ) ) {
			return;
		}

		if ( self::SLUG !== $this->current_page ) {
			return;
		}

		$data_export = Data_Export::instance();

		// Combine bulk actions for export requests triggered by WP_List_Table
		$action      = isset( $_REQUEST['action'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) : '';
		$action2     = isset( $_REQUEST['action2'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['action2'] ) ) : '';
		$bulk_action = ( '-1' !== $action && '' !== $action ) ? $action : $action2;

		if ( 'delete' === $bulk_action && ! empty( $_REQUEST['export_ids'] ) ) {
			// Verify bulk action nonce generated by WP_List_Table
			check_admin_referer( 'bulk-export_requests' );

			$ids = array_map( 'intval', (array) $_REQUEST['export_ids'] );
			foreach ( $ids as $export_id ) {
				// Delete directly without redirect
				$data_export->delete_export_request( $export_id );
			}

			wp_safe_redirect( add_query_arg( array( 'deleted' => 1 ), admin_url( self::$index_url ) ) );
			exit;
		}

		$item_id = (int) isset( $_REQUEST['id'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: used as intval

		switch ( (string) $this->current_action ) {
			case 'request_export':
				// Handle export form submission
				check_admin_referer( 'pwp-export-request' );

				// Success should trigger redirect
				$success = false;
				$data    = $data_export->validate_sanitize_export_data( $_POST );

				if ( empty( $data['errors'] ) && ! empty( $data['params'] ) ) {
					// Create export request
					$request_id = $data_export->create_export_request( $data['params'], $data['email'] );
					if ( ! is_wp_error( $request_id ) ) {
						$success = true;
					}
				}

				if ( $success ) {
					// Redirect to success page
					wp_safe_redirect( add_query_arg( array( 'created' => 1 ), admin_url( self::$index_url ) ) );
					exit;
				}
				break;


			case 'download':
				if ( empty( $item_id ) ) {
					wp_safe_redirect( admin_url( self::$index_url ) );
					exit;
				}
				// Note: Links can come from email, so can't have nonces

				$data_export->handle_download( $item_id );
				exit;
				break;

			case 'export_email':
				if ( empty( $item_id ) ) {
					wp_safe_redirect( admin_url( self::$index_url ) );
					exit;
				}
				check_admin_referer( 'pwp-export-email-' . $item_id ); // Immediately dies on failing.

				$success = false;
				$email   = $data_export->get_export_email( $item_id );
				if ( ! empty( $email ) ) {
					$success = $data_export->send_export_notification( $item_id, $email );
				}

				if ( $success ) {
					wp_safe_redirect( add_query_arg( array( 'export_emailed' => 1 ), admin_url( self::$index_url ) ) );
					exit;
				} else {
					// Redirect back for error message
					wp_safe_redirect( add_query_arg( array( 'export_email_error' => 1 ), admin_url( self::$index_url ) ) );
					exit;
				}
				break;

			case 'delete_export':
				if ( empty( $item_id ) ) {
					wp_safe_redirect( admin_url( self::$index_url ) );
					exit;
				}
				check_admin_referer( 'pwp-delete-export-' . $item_id ); // Immediately dies on failing.

				$success = $data_export->delete_export_request( $item_id );
				if ( $success ) {
					wp_safe_redirect( add_query_arg( array( 'deleted' => 1 ), admin_url( self::$index_url ) ) );
					exit;
				} else {
					// Redirect back for error message
					wp_safe_redirect( add_query_arg( array( 'delete_error' => 1 ), admin_url( self::$index_url ) ) );
					exit;
				}
				break;
		}
	}

	/**
	 * Route to the correct screen
	 *
	 * @return void
	 */
	public function route(): void {
		// Double check for user caps before any possible processing of data.
		if ( ! current_user_can( Admin::CAP ) ) {
			return;
		}

		if ( self::SLUG !== $this->current_page ) {
			return;
		}

		// Default to index screen (Data Export)
		$this->index_screen();
	}

	/**
	 * Display Data Export screen
	 *
	 * @return void
	 */
	protected function index_screen(): void {
		// Trigger messaging from actions.
		if ( isset( $_REQUEST['created'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- this is only displaying a message with no dynamic values.
			wp_admin_notice(
				'<span class="dashicons dashicons-yes-alt"></span>' . __( 'Export request created successfully.', 'personalizewp' ),
				array(
					'type'        => 'success',
					'id'          => 'message',
					'dismissible' => true,
				)
			);
		}
		if ( isset( $_REQUEST['export_emailed'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- this is only displaying a message with no dynamic values.
			wp_admin_notice(
				'<span class="dashicons dashicons-yes-alt"></span>' . __( 'Export email re-sent successfully.', 'personalizewp' ),
				array(
					'type'        => 'success',
					'id'          => 'message',
					'dismissible' => true,
				)
			);
		}
		if ( isset( $_REQUEST['deleted'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- this is only displaying a message with no dynamic values.
			wp_admin_notice(
				'<span class="dashicons dashicons-yes-alt"></span>' . __( 'Export request deleted successfully.', 'personalizewp' ),
				array(
					'type'        => 'success',
					'id'          => 'message',
					'dismissible' => true,
				)
			);
		}
		if ( isset( $_REQUEST['delete_error'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- this is only displaying a message with no dynamic values.
			wp_admin_notice(
				'<span class="dashicons dashicons-warning"></span>' . __( 'Failed to delete export request.', 'personalizewp' ),
				array(
					'type'        => 'error',
					'id'          => 'message',
					'dismissible' => true,
				)
			);
		}

		$this->display_header();

		// Display Data Export content
		require_once $this->template_path . 'data-export.php';

		$this->display_footer();
	}
}
