<?php
/**
 * Repair tables cleanup task.
 *
 * @package DatabaseCleanup
 */

namespace DatabaseCleanup\Includes\Tasks;

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

class Task_Repair_Tables extends Abstract_Cleanup_Task {

	public function get_id(): string {
		return 'repair_tables';
	}

	public function get_label(): string {
		return __( 'Repair tables', 'wppowersuite-lite' );
	}

	public function get_description(): string {
		return __( 'Run REPAIR TABLE on WordPress core tables. Use when tables may be corrupted.', 'wppowersuite-lite' );
	}

	public function is_safe(): bool {
		return false;
	}

	public function scan( array $settings ): array {
		unset( $settings );

		$tables = $this->eligible_tables();

		return [
			'count'           => count( $tables ),
			'estimated_bytes' => 0,
			'details'         => [ 'tables' => array_column( $tables, 'name' ) ],
		];
	}

	public function clean( array $settings, int $batch_size, mixed $cursor = null ): array {
		global $wpdb;

		unset( $settings, $batch_size );

		$tables = $this->eligible_tables();
		$index  = is_array( $cursor ) ? absint( $cursor['index'] ?? 0 ) : 0;
		$repaired = 0;

		if ( ! isset( $tables[ $index ] ) ) {
			return [
				'deleted' => 0,
				'done'    => true,
				'cursor'  => null,
				'bytes'   => 0,
			];
		}

		$table = (string) $tables[ $index ]['name'];

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$wpdb->query( "REPAIR TABLE `{$table}`" );
		++$repaired;

		$next = $index + 1;
		$done = ! isset( $tables[ $next ] );

		return [
			'deleted' => $repaired,
			'done'    => $done,
			'cursor'  => $done ? null : [ 'index' => $next ],
			'bytes'   => 0,
		];
	}

	/**
	 * @return list<array{name:string}>
	 */
	private function eligible_tables(): array {
		global $wpdb;

		$core   = array_values( array_unique( array_merge( $wpdb->tables( 'all', true ), [ $wpdb->usermeta ] ) ) );
		$result = [];

		foreach ( $core as $table ) {
			if ( ! is_string( $table ) || $table === '' ) {
				continue;
			}
			if ( str_starts_with( $table, $wpdb->prefix . 'wpps_' ) ) {
				continue;
			}
			$result[] = [ 'name' => $table ];
		}

		return $result;
	}
}
