<?php
/**
 * System health and diagnostics for DataStream.
 *
 * @package DataStream
 */

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

/**
 * Class DataStream_Health
 */
class DataStream_Health {

	/**
	 * Run a full diagnostic report.
	 *
	 * @return array<string, mixed>
	 */
	public static function get_report() {
		global $wpdb;

		$dao         = new DataStream_DAO();
		$table       = $wpdb->prefix . DATASTREAM_TABLE;
		$table_like  = $wpdb->esc_like( $table );
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- SHOW TABLES for our own table; not a post query.
		$table_found = $wpdb->get_var(
			$wpdb->prepare( 'SHOW TABLES LIKE %s', $table_like )
		);
		$next_sync   = wp_next_scheduled( DATASTREAM_CRON_HOOK );
		$api_url     = (string) DataStream_Config::get( 'api_url' );
		$issues      = array();
		$warnings    = array();

		if ( $table !== $table_found ) {
			$issues[] = __( 'Ingestion table is missing. Deactivate and reactivate the plugin to repair.', 'datastream-api-sync' );
		}

		if ( DataStream_Config::get( 'cron_enabled' ) && ! $next_sync ) {
			$warnings[] = __( 'Cron is enabled but no sync event is scheduled.', 'datastream-api-sync' );
		}

		if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
			$warnings[] = __( 'WP-Cron is disabled. Ensure a system cron calls wp-cron.php.', 'datastream-api-sync' );
		}

		if ( '' === $api_url ) {
			$warnings[] = __( 'API URL is empty. Scheduled syncs will skip remote fetch.', 'datastream-api-sync' );
		}

		if ( DataStream_Sync_Lock::is_locked() ) {
			$warnings[] = __( 'A sync lock is active. Another ingestion may be running.', 'datastream-api-sync' );
		}

		$backoff_until = (int) DataStream_Config::get( 'backoff_until' );

		if ( $backoff_until > time() ) {
			$warnings[] = sprintf(
				/* translators: 1: number of consecutive failures, 2: UTC datetime */
				__( 'Scheduled syncs are paused after %1$d consecutive failures. Next retry: %2$s UTC. Run a manual sync to retry immediately.', 'datastream-api-sync' ),
				absint( DataStream_Config::get( 'failure_count' ) ),
				gmdate( 'Y-m-d H:i:s', $backoff_until )
			);
		}

		if ( ! function_exists( 'curl_init' ) && ! ini_get( 'allow_url_fopen' ) ) {
			$issues[] = __( 'Neither cURL nor allow_url_fopen is available for HTTP requests.', 'datastream-api-sync' );
		}

		return array(
			'healthy'          => empty( $issues ),
			'issues'           => $issues,
			'warnings'         => $warnings,
			'table_exists'     => ( $table === $table_found ),
			'record_count'     => $dao->get_record_count(),
			'stream_counts'    => $dao->get_stream_counts(),
			'cron_enabled'     => (bool) DataStream_Config::get( 'cron_enabled' ),
			'cron_scheduled'   => (bool) $next_sync,
			'next_sync'        => $next_sync ? gmdate( 'Y-m-d H:i:s', $next_sync ) : '',
			'next_sync_unix'   => $next_sync ? intval( $next_sync ) : 0,
			'cron_schedule'    => (string) DataStream_Config::get( 'cron_schedule' ),
			'wp_cron_disabled' => defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON,
			'sync_locked'      => DataStream_Sync_Lock::is_locked(),
			'last_sync'        => (string) DataStream_Config::get( 'last_sync' ),
			'last_sync_result' => get_option( 'datastream_last_sync_result', array() ),
			'sync_history'     => get_option( 'datastream_sync_history', array() ),
			'php_version'      => PHP_VERSION,
			'wp_version'       => get_bloginfo( 'version' ),
			'plugin_version'   => DATASTREAM_VERSION,
			'db_version'       => get_option( 'datastream_db_version', '0' ),
		);
	}

	/**
	 * Repair cron schedule if missing.
	 *
	 * @return bool
	 */
	public static function repair_cron() {
		if ( ! DataStream_Config::get( 'cron_enabled' ) ) {
			DataStream_Engine::unschedule_sync();
			return true;
		}

		DataStream_Engine::reschedule_sync( (string) DataStream_Config::get( 'cron_schedule' ) );
		return (bool) wp_next_scheduled( DATASTREAM_CRON_HOOK );
	}

	/**
	 * Repair database schema.
	 */
	public static function repair_schema() {
		DataStream_Schema::create_schema();
		update_option( 'datastream_db_version', DATASTREAM_VERSION, false );
	}

	/**
	 * Verify cron on admin bootstrap.
	 */
	public static function maybe_repair_cron() {
		if ( ! DataStream_Config::get( 'cron_enabled' ) ) {
			return;
		}

		if ( ! wp_next_scheduled( DATASTREAM_CRON_HOOK ) ) {
			DataStream_Engine::schedule_sync();
			DataStream_Logger::info( 'Missing cron event auto-repaired.' );
		}
	}
}
