<?php
namespace WpRigel\Commandify;

defined( 'ABSPATH' ) || exit;

/**
 * Register action commands
 * Hooks into commandify_register_commands at priority 30 (after search and navigation)
 */
add_action(
	'commandify_register_commands',
	function () {
		// Clear Cache.
		commandify_register_command(
			array(
				'id'              => 'clear-cache',
				'title'           => __( 'Clear Cache', 'commandify' ),
				'description'     => __( 'Clear all WordPress caches', 'commandify' ),
				'type'            => 'action',
				'callback'        => function () {
					wp_cache_flush();

					return array(
						'success' => true,
						'message' => __( 'All caches cleared successfully! Object cache, transients, and opcache flushed.', 'commandify' ),
						'data'    => array(
							'timestamp' => current_time( 'mysql' ),
						),
					);
				},
				'category'        => 'tools',
				'icon'            => 'dashicons-update',
				'keywords'        => array( 'cache', 'clear', 'flush', 'performance' ),
				'capability'      => 'manage_options',
				'priority'        => 30,
				'loading_message' => __( 'Clearing cache...', 'commandify' ),
			)
		);

		// Check for Updates.
		commandify_register_command(
			array(
				'id'              => 'check-updates',
				'title'           => __( 'Check for Updates', 'commandify' ),
				'description'     => __( 'Check for WordPress, plugin, and theme updates', 'commandify' ),
				'type'            => 'action',
				'callback'        => function () {
					wp_update_plugins();
					wp_update_themes();
					wp_version_check();

					$update_plugins = get_site_transient( 'update_plugins' );
					$update_themes  = get_site_transient( 'update_themes' );
					$update_core    = get_site_transient( 'update_core' );

					$plugin_updates = ! empty( $update_plugins->response ) ? count( $update_plugins->response ) : 0;
					$theme_updates  = ! empty( $update_themes->response ) ? count( $update_themes->response ) : 0;
					$core_updates   = ! empty( $update_core->updates ) && isset( $update_core->updates[0] ) ? 1 : 0;

					$total = $plugin_updates + $theme_updates + $core_updates;

					$message_parts = array();
					if ( $core_updates > 0 ) {
						/* translators: %d: Number of WordPress updates */
						$message_parts[] = sprintf( __( '%d WordPress update', 'commandify' ), $core_updates );
					}
					if ( $plugin_updates > 0 ) {
						/* translators: %d: Number of plugin updates */
						$message_parts[] = sprintf( __( '%d plugin update(s)', 'commandify' ), $plugin_updates );
					}
					if ( $theme_updates > 0 ) {
						/* translators: %d: Number of theme updates */
						$message_parts[] = sprintf( __( '%d theme update(s)', 'commandify' ), $theme_updates );
					}

					$message = $total > 0
					/* translators: %s: List of available updates */
					? sprintf( __( 'Found: %s', 'commandify' ), implode( ', ', $message_parts ) )
						: __( 'Everything is up to date!', 'commandify' );

					return array(
						'success' => true,
						'message' => $message,
						'data'    => array(
							'total'          => $total,
							'plugin_updates' => $plugin_updates,
							'theme_updates'  => $theme_updates,
							'core_updates'   => $core_updates,
						),
					);
				},
				'category'        => 'tools',
				'icon'            => 'dashicons-update',
				'keywords'        => array( 'updates', 'check', 'upgrade', 'version' ),
				'capability'      => 'update_plugins',
				'priority'        => 25,
				'loading_message' => __( 'Checking for updates...', 'commandify' ),
			)
		);

		// Empty Trash.
		commandify_register_command(
			array(
				'id'              => 'empty-trash',
				'title'           => __( 'Empty Trash', 'commandify' ),
				'description'     => __( 'Permanently delete all trashed items by post type', 'commandify' ),
				'type'            => 'action',
				'callback'        => 'WpRigel\Commandify\empty_trash_callback',
				'category'        => 'tools',
				'icon'            => 'dashicons-trash',
				'keywords'        => array( 'trash', 'empty', 'delete', 'clean' ),
				'capability'      => 'delete_posts',
				'priority'        => 20,
				'loading_message' => __( 'Emptying trash...', 'commandify' ),
				'form'            => array(
					'title'       => __( 'Empty Trash', 'commandify' ),
					'description' => __( 'Select a post type to permanently delete all trashed items. This action cannot be undone.', 'commandify' ),
					'fields'      => array(
						array(
							'name'     => 'post_type',
							'label'    => __( 'Post Type', 'commandify' ),
							'type'     => 'select',
							'required' => true,
							'options'  => get_empty_trash_post_types(),
						),
					),
					'submit_text' => __( 'Empty Trash', 'commandify' ),
				),
			)
		);

		// Flush Rewrite Rules.
		commandify_register_command(
			array(
				'id'              => 'flush-rewrite-rules',
				'title'           => __( 'Flush Rewrite Rules', 'commandify' ),
				'description'     => __( 'Regenerate permalink rewrite rules', 'commandify' ),
				'type'            => 'action',
				'callback'        => function () {
					flush_rewrite_rules( false );

					return array(
						'success' => true,
						'message' => __( 'Rewrite rules flushed successfully! Permalink structure has been regenerated.', 'commandify' ),
						'data'    => array(
							'timestamp' => current_time( 'mysql' ),
						),
					);
				},
				'category'        => 'tools',
				'icon'            => 'dashicons-admin-links',
				'keywords'        => array( 'flush', 'rewrite', 'rules', 'permalinks', 'permalink' ),
				'capability'      => 'manage_options',
				'priority'        => 15,
				'loading_message' => __( 'Flushing rewrite rules...', 'commandify' ),
			)
		);
	}
);

/**
 * Get post types for empty trash form
 * Returns post types that are public and have show_ui enabled
 *
 * @return array Array of post type options
 */
function get_empty_trash_post_types() {
	$post_types = get_post_types(
		array(
			'public'  => true,
			'show_ui' => true,
		),
		'objects'
	);

	$options = array();

	foreach ( $post_types as $post_type ) {
		// Skip built-in types that don't support trash
		if ( in_array( $post_type->name, array( 'attachment', 'nav_menu_item', 'revision' ), true ) ) {
			continue;
		}

		// Check if user has permission to delete posts of this type
		$cap = $post_type->cap->delete_posts ?? 'delete_posts';
		if ( ! current_user_can( $cap ) ) {
			continue;
		}

		$label                       = $post_type->labels->name ?? $post_type->name;
		$options[ $post_type->name ] = $label;
	}

	return $options;
}

/**
 * Optimized empty trash callback with post type selection and batch processing
 * Deletes all trashed posts of a specific post type
 *
 * @param \WP_REST_Request|array $request Request object or params array
 * @return array Response array with success status and message
 */
function empty_trash_callback( $request = array() ) {
	// Extract params from request object or use array directly
	if ( $request instanceof \WP_REST_Request ) {
		$params = $request->get_params();
	} else {
		$params = is_array( $request ) ? $request : array();
	}

	$post_type = isset( $params['post_type'] ) ? sanitize_text_field( $params['post_type'] ) : '';

	if ( empty( $post_type ) ) {
		return array(
			'success' => false,
			'message' => __( 'Post type is required', 'commandify' ),
		);
	}

	// Verify post type exists and user has permission
	$post_type_obj = get_post_type_object( $post_type );
	if ( ! $post_type_obj ) {
		return array(
			'success' => false,
			'message' => __( 'Invalid post type', 'commandify' ),
		);
	}

	$cap = $post_type_obj->cap->delete_posts ?? 'delete_posts';
	if ( ! current_user_can( $cap ) ) {
		return array(
			'success' => false,
			'message' => __( 'You do not have permission to delete posts of this type', 'commandify' ),
		);
	}

	// Extend execution time for large operations
	if ( function_exists( 'set_time_limit' ) ) {
		set_time_limit( 300 );
	}

	// Get total count first
	$total_count = wp_count_posts( $post_type );
	$trash_count = isset( $total_count->trash ) ? (int) $total_count->trash : 0;

	if ( 0 === $trash_count ) {
		$post_type_label = $post_type_obj->labels->name ?? $post_type;
		return array(
			'success' => true,
			/* translators: %s: Post type label */
			'message' => sprintf( __( 'No trashed %s found', 'commandify' ), strtolower( $post_type_label ) ),
			'data'    => array(
				'deleted' => 0,
				'total'   => 0,
			),
		);
	}

	$threshold = 200;
	// Use batch processing if more than 200 items
	$offset = isset( $params['offset'] ) ? (int) $params['offset'] : 0;
	$limit  = isset( $params['limit'] ) ? (int) $params['limit'] : 200;
	// Process 200 items per batch

	// For small datasets, delete all at once (normal operation)
	if ( $trash_count <= $threshold && 0 === $offset ) {
		// Query all trashed posts of this type
		$trashed_posts_query = new \WP_Query(
			array(
				'post_status'            => 'trash',
				'post_type'              => $post_type,
				'posts_per_page'         => -1,
				'fields'                 => 'ids',
				'no_found_rows'          => true,
				'update_post_meta_cache' => false,
				'update_post_term_cache' => false,
				'orderby'                => 'ID',
				'order'                  => 'ASC',
			)
		);

		$deleted = 0;
		if ( $trashed_posts_query->have_posts() ) {
			foreach ( $trashed_posts_query->posts as $post_id ) {
				if ( wp_delete_post( $post_id, true ) ) {
					++$deleted;
				}
			}
		}

		wp_reset_postdata();

		$post_type_label = $post_type_obj->labels->name ?? $post_type;
		$message         = $deleted > 0
			/* translators: %1$d: Number deleted, %2$s: Post type label */
			? sprintf( __( 'Successfully deleted %1$d trashed %2$s', 'commandify' ), $deleted, strtolower( $post_type_label ) )
			/* translators: %s: Post type label */
			: sprintf( __( 'No trashed %s found', 'commandify' ), strtolower( $post_type_label ) );

		return array(
			'success' => true,
			'message' => $message,
			'data'    => array(
				'deleted'   => $deleted,
				'total'     => $trash_count,
				'completed' => true,
			),
		);
	}//end if

	// For large datasets, use batch processing
	$trashed_posts_query = new \WP_Query(
		array(
			'post_status'            => 'trash',
			'post_type'              => $post_type,
			'posts_per_page'         => $limit,
			'offset'                 => $offset,
			'fields'                 => 'ids',
			'no_found_rows'          => true,
			'update_post_meta_cache' => false,
			'update_post_term_cache' => false,
			'orderby'                => 'ID',
			'order'                  => 'ASC',
		)
	);

	$deleted    = 0;
	$start_time = time();

	if ( $trashed_posts_query->have_posts() ) {
		foreach ( $trashed_posts_query->posts as $post_id ) {
			// Check time limit (stop if approaching timeout)
			if ( ( time() - $start_time ) > 240 ) {
				// Stop at 4 minutes
				break;
			}

			if ( wp_delete_post( $post_id, true ) ) {
				++$deleted;
			}

			// Free memory periodically
			if ( 0 === $deleted % 50 ) {
				\wp_cache_flush_group( 'posts' );
				\wp_cache_flush_group( 'post_meta' );
			}
		}
	}

	wp_reset_postdata();

	$new_offset = $offset + count( $trashed_posts_query->posts );
	$remaining  = max( 0, $trash_count - $new_offset );
	$completed  = 0 === $remaining;

	$post_type_label = $post_type_obj->labels->name ?? $post_type;
	$message         = $deleted > 0
		/* translators: %1$d: Number deleted, %3$s: Post type label */
		? sprintf(
			/* translators: %1$d: Number deleted, %3$s: Post type label */
			__( 'Deleted %1$d trashed %3$s', 'commandify' ) . ( ! $completed ? ' (' . sprintf( /* translators: %d: Number remaining */ __( '%d remaining', 'commandify' ), $remaining ) . ')' : '' ),
			$deleted,
			$remaining,
			strtolower( $post_type_label )
		)
		/* translators: %s: Post type label */
		: sprintf( __( 'No trashed %s found', 'commandify' ), strtolower( $post_type_label ) );

	return array(
		'success' => true,
		'message' => $message,
		'data'    => array(
			'deleted'   => $deleted,
			'total'     => $trash_count,
			'offset'    => $new_offset,
			'remaining' => $remaining,
			'completed' => $completed,
			'continue'  => ! $completed,
		),
	);
}
