<?php
/**
 * Database migrations for the public WordPress.org Free package.
 *
 * Migrates only legacy email-verification data required by Free authentication.
 * It does not inspect, create, migrate or mark complete any schema belonging to
 * separately distributed packages, preserving safe downgrade/reinstall behavior.
 */

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

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Intentional one-time CAS migration query.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Migration reads current DB state.
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- WordPress-owned usermeta table identifier.
// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter -- Internal WordPress table identifier.

if (!function_exists('custausu_db_migrations_get')) {
  function custausu_db_migrations_get(): array {
    $value = get_option(custausu_db_option_migrations_key(), []);
    return is_array($value) ? $value : [];
  }
}

if (!function_exists('custausu_db_migrations_set')) {
  function custausu_db_migrations_set(array $data): void {
    update_option(custausu_db_option_migrations_key(), $data, false);
  }
}

if (!function_exists('custausu_db_migration_get')) {
  function custausu_db_migration_get(string $key): array {
    $all = custausu_db_migrations_get();
    $row = $all[$key] ?? [];
    return is_array($row) ? $row : [];
  }
}

if (!function_exists('custausu_db_migration_mark_done')) {
  function custausu_db_migration_mark_done(string $key, array $stats = []): void {
    $all = custausu_db_migrations_get();
    $all[$key] = [
      'done' => true,
      'ran_at' => gmdate('Y-m-d H:i:s'),
      'stats' => $stats,
    ];
    custausu_db_migrations_set($all);
  }
}

if (!function_exists('custausu_db_migration_is_done')) {
  function custausu_db_migration_is_done(string $key): bool {
    $row = custausu_db_migration_get($key);
    return !empty($row['done']);
  }
}

if (!function_exists('custausu_db_migration_email_available')) {
  function custausu_db_migration_email_available(): bool {
    return function_exists('custausu_db_email_verifications_is_ready')
      && custausu_db_email_verifications_is_ready();
  }
}

if (!function_exists('custausu_db_migrate_email_verifications_from_usermeta')) {
    function custausu_db_migrate_email_verifications_from_usermeta(): array {
        global $wpdb;

        $migration_key = 'email_verifications_v1';

        if (custausu_db_migration_is_done($migration_key)) {
            return [
                'done'          => true,
                'skipped'       => true,
                'reason'        => 'already_done',
                'users_found'   => 0,
                'rows_inserted' => 0,
                'skipped_empty' => 0,
                'skipped_done'  => 0,
                'errors'        => 0,
            ];
        }

        $stats = [
            'done'          => false,
            'skipped'       => false,
            'users_found'   => 0,
            'rows_inserted' => 0,
            'skipped_empty' => 0,
            'skipped_done'  => 0,
            'errors'        => 0,
        ];

        if (!function_exists('custausu_db_email_verifications_is_ready') || !custausu_db_email_verifications_is_ready()) {
            return $stats;
        }

        $meta_key = 'email_verification_token';

        $user_ids = $wpdb->get_col(
            $wpdb->prepare(
                "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = %s",
                $meta_key
            )
        );

        if (!is_array($user_ids)) {
            $user_ids = [];
        }

        $user_ids = array_values(array_unique(array_map('intval', $user_ids)));
        $stats['users_found'] = count($user_ids);

        foreach ($user_ids as $user_id) {
            if ($user_id <= 0) continue;

            try {
                $token = (string) get_user_meta($user_id, 'email_verification_token', true);
                $token = trim($token);

                if ($token === '') {
                    $stats['skipped_empty']++;
                    continue;
                }

                $verified = (string) get_user_meta($user_id, 'email_verified', true);
                if ($verified === 'yes') {
                    $stats['skipped_done']++;
                    continue;
                }

                $user = get_userdata($user_id);
                if (!$user || empty($user->user_email)) {
                    $stats['errors']++;
                    continue;
                }

                $expires_ts = (int) get_user_meta($user_id, 'email_verification_expires', true);
                $expires_at = $expires_ts > 0
                    ? custausu_db_email_verifications_ts_to_mysql_utc($expires_ts)
                    : null;

                $ok = custausu_db_email_verifications_create_or_replace_pending(
                    $user_id,
                    (string)$user->user_email,
                    $token,
                    $expires_at,
                    'register_verify',
                    [
                        'migrated_from' => 'usermeta',
                    ]
                );

                if ($ok) {
                    $stats['rows_inserted']++;
                } else {
                    $stats['errors']++;
                }

            } catch (\Throwable $e) {
                $stats['errors']++;

                if (function_exists('custausu_log')) {
                    custausu_log('email', 'CAS email verification migration row failed', [
                        'user_id' => (int)$user_id,
                        'error'   => $e->getMessage(),
                    ], 'error');
                }
            }
        }

        $stats['done'] = true;
        custausu_db_migration_mark_done($migration_key, $stats);

        if (function_exists('custausu_log')) {
            custausu_log('email', 'CAS email verification migration completed', $stats, 'info');
        }

        return $stats;
    }
}

if (!function_exists('custausu_db_run_pending_migrations')) {
  function custausu_db_run_pending_migrations(): void {
    if (custausu_db_migration_email_available()) {
      custausu_db_migrate_email_verifications_from_usermeta();
    }
  }
}

if (!function_exists('custausu_db_maybe_run_pending_migrations')) {
  function custausu_db_maybe_run_pending_migrations(): void {
    static $running = false;
    if ($running) {
      return;
    }
    $running = true;

    try {
      custausu_db_run_pending_migrations();
    } catch (\Throwable $error) {
      if (function_exists('custausu_log')) {
        custausu_log('error', 'CAS pending Free migrations runner failed', [
          'error' => $error->getMessage(),
        ], 'error');
      }
    } finally {
      $running = false;
    }
  }
}

add_action('init', 'custausu_db_maybe_run_pending_migrations', 5);
