<?php
/**
 * Uninstall handler for WP SEO Next.
 *
 * NOTE:
 * - We delete plugin-owned options/site options and drop plugin-owned custom tables.
 * - We do NOT delete postmeta/termmeta by default (SEO overrides + suggestions),
 *   because that could surprise users. Add your own cleanup command if desired.
 */

defined('WP_UNINSTALL_PLUGIN') || exit;

global $wpdb;

if (!isset($wpdb) || !($wpdb instanceof \wpdb)) {
    return;
}

/**
 * Delete option rows for the current site/blog using plugin-owned prefixes.
 */
function wpsn_uninstall_delete_current_site_options(\wpdb $wpdb): void
{
    $patterns = [
        'wpsn\\_%',
        '\\_transient\\_wpsn\\_%',
        '\\_transient\\_timeout\\_wpsn\\_%',
    ];

    foreach ($patterns as $pattern) {
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table name is provided by core.
        $wpdb->query(
            $wpdb->prepare(
                "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s ESCAPE '\\\\'",
                $pattern
            )
        );
    }
}

/**
 * Drop all custom tables owned by the plugin for the current site/blog.
 */
function wpsn_uninstall_drop_current_site_tables(\wpdb $wpdb): void
{
    $pattern = $wpdb->esc_like($wpdb->prefix . 'wpsn_') . '%';
    $tables = $wpdb->get_col($wpdb->prepare('SHOW TABLES LIKE %s', $pattern));
    if (!is_array($tables) || empty($tables)) {
        return;
    }

    foreach ($tables as $table) {
        if (!is_string($table) || $table === '') {
            continue;
        }

        $table = preg_replace('/[^A-Za-z0-9_\\$]/', '', $table);
        if (!is_string($table) || $table === '') {
            continue;
        }

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- sanitized identifier.
        $wpdb->query("DROP TABLE IF EXISTS `{$table}`");
    }
}

/**
 * Remove per-site plugin data.
 */
function wpsn_uninstall_current_site(\wpdb $wpdb): void
{
    wpsn_uninstall_delete_current_site_options($wpdb);
    wpsn_uninstall_drop_current_site_tables($wpdb);

    if (function_exists('remove_role')) {
        remove_role('wpsn_seo_manager');
    }
}

/**
 * Remove network-wide plugin data.
 */
function wpsn_uninstall_network_data(\wpdb $wpdb): void
{
    if (!function_exists('is_multisite') || !is_multisite()) {
        return;
    }

    if (isset($wpdb->sitemeta) && is_string($wpdb->sitemeta) && $wpdb->sitemeta !== '') {
        $patterns = [
            'wpsn\\_%',
            '\\_site\\_transient\\_wpsn\\_%',
            '\\_site\\_transient\\_timeout\\_wpsn\\_%',
        ];

        foreach ($patterns as $pattern) {
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table name is provided by core.
            $wpdb->query(
                $wpdb->prepare(
                    "DELETE FROM {$wpdb->sitemeta} WHERE meta_key LIKE %s ESCAPE '\\\\'",
                    $pattern
                )
            );
        }
    }

    delete_site_option('wpsn_network_settings');
}

if (function_exists('is_multisite') && is_multisite() && function_exists('get_sites') && function_exists('switch_to_blog') && function_exists('restore_current_blog')) {
    $siteIds = get_sites([
        'fields' => 'ids',
        'number' => 0,
    ]);

    if (is_array($siteIds)) {
        foreach ($siteIds as $siteId) {
            $siteId = (int) $siteId;
            if ($siteId <= 0) {
                continue;
            }

            switch_to_blog($siteId);
            wpsn_uninstall_current_site($wpdb);
            restore_current_blog();
        }
    } else {
        wpsn_uninstall_current_site($wpdb);
    }

    wpsn_uninstall_network_data($wpdb);
} else {
    wpsn_uninstall_current_site($wpdb);
}
