<?php
/**
 * Tools API Controller
 *
 * @package DokanKits\REST\Controllers\Version1
 * @since 3.0.2
 */

namespace DokanKits\REST\Controllers\Version1;

use DokanKits\Core\Data\DataStore;
use DokanKits\Core\Data\Models\Settings;
use DokanKits\Core\Data\Stores\SettingsDataStore;
use DokanKits\REST\Controllers\Controller;
use DokanKits\Setup\Migrator;
use DokanKits\Setup\SystemCheck;
use Exception;
use WP_Error;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use wpdb;

/**
 * Tools API Controller class.
 *
 * Handles API endpoints for managing maintenance and utility tools.
 *
 * @since 3.0.2
 */
class ToolsController extends Controller {
	/**
	 * Route base.
	 *
	 * @var string
	 */
	protected $rest_base = 'tools';

	/**
	 * Register routes.
	 *
	 * @since 3.0.2
	 *
	 * @return void
	 */
	public function register_routes() {
		// Database tables management.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/database/recreate',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'recreate_tables' ),
					'permission_callback' => array( $this, 'admin_permissions_check' ),
					'args'                => $this->get_recreate_tables_params(),
				),
				'schema' => array( $this, 'get_database_operation_schema' ),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/database/optimize',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'optimize_tables' ),
					'permission_callback' => array( $this, 'admin_permissions_check' ),
					'args'                => $this->get_optimize_tables_params(),
				),
				'schema' => array( $this, 'get_database_operation_schema' ),
			)
		);

		// Migration management.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/migration/run',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'run_migration' ),
					'permission_callback' => array( $this, 'admin_permissions_check' ),
					'args'                => $this->get_run_migration_params(),
				),
				'schema' => array( $this, 'get_migration_operation_schema' ),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/migration/status',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_migration_status' ),
					'permission_callback' => array( $this, 'admin_permissions_check' ),
					'args'                => $this->get_migration_status_params(),
				),
				'schema' => array( $this, 'get_migration_status_schema' ),
			)
		);

		// System diagnostics.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/diagnostics/run',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'run_diagnostics' ),
					'permission_callback' => array( $this, 'admin_permissions_check' ),
					'args'                => $this->get_run_diagnostics_params(),
				),
				'schema' => array( $this, 'get_diagnostics_schema' ),
			)
		);

		// Log management.
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/download-logs',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'download_logs' ),
					'permission_callback' => array( $this, 'admin_permissions_check' ),
					'args'                => $this->get_download_logs_params(),
				),
				'schema' => array( $this, 'get_logs_schema' ),
			)
		);
	}

	/**
	 * Get recreate tables endpoint parameters.
	 *
	 * @since 3.0.2
	 *
	 * @return array Recreate tables parameters.
	 */
	private function get_recreate_tables_params(): array {
		$params = array();

		/**
		 * Filter recreate tables endpoint parameters.
		 *
		 * @since 3.0.0
		 *
		 * @param array $params Recreate tables parameters.
		 */
		return apply_filters( 'dokan_kits_rest_recreate_tables_params', $params );
	}

	/**
	 * Get optimize tables endpoint parameters.
	 *
	 * @since 3.0.2
	 *
	 * @return array Optimize tables parameters.
	 */
	private function get_optimize_tables_params(): array {
		$params = array();

		/**
		 * Filter optimize tables endpoint parameters.
		 *
		 * @since 3.0.0
		 *
		 * @param array $params Optimize tables parameters.
		 */
		return apply_filters( 'dokan_kits_rest_optimize_tables_params', $params );
	}

	/**
	 * Get run migration endpoint parameters.
	 *
	 * @since 3.0.2
	 *
	 * @return array Run migration parameters.
	 */
	private function get_run_migration_params(): array {
		$params = array();

		/**
		 * Filter run migration endpoint parameters.
		 *
		 * @since 3.0.0
		 *
		 * @param array $params Run migration parameters.
		 */
		return apply_filters( 'dokan_kits_rest_run_migration_params', $params );
	}

	/**
	 * Get migration status endpoint parameters.
	 *
	 * @since 3.0.2
	 *
	 * @return array Migration status parameters.
	 */
	private function get_migration_status_params(): array {
		$params = array();

		/**
		 * Filter migration status endpoint parameters.
		 *
		 * @since 3.0.0
		 *
		 * @param array $params Migration status parameters.
		 */
		return apply_filters( 'dokan_kits_rest_migration_status_params', $params );
	}

	/**
	 * Get run diagnostics endpoint parameters.
	 *
	 * @since 3.0.2
	 *
	 * @return array Run diagnostics parameters.
	 */
	private function get_run_diagnostics_params(): array {
		$params = array();

		/**
		 * Filter run diagnostics endpoint parameters.
		 *
		 * @since 3.0.0
		 *
		 * @param array $params Run diagnostics parameters.
		 */
		return apply_filters( 'dokan_kits_rest_run_diagnostics_params', $params );
	}

	/**
	 * Get download logs endpoint parameters.
	 *
	 * @since 3.0.2
	 *
	 * @return array Download logs parameters.
	 */
	private function get_download_logs_params(): array {
		$params = array();

		/**
		 * Filter download logs endpoint parameters.
		 *
		 * @since 3.0.0
		 *
		 * @param array $params Download logs parameters.
		 */
		return apply_filters( 'dokan_kits_rest_download_logs_params', $params );
	}

	/**
	 * Recreate database tables.
	 *
	 * @since 3.0.2
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
	 */
	public function recreate_tables( WP_REST_Request $request ) {
		try {
			/**
			 * Action fired before recreating database tables.
			 *
			 * @since 3.0.2
			 *
			 * @param WP_REST_Request $request The request object.
			 */
			do_action( 'dokan_kits_before_recreate_tables', $request );

			$result = $this->recreate_database_tables();

			/**
			 * Action fired after recreating database tables.
			 *
			 * @since 3.0.2
			 *
			 * @param array           $result  The recreation result.
			 * @param WP_REST_Request $request The request object.
			 */
			do_action( 'dokan_kits_after_recreate_tables', $result, $request );

			return $this->success(
				$result,
				sprintf(
				/* translators: %d: Number of tables recreated */
					_n(
						'%d database table recreated successfully.',
						'%d database tables recreated successfully.',
						count( $result['tables'] ),
						'dokan-kits'
					),
					count( $result['tables'] )
				)
			);

		} catch ( Exception $e ) {
			return $this->handle_exception( $e, 'recreate_tables' );
		}
	}

	/**
	 * Optimize database tables.
	 *
	 * @since 3.0.2
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
	 */
	public function optimize_tables( WP_REST_Request $request ) {
		try {
			/**
			 * Action fired before optimizing database tables.
			 *
			 * @since 3.0.2
			 *
			 * @param WP_REST_Request $request The request object.
			 */
			do_action( 'dokan_kits_before_optimize_tables', $request );

			$result = $this->optimize_database_tables();

			/**
			 * Action fired after optimizing database tables.
			 *
			 * @since 3.0.2
			 *
			 * @param array           $result  The optimization result.
			 * @param WP_REST_Request $request The request object.
			 */
			do_action( 'dokan_kits_after_optimize_tables', $result, $request );

			if ( ! empty( $result['failed'] ) ) {
				return $this->error(
					__( 'Some tables could not be optimized.', 'dokan-kits' ),
					'partial_optimization_failure',
					207, // Multi-Status.
					$result
				);
			}

			return $this->success(
				$result,
				sprintf(
				/* translators: %d: Number of tables optimized */
					_n(
						'%d database table optimized successfully.',
						'%d database tables optimized successfully.',
						count( $result['optimized'] ),
						'dokan-kits'
					),
					count( $result['optimized'] )
				)
			);

		} catch ( Exception $e ) {
			return $this->handle_exception( $e, 'optimize_tables' );
		}
	}

	/**
	 * Run database migration.
	 *
	 * @since 3.0.2
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
	 */
	public function run_migration( WP_REST_Request $request ) {
		try {
			/**
			 * Action fired before running migration.
			 *
			 * @since 3.0.2
			 *
			 * @param WP_REST_Request $request The request object.
			 */
			do_action( 'dokan_kits_before_run_migration', $request );

			$migrator = dokan_kits_get_container()->get( Migrator::class );

			if ( $migrator->is_migration_running() ) {
				return $this->error(
					__( 'A migration is already in progress.', 'dokan-kits' ),
					'migration_in_progress',
					409 // Conflict.
				);
			}

			$result = $this->execute_migration( $migrator );

			/**
			 * Action fired after running migration.
			 *
			 * @since 3.0.2
			 *
			 * @param array           $result  The migration result.
			 * @param WP_REST_Request $request The request object.
			 */
			do_action( 'dokan_kits_after_run_migration', $result, $request );

			return $this->success(
				$result,
				sprintf(
				/* translators: %d: Number of migration versions executed */
					_n(
						'%d migration version executed successfully.',
						'%d migration versions executed successfully.',
						count( $result['versions'] ),
						'dokan-kits'
					),
					count( $result['versions'] )
				)
			);

		} catch ( Exception $e ) {
			return $this->handle_exception( $e, 'run_migration' );
		}
	}

	/**
	 * Get migration status.
	 *
	 * @since 3.0.2
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
	 */
	public function get_migration_status( WP_REST_Request $request ) {
		try {
			/**
			 * Action fired before getting migration status.
			 *
			 * @since 3.0.2
			 *
			 * @param WP_REST_Request $request The request object.
			 */
			do_action( 'dokan_kits_before_get_migration_status', $request );

			$status_data = $this->prepare_migration_status();

			/**
			 * Filter the migration status data.
			 *
			 * @since 3.0.2
			 *
			 * @param array           $status_data The migration status data.
			 * @param WP_REST_Request $request     The request object.
			 */
			$status_data = apply_filters( 'dokan_kits_migration_status_data', $status_data, $request );

			/**
			 * Action fired after getting migration status.
			 *
			 * @since 3.0.2
			 *
			 * @param array           $status_data The migration status data.
			 * @param WP_REST_Request $request     The request object.
			 */
			do_action( 'dokan_kits_after_get_migration_status', $status_data, $request );

			return $this->success(
				$status_data,
				__( 'Migration status retrieved successfully.', 'dokan-kits' )
			);

		} catch ( Exception $e ) {
			return $this->handle_exception( $e, 'get_migration_status' );
		}
	}

	/**
	 * Run system diagnostics.
	 *
	 * @since 3.0.2
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
	 */
	public function run_diagnostics( WP_REST_Request $request ) {
		try {
			/**
			 * Action fired before running diagnostics.
			 *
			 * @since 3.0.2
			 *
			 * @param WP_REST_Request $request The request object.
			 */
			do_action( 'dokan_kits_before_run_diagnostics', $request );

			$diagnostics_data = $this->perform_system_diagnostics();

			/**
			 * Filter the diagnostics data.
			 *
			 * @since 3.0.2
			 *
			 * @param array           $diagnostics_data The diagnostics data.
			 * @param WP_REST_Request $request          The request object.
			 */
			$diagnostics_data = apply_filters( 'dokan_kits_diagnostics_data', $diagnostics_data, $request );

			/**
			 * Action fired after running diagnostics.
			 *
			 * @since 3.0.2
			 *
			 * @param array           $diagnostics_data The diagnostics data.
			 * @param WP_REST_Request $request          The request object.
			 */
			do_action( 'dokan_kits_after_run_diagnostics', $diagnostics_data, $request );

			return $this->success(
				$diagnostics_data,
				__( 'System diagnostics completed successfully.', 'dokan-kits' )
			);

		} catch ( Exception $e ) {
			return $this->handle_exception( $e, 'run_diagnostics' );
		}
	}

	/**
	 * Download error logs.
	 *
	 * @since 3.0.2
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
	 */
	public function download_logs( WP_REST_Request $request ) {
		try {
			/**
			 * Action fired before preparing logs for download.
			 *
			 * @since 3.0.2
			 *
			 * @param WP_REST_Request $request The request object.
			 */
			do_action( 'dokan_kits_before_download_logs', $request );

			$logs_data = $this->prepare_log_files();

			if ( is_wp_error( $logs_data ) ) {
				return $logs_data;
			}

			/**
			 * Filter the logs data.
			 *
			 * @since 3.0.2
			 *
			 * @param array           $logs_data The logs data.
			 * @param WP_REST_Request $request   The request object.
			 */
			$logs_data = apply_filters( 'dokan_kits_logs_data', $logs_data, $request );

			/**
			 * Action fired after preparing logs for download.
			 *
			 * @since 3.0.2
			 *
			 * @param array           $logs_data The logs data.
			 * @param WP_REST_Request $request   The request object.
			 */
			do_action( 'dokan_kits_after_download_logs', $logs_data, $request );

			return $this->success(
				$logs_data,
				__( 'Log files prepared for download successfully.', 'dokan-kits' )
			);

		} catch ( Exception $e ) {
			return $this->handle_exception( $e, 'download_logs' );
		}
	}

	/**
	 * Recreate database tables.
	 *
	 * @since 3.0.2
	 *
	 * @return array Recreation result.
	 */
	private function recreate_database_tables(): array {
		$data_stores    = dokan_kits_get_container()->get( 'data-store-service' );
		$created_tables = array();
		$failed_tables  = array();

		foreach ( $data_stores as $data_store ) {
			if ( ! $data_store instanceof DataStore ) {
				continue;
			}

			try {
				$data_store->create_tables();
				$data_store->verify_tables();
				$created_tables[] = $data_store->get_table_name();
			} catch ( Exception $e ) {
				$failed_tables[ $data_store->get_table_name() ] = $e->getMessage();
			}
		}

		/**
		 * Action after recreating all data store tables.
		 *
		 * @since 3.0.2
		 *
		 * @param array $data_stores Array of data stores.
		 * @param array $created_tables Array of successfully created tables.
		 * @param array $failed_tables Array of failed table creations.
		 */
		do_action( 'dokan_kits_tables_recreated', $data_stores, $created_tables, $failed_tables );

		return array(
			'tables' => $created_tables,
			'failed' => $failed_tables,
			'total'  => count( $created_tables ),
		);
	}

	/**
	 * Optimize database tables.
	 *
	 * @since 3.0.2
	 *
	 * @return array Optimization result.
	 */
	private function optimize_database_tables(): array {
		global $wpdb;

		$tables    = $this->get_dokan_kits_tables();
		$optimized = array();
		$failed    = array();

		foreach ( $tables as $table ) {
			$table_name = $wpdb->prefix . $table;

			try {
				$repair_result   = $wpdb->query( $wpdb->prepare( 'REPAIR TABLE %i', $table_name ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				$optimize_result = $wpdb->query( $wpdb->prepare( 'OPTIMIZE TABLE %i', $table_name ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared

				if ( false !== $repair_result && false !== $optimize_result ) {
					$optimized[] = $table_name;
				} else {
					$failed[ $table_name ] = __( 'Failed to repair or optimize table.', 'dokan-kits' );
				}
			} catch ( Exception $e ) {
				$failed[ $table_name ] = $e->getMessage();
			}
		}

		return array(
			'optimized' => $optimized,
			'failed'    => $failed,
			'total'     => count( $optimized ),
		);
	}

	/**
	 * Execute database migration.
	 *
	 * @since 3.0.2
	 *
	 * @param Migrator $migrator The migrator instance.
	 *
	 * @return array Migration result.
	 */
	private function execute_migration( Migrator $migrator ): array {
		$migrator->run();
		$executed_versions = $migrator->get_ordered_versions();

		/**
		 * Action fired after running migrations via REST API.
		 *
		 * @since 3.0.2
		 *
		 * @param array $executed_versions Executed migration versions.
		 */
		do_action( 'dokan_kits_migrations_executed', $executed_versions );

		return array(
			'versions'  => $executed_versions,
			'total'     => count( $executed_versions ),
			'timestamp' => current_time( 'mysql' ),
		);
	}

	/**
	 * Prepare migration status data.
	 *
	 * @since 3.0.2
	 *
	 * @return array Migration status data.
	 */
	private function prepare_migration_status(): array {
		$migrator = dokan_kits_get_container()->get( Migrator::class );

		$settings_store    = dokan_kits_get_container()->get( SettingsDataStore::class );
		$migration_history = $settings_store->get_settings_by_name( 'migration_history' );
		$history           = $migration_history instanceof Settings ? $migration_history->get_value() : array();

		return array(
			'is_running'           => $migrator->is_migration_running(),
			'needs_migration'      => $migrator->needs_migration(),
			'current_version'      => defined( 'DOKAN_KITS_VERSION' ) ? DOKAN_KITS_VERSION : 'unknown',
			'migration_history'    => is_array( $history ) ? $history : array(),
			'available_migrations' => $migrator->get_ordered_versions(),
			'last_check'           => current_time( 'mysql' ),
		);
	}

	/**
	 * Perform system diagnostics.
	 *
	 * @since 3.0.2
	 *
	 * @return array Diagnostic results.
	 */
	private function perform_system_diagnostics(): array {
		global $wpdb;

		$results = array(
			'wordpress'    => $this->get_wordpress_info(),
			'php'          => $this->get_php_info(),
			'server'       => $this->get_server_info( $wpdb ),
			'dokan_kits'   => $this->get_dokan_kits_info(),
			'dokan'        => $this->get_dokan_info(),
			'woocommerce'  => $this->get_woocommerce_info(),
			'system_check' => $this->get_system_check_info(),
		);

		return apply_filters( 'dokan_kits_diagnostic_results', $results );
	}

	/**
	 * Get WordPress environment info.
	 *
	 * @return array
	 */
	private function get_wordpress_info(): array {
		return array(
			'version'      => get_bloginfo( 'version' ),
			'home_url'     => home_url(),
			'site_url'     => site_url(),
			'is_multisite' => is_multisite(),
			'memory_limit' => WP_MEMORY_LIMIT,
			'debug_mode'   => defined( 'WP_DEBUG' ) && WP_DEBUG,
			'language'     => get_locale(),
		);
	}

	/**
	 * Get PHP environment info.
	 *
	 * @return array
	 */
	private function get_php_info(): array {
		return array(
			'version'             => phpversion(),
			'memory_limit'        => ini_get( 'memory_limit' ),
			'max_execution_time'  => ini_get( 'max_execution_time' ),
			'post_max_size'       => ini_get( 'post_max_size' ),
			'upload_max_filesize' => ini_get( 'upload_max_filesize' ),
			'extensions'          => array(
				'mysqli'   => extension_loaded( 'mysqli' ),
				'curl'     => extension_loaded( 'curl' ),
				'json'     => extension_loaded( 'json' ),
				'gd'       => extension_loaded( 'gd' ),
				'mbstring' => extension_loaded( 'mbstring' ),
			),
		);
	}

	/**
	 * Get server info.
	 *
	 * @param wpdb $wpdb WordPress database object.
	 *
	 * @return array
	 */
	private function get_server_info( $wpdb ): array {
		return array(
			'software'      => isset( $_SERVER['SERVER_SOFTWARE'] ) ? $this->sanitize_text( $_SERVER['SERVER_SOFTWARE'] ) : '',
			'mysql_version' => $wpdb->get_var( 'SELECT VERSION()' ),
		);
	}

	/**
	 * Get Dokan Kits info.
	 *
	 * @return array
	 */
	private function get_dokan_kits_info(): array {
		return array(
			'version'         => defined( 'DOKAN_KITS_VERSION' ) ? DOKAN_KITS_VERSION : 'unknown',
			'database_tables' => $this->check_database_tables(),
		);
	}

	/**
	 * Get Dokan plugin info.
	 *
	 * @return array
	 */
	private function get_dokan_info(): array {
		if ( ! function_exists( 'dokan' ) ) {
			return array(
				'installed' => false,
				'message'   => __( 'Dokan plugin is not installed or active.', 'dokan-kits' ),
			);
		}

		return array(
			'version'     => defined( 'DOKAN_PLUGIN_VERSION' ) ? DOKAN_PLUGIN_VERSION : 'unknown',
			'is_pro'      => defined( 'DOKAN_PRO_PLUGIN_VERSION' ),
			'pro_version' => defined( 'DOKAN_PRO_PLUGIN_VERSION' ) ? DOKAN_PRO_PLUGIN_VERSION : '',
		);
	}

	/**
	 * Get WooCommerce info.
	 *
	 * @return array
	 */
	private function get_woocommerce_info(): array {
		if ( ! dokan_kits_is_woocommerce_active() ) {
			return array(
				'installed' => false,
				'message'   => __( 'WooCommerce is not installed or active.', 'dokan-kits' ),
			);
		}

		return array(
			'version'        => WC()->version,
			'currency'       => get_woocommerce_currency(),
			'products_count' => wp_count_posts( 'product' )->publish,
		);
	}

	/**
	 * Get system check info.
	 *
	 * @return array
	 */
	private function get_system_check_info(): array {
		$system_check = dokan_kits_get_container()->get( SystemCheck::class );
		$pass         = $system_check->check();

		return array(
			'pass'    => $pass,
			'message' => $pass ? __( 'System requirements met.', 'dokan-kits' ) : __( 'System requirements not met.', 'dokan-kits' ),
		);
	}

	/**
	 * Get the list of Dokan Kits database tables.
	 *
	 * @since 3.0.2
	 *
	 * @return array List of table names without prefix.
	 */
	private function get_dokan_kits_tables(): array {
		$tables      = array();
		$data_stores = dokan_kits_get_container()->get( 'data-store-service' );

		foreach ( $data_stores as $data_store ) {
			if ( $data_store instanceof DataStore ) {
				$tables[] = $data_store->get_table_name();
			}
		}

		/**
		 * Filter the list of database tables.
		 *
		 * @since 3.0.2
		 *
		 * @param array $tables List of database tables.
		 */
		return apply_filters( 'dokan_kits_database_tables', array_unique( $tables ) );
	}

	/**
	 * Check database tables.
	 *
	 * @since 3.0.2
	 *
	 * @return array Table check results.
	 */
	private function check_database_tables(): array {
		global $wpdb;

		$tables  = $this->get_dokan_kits_tables();
		$results = array();

		foreach ( $tables as $table ) {
			$table_name = $wpdb->prefix . $table;
			$exists     = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name;

			if ( $exists ) {
				$count             = $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM %i', $table_name ) );
				$results[ $table ] = array(
					'exists'  => true,
					'name'    => $table_name,
					'records' => absint( $count ),
				);
			} else {
				$results[ $table ] = array(
					'exists' => false,
					'name'   => $table_name,
					'error'  => __( 'Table does not exist', 'dokan-kits' ),
				);
			}
		}

		return $results;
	}

	/**
	 * Prepare log files for download.
	 *
	 * @since 3.0.2
	 *
	 * @return array|WP_Error Log file information or error.
	 */
	private function prepare_log_files() {
		$log_dir = WP_CONTENT_DIR . '/debug-logs/';
		$log_url = content_url( '/debug-logs/' );

		// Ensure log directory exists.
		if ( ! file_exists( $log_dir ) && ! wp_mkdir_p( $log_dir ) ) {
			return $this->error(
				__( 'Could not create log directory.', 'dokan-kits' ),
				'log_dir_creation_failed',
				500
			);
		}

		// Add .htaccess file to protect logs if not exists.
		$htaccess_file = $log_dir . '.htaccess';
		if ( ! file_exists( $htaccess_file ) ) {
			$htaccess_content = "Order deny,allow\nDeny from all\n";
			file_put_contents( $htaccess_file, $htaccess_content ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
		}

		// Create a new log file with current date.
		$date      = current_time( 'Y-m-d-H-i-s' );
		$filename  = "dokan-kits-debug-{$date}.log";
		$file_path = wp_normalize_path( $log_dir . $filename );
		$file_url  = $log_url . $filename;

		// Gather log data.
		$log_data = $this->collect_debug_info();

		// Write to file.
		if ( false === file_put_contents( $file_path, $log_data ) ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
			return $this->error(
				__( 'Could not write to log file.', 'dokan-kits' ),
				'log_write_failed',
				500
			);
		}

		return array(
			'file_name' => $filename,
			'file_url'  => $file_url,
			'file_path' => $file_path,
			'file_size' => size_format( filesize( $file_path ) ),
			'created'   => $date,
			'timestamp' => current_time( 'mysql' ),
		);
	}

	/**
	 * Collect debug information for logs.
	 *
	 * @since 3.0.2
	 *
	 * @return string Log data as formatted string.
	 */
	private function collect_debug_info(): string {
		$diagnostics = $this->perform_system_diagnostics();

		$sections = array(
			'WordPress Environment' => $diagnostics['wordpress'],
			'PHP Environment'       => $diagnostics['php'],
			'Server Environment'    => $diagnostics['server'],
			'Dokan Kits'            => $diagnostics['dokan_kits'],
		);

		if ( isset( $diagnostics['dokan'] ) ) {
			$sections['Dokan Plugin'] = $diagnostics['dokan'];
		}
		if ( isset( $diagnostics['woocommerce'] ) ) {
			$sections['WooCommerce'] = $diagnostics['woocommerce'];
		}

		$log_data  = $this->build_log_header();
		$log_data .= $this->build_log_sections( $sections );
		$log_data .= $this->build_active_plugins_section();
		$log_data .= $this->build_log_footer();

		return apply_filters( 'dokan_kits_debug_log_data', $log_data, $diagnostics );
	}

	/**
	 * Build log header.
	 *
	 * @return string
	 */
	private function build_log_header(): string {
		return "Dokan Kits Debug Log\n" . str_repeat( '=', 50 ) . "\n" .
				'Generated: ' . current_time( 'mysql' ) . "\n" .
				'Plugin Version: ' . ( defined( 'DOKAN_KITS_VERSION' ) ? DOKAN_KITS_VERSION : 'unknown' ) . "\n\n";
	}

	/**
	 * Build log sections.
	 *
	 * @param array $sections Sections data.
	 *
	 * @return string
	 */
	private function build_log_sections( array $sections ): string {
		$log_data = '';
		foreach ( $sections as $title => $data ) {
			$log_data .= "=== {$title} ===\n";
			$log_data .= $this->format_section_data( $data );
			$log_data .= "\n";
		}
		return $log_data;
	}

	/**
	 * Format section data.
	 *
	 * @param array $data Section data.
	 *
	 * @return string
	 */
	private function format_section_data( array $data ): string {
		$formatted = '';
		foreach ( $data as $key => $value ) {
			if ( 'extensions' === $key ) {
				$formatted .= "Extensions:\n";
				foreach ( $value as $ext => $loaded ) {
					$formatted .= "  {$ext}: " . ( $loaded ? 'Loaded' : 'Not Loaded' ) . "\n";
				}
			} elseif ( 'database_tables' === $key ) {
				$formatted .= "Database Tables:\n";
				foreach ( $value as $table => $info ) {
					$status     = $info['exists'] ? "Exists ({$info['records']} records)" : 'Missing';
					$formatted .= "  {$table}: {$status}\n";
				}
			} elseif ( is_bool( $value ) ) {
				$formatted .= ucfirst( str_replace( '_', ' ', $key ) ) . ': ' . ( $value ? 'Yes' : 'No' ) . "\n";
			} elseif ( isset( $value['installed'] ) && ! $value['installed'] ) {
				$formatted .= "Status: Not installed\n";
			} elseif ( is_array( $value ) ) {
				foreach ( $value as $sub_key => $sub_value ) {
					$formatted .= ucfirst( str_replace( '_', ' ', $sub_key ) ) . ': ' . $sub_value . "\n";
				}
			} else {
				$formatted .= ucfirst( str_replace( '_', ' ', $key ) ) . ': ' . $value . "\n";
			}
		}
		return $formatted;
	}

	/**
	 * Build active plugins section.
	 *
	 * @return string
	 */
	private function build_active_plugins_section(): string {
		$log_data       = "=== Active Plugins ===\n";
		$active_plugins = (array) get_option( 'active_plugins', array() );
		if ( is_multisite() ) {
			$network_active_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
			$active_plugins         = array_merge( $active_plugins, $network_active_plugins );
		}

		foreach ( $active_plugins as $plugin ) {
			if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin ) ) {
				$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
				if ( ! empty( $plugin_data['Name'] ) ) {
					$log_data .= "{$plugin_data['Name']} ({$plugin_data['Version']})\n";
				}
			}
		}
		return $log_data . "\n";
	}

	/**
	 * Build log footer.
	 *
	 * @return string
	 */
	private function build_log_footer(): string {
		return str_repeat( '=', 50 ) . "\nEnd of Debug Log\n";
	}

	/**
	 * Get database operation schema.
	 *
	 * @since 3.0.2
	 *
	 * @return array Database operation schema.
	 */
	public function get_database_operation_schema(): array {
		$schema = array(
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
			'title'      => 'dokan_kits_database_operation',
			'type'       => 'object',
			'properties' => array_merge(
				$this->get_standard_response_schema(),
				array(
					'data' => array(
						'description' => __( 'Database operation result.', 'dokan-kits' ),
						'type'        => 'object',
						'properties'  => array(
							'tables' => array(
								'description' => __( 'List of successfully processed tables.', 'dokan-kits' ),
								'type'        => 'array',
								'items'       => array( 'type' => 'string' ),
							),
							'failed' => array(
								'description'          => __( 'Failed operations by table name.', 'dokan-kits' ),
								'type'                 => array( 'object', 'array' ),
								'additionalProperties' => array( 'type' => 'string' ),
							),
							'total'  => array(
								'description' => __( 'Total number of successfully processed tables.', 'dokan-kits' ),
								'type'        => 'integer',
								'minimum'     => 0,
							),
						),
					),
				)
			),
		);

		/**
		 * Filter database operation endpoint schema.
		 *
		 * @since 3.0.0
		 *
		 * @param array $schema Database operation schema.
		 */
		return apply_filters( 'dokan_kits_rest_database_operation_schema', $schema );
	}

	/**
	 * Get migration operation schema.
	 *
	 * @since 3.0.2
	 *
	 * @return array Migration operation schema.
	 */
	public function get_migration_operation_schema(): array {
		$schema = array(
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
			'title'      => 'dokan_kits_migration_operation',
			'type'       => 'object',
			'properties' => array_merge(
				$this->get_standard_response_schema(),
				array(
					'data' => array(
						'description' => __( 'Migration operation result.', 'dokan-kits' ),
						'type'        => 'object',
						'properties'  => array(
							'versions'  => array(
								'description' => __( 'List of executed migration versions.', 'dokan-kits' ),
								'type'        => 'array',
								'items'       => array( 'type' => 'string' ),
							),
							'total'     => array(
								'description' => __( 'Total number of executed migrations.', 'dokan-kits' ),
								'type'        => 'integer',
								'minimum'     => 0,
							),
							'timestamp' => array(
								'description' => __( 'Migration execution timestamp.', 'dokan-kits' ),
								'type'        => 'string',
								'format'      => 'date-time',
							),
						),
					),
				)
			),
		);

		/**
		 * Filter migration operation endpoint schema.
		 *
		 * @since 3.0.0
		 *
		 * @param array $schema Migration operation schema.
		 */
		return apply_filters( 'dokan_kits_rest_migration_operation_schema', $schema );
	}

	/**
	 * Get migration status schema.
	 *
	 * @since 3.0.2
	 *
	 * @return array Migration status schema.
	 */
	public function get_migration_status_schema(): array {
		$schema = array(
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
			'title'      => 'dokan_kits_migration_status',
			'type'       => 'object',
			'properties' => array_merge(
				$this->get_standard_response_schema(),
				array(
					'data' => array(
						'description' => __( 'Migration status information.', 'dokan-kits' ),
						'type'        => 'object',
						'properties'  => array(
							'is_running'           => array(
								'description' => __( 'Whether migration is currently running.', 'dokan-kits' ),
								'type'        => 'boolean',
							),
							'needs_migration'      => array(
								'description' => __( 'Whether migration is needed.', 'dokan-kits' ),
								'type'        => 'boolean',
							),
							'current_version'      => array(
								'description' => __( 'Current plugin version.', 'dokan-kits' ),
								'type'        => 'string',
							),
							'migration_history'    => array(
								'description' => __( 'Historical migration data.', 'dokan-kits' ),
								'type'        => 'array',
							),
							'available_migrations' => array(
								'description' => __( 'Available migration versions.', 'dokan-kits' ),
								'type'        => 'array',
								'items'       => array( 'type' => 'string' ),
							),
							'last_check'           => array(
								'description' => __( 'Last status check timestamp.', 'dokan-kits' ),
								'type'        => 'string',
								'format'      => 'date-time',
							),
						),
					),
				)
			),
		);

		/**
		 * Filter migration status endpoint schema.
		 *
		 * @since 3.0.0
		 *
		 * @param array $schema Migration status schema.
		 */
		return apply_filters( 'dokan_kits_rest_migration_status_schema', $schema );
	}

	/**
	 * Get diagnostics schema.
	 *
	 * @since 3.0.2
	 *
	 * @return array Diagnostics schema.
	 */
	public function get_diagnostics_schema(): array {
		$schema = array(
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
			'title'      => 'dokan_kits_diagnostics',
			'type'       => 'object',
			'properties' => array_merge(
				$this->get_standard_response_schema(),
				array(
					'data' => array(
						'description' => __( 'System diagnostics information.', 'dokan-kits' ),
						'type'        => 'object',
						'properties'  => array(
							'wordpress'    => array(
								'description' => __( 'WordPress environment information.', 'dokan-kits' ),
								'type'        => 'object',
							),
							'php'          => array(
								'description' => __( 'PHP environment information.', 'dokan-kits' ),
								'type'        => 'object',
							),
							'server'       => array(
								'description' => __( 'Server environment information.', 'dokan-kits' ),
								'type'        => 'object',
							),
							'dokan_kits'   => array(
								'description' => __( 'Dokan Kits specific information.', 'dokan-kits' ),
								'type'        => 'object',
							),
							'dokan'        => array(
								'description' => __( 'Dokan plugin information.', 'dokan-kits' ),
								'type'        => 'object',
							),
							'woocommerce'  => array(
								'description' => __( 'WooCommerce information.', 'dokan-kits' ),
								'type'        => 'object',
							),
							'system_check' => array(
								'description' => __( 'System requirements check result.', 'dokan-kits' ),
								'type'        => 'object',
								'properties'  => array(
									'pass'    => array(
										'description' => __( 'Whether system check passed.', 'dokan-kits' ),
										'type'        => 'boolean',
									),
									'message' => array(
										'description' => __( 'System check message.', 'dokan-kits' ),
										'type'        => 'string',
									),
								),
							),
						),
					),
				)
			),
		);

		/**
		 * Filter diagnostics endpoint schema.
		 *
		 * @since 3.0.0
		 *
		 * @param array $schema Diagnostics schema.
		 */
		return apply_filters( 'dokan_kits_rest_diagnostics_schema', $schema );
	}

	/**
	 * Get logs schema.
	 *
	 * @since 3.0.2
	 *
	 * @return array Logs schema.
	 */
	public function get_logs_schema(): array {
		$schema = array(
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
			'title'      => 'dokan_kits_logs',
			'type'       => 'object',
			'properties' => array_merge(
				$this->get_standard_response_schema(),
				array(
					'data' => array(
						'description' => __( 'Log file information.', 'dokan-kits' ),
						'type'        => 'object',
						'properties'  => array(
							'file_name' => array(
								'description' => __( 'Generated log file name.', 'dokan-kits' ),
								'type'        => 'string',
							),
							'file_url'  => array(
								'description' => __( 'URL to download the log file.', 'dokan-kits' ),
								'type'        => 'string',
								'format'      => 'uri',
							),
							'file_path' => array(
								'description' => __( 'Server path to the log file.', 'dokan-kits' ),
								'type'        => 'string',
							),
							'file_size' => array(
								'description' => __( 'Human-readable file size.', 'dokan-kits' ),
								'type'        => 'string',
							),
							'created'   => array(
								'description' => __( 'File creation date identifier.', 'dokan-kits' ),
								'type'        => 'string',
							),
							'timestamp' => array(
								'description' => __( 'File creation timestamp.', 'dokan-kits' ),
								'type'        => 'string',
								'format'      => 'date-time',
							),
						),
					),
				)
			),
		);

		/**
		 * Filter logs endpoint schema.
		 *
		 * @since 3.0.0
		 *
		 * @param array $schema Logs schema.
		 */
		return apply_filters( 'dokan_kits_rest_logs_schema', $schema );
	}
}
