<?php
/**
 * Zano Database Migration
 *
 * Handles database schema updates for asset support
 *
 * @package AnyCoin_Payment_Gateway
 */

defined( 'ABSPATH' ) || exit;

/**
 * AnyCoin Database Migration utilities.
 *
 * @package AnyCoin_Payment_Gateway
 */
class AnyCoin_Database_Migration {

	/**
	 * Current database version.
	 *
	 * 1.4.0: Zano HF6 - unique constraint moved from tx_hash to
	 * (tx_hash, payment_id) so one transaction can pay multiple orders.
	 */
	const DB_VERSION = '1.4.0';

	/**
	 * Run database migrations.
	 */
	public static function migrate() {
		// Prefer new option name; fall back to legacy for BC.
		$current_version = get_option( AnyCoin_Constants::DB_VERSION_OPTION, get_option( 'zano_payment_db_version', '1.0.0' ) );

		if ( version_compare( $current_version, self::DB_VERSION, '<' ) ) {
			// Ensure schema is up to date using dbDelta via the database manager.
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange -- Controlled migration using dbDelta during plugin upgrade
			AnyCoin_Database_Manager::run_table_migrations();

			// Ensure unique constraint rules are satisfied.
			AnyCoin_Database_Manager::resolve_duplicate_transactions();

			// Write to new option name and remove legacy option.
			update_option( AnyCoin_Constants::DB_VERSION_OPTION, self::DB_VERSION );
			delete_option( 'zano_payment_db_version' );
		}
	}

	/**
	 * Add asset-specific columns to payments table (delegated).
	 */
	private static function add_asset_columns() {
		AnyCoin_Database_Manager::run_table_migrations();
	}

	/**
	 * Add block tracking columns (delegated).
	 */
	private static function add_block_tracking_columns() {
		AnyCoin_Database_Manager::run_table_migrations();
	}

	/**
	 * Add unique constraint on tx_hash to prevent race conditions (delegated).
	 */
	private static function add_tx_hash_unique_constraint() {
		AnyCoin_Database_Manager::resolve_duplicate_transactions();
	}

	/**
	 * Create the payments table if it doesn't exist.
	 */
	public static function create_payments_table() {
		// Use the database manager create_tables which uses dbDelta.
		AnyCoin_Database_Manager::create_tables();
	}

	/**
	 * Reset and migrate legacy artifacts (options, tables, transients, meta keys, cron).
	 * Intended to be run from the admin debug tools when resetting.
	 */
	public static function reset_and_migrate_legacy() {
		global $wpdb;

		// 1) Drop legacy table if present.
		$legacy_table = $wpdb->prefix . 'zano_payments';
		$table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $legacy_table ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
		if ( $table_exists === $legacy_table ) {
			// Drop legacy table; phpcs:ignore is necessary for identifier.
			$wpdb->query( 'DROP TABLE ' . $legacy_table ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.SchemaChange.SchemaChange
		}

		// 2) Ensure new table exists.
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange -- Controlled dbDelta create during admin-triggered reset
		AnyCoin_Database_Manager::create_tables();

		// 3) Migrate options: copy legacy settings if new missing, then delete legacy.
		$legacy_settings = get_option( 'woocommerce_zano_payment_settings', null );
		if ( is_array( $legacy_settings ) && ! get_option( 'woocommerce_anycoin_payment_settings', null ) ) {
			update_option( 'woocommerce_anycoin_payment_settings', $legacy_settings );
		}
		delete_option( 'woocommerce_zano_payment_settings' );

		// 4) DB version option: set new and delete legacy key.
		update_option( AnyCoin_Constants::DB_VERSION_OPTION, self::DB_VERSION );
		delete_option( 'zano_payment_db_version' );

		// 5) Transients: clear legacy.
		delete_transient( 'zano_last_status_update' );

		// 6) Rename legacy order meta keys to new keys.
		$meta_renames = [
			'_zano_payment_asset_symbol'  => '_anycoin_payment_asset_symbol',
			'_zano_payment_asset_amount'  => '_anycoin_payment_asset_amount',
			'_zano_payment_asset_id'      => '_anycoin_payment_asset_id',
			'_zano_payment_tx_hash'       => '_anycoin_payment_tx_hash',
			'_zano_verification_method'   => '_anycoin_verification_method',
			'_zano_verification_attempts' => '_anycoin_verification_attempts',
			'_zano_selected_asset'        => '_anycoin_selected_asset',
			'_zano_asset_id'              => '_anycoin_asset_id',
			'_zano_asset_amount'          => '_anycoin_asset_amount',
		];
		foreach ( $meta_renames as $old_key => $new_key ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
			$wpdb->query(
				$wpdb->prepare(
					"UPDATE {$wpdb->postmeta} SET meta_key = %s WHERE meta_key = %s",
					$new_key,
					$old_key
				)
			);
		}

		// 7) Unschedule legacy cron hooks (best effort).
		$crons = get_option( 'cron', [] );
		if ( is_array( $crons ) ) {
			foreach ( $crons as $timestamp => $hooks ) {
				if ( ! is_array( $hooks ) ) {
					continue;
				}
				foreach ( $hooks as $hook => $data ) {
					if ( strpos( $hook, 'zano_' ) === 0 ) {
						wp_clear_scheduled_hook( $hook );
					}
				}
			}
		}
	}

	/**
	 * Check if block tracking columns exist.
	 */
	public static function has_block_tracking_columns() {
		// After migrations, assume presence.
		AnyCoin_Database_Manager::run_table_migrations();
		return true;
	}
}

// Run migration on plugin activation.
register_activation_hook( __FILE__, [ 'AnyCoin_Database_Migration', 'create_payments_table' ] );
add_action( 'plugins_loaded', [ 'AnyCoin_Database_Migration', 'migrate' ] );
