<?php

declare( strict_types=1 );

namespace StrykeWP\Core;

use StrykeWP\Modules\Connector\ApiLogger;
use StrykeWP\Modules\Backup\BackupSettings;

/**
 * Centralises creation and removal of all STRYKE WP custom DB tables.
 *
 * create_all() is idempotent — it uses dbDelta() internally and is safe to
 * call on every plugin activation as well as from each module's on_enable().
 *
 * drop_all() is destructive and called ONLY from uninstall.php.
 *
 * @package StrykeWP\Core
 */
final class SchemaManager {

	// -----------------------------------------------------------------------
	// Create
	// -----------------------------------------------------------------------

	/**
	 * Creates (or upgrades) all custom database tables.
	 *
	 * Delegates to each module's own create_table() method which uses dbDelta(),
	 * so this is safe to call multiple times without duplicating data.
	 *
	 * @return void
	 */
	public static function create_all(): void {
		ApiLogger::create_table();
		BackupSettings::create_table();
	}

	// -----------------------------------------------------------------------
	// Drop
	// -----------------------------------------------------------------------

	/**
	 * Drops all custom DB tables.
	 *
	 * DESTRUCTIVE — called ONLY from uninstall.php after the user explicitly
	 * deletes the plugin via WordPress admin.
	 *
	 * @return void
	 */
	public static function drop_all(): void {
		global $wpdb;

		$tables = [
			ApiLogger::get_table_name(),
			BackupSettings::get_table_name(),
		];

		foreach ( $tables as $table ) {
			if ( ! preg_match( '/^[a-z0-9_]+$/i', $table ) ) {
				continue;
			}
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			$wpdb->query( "DROP TABLE IF EXISTS `{$table}`" );
		}
	}

	// -----------------------------------------------------------------------
	// Version Check
	// -----------------------------------------------------------------------

	/**
	 * Runs schema upgrades when the plugin version has changed.
	 *
	 * Safe to call on every boot (compares stored vs running version first).
	 * Extend this method in future versions to add new columns / tables.
	 *
	 * @param OptionManager $options Shared option manager.
	 * @return void
	 */
	public static function maybe_upgrade( OptionManager $options ): void {
		$installed = $options->get( 'version' );

		if ( $installed === STRYKE_WP_VERSION ) {
			return;
		}

		// Re-run table creation on version change (dbDelta handles ALTER safely).
		self::create_all();

		$options->set( 'version', STRYKE_WP_VERSION );
	}
}
