<?php
if (!defined('WP_UNINSTALL_PLUGIN')) {
    exit;
}

require_once __DIR__ . '/app/Core/Access.php';
require_once __DIR__ . '/app/Core/SettingsPage.php';
require_once __DIR__ . '/app/Modules/Notifications/module.php';

$plugin_caps = \BLR\Backline\Core\Access::all_plugin_caps();
$admin_role = get_role('administrator');
if ($admin_role) {
    foreach ($plugin_caps as $cap) {
        $admin_role->remove_cap($cap);
    }
}

if (!\BLR\Backline\Core\SettingsPage::remove_data_on_uninstall()) {
    return;
}

/**
 * Delete attachments in batches using a constrained query callback.
 *
 * @param callable():array<int,int|string> $query_ids
 */
function blr_ba_delete_attachment_batch(callable $query_ids): void {
    do {
        $attachment_ids = array_values(array_unique(array_map('intval', (array) $query_ids())));
        foreach ($attachment_ids as $attachment_id) {
            if ($attachment_id > 0) {
                wp_delete_attachment($attachment_id, true);
            }
        }
    } while (!empty($attachment_ids));
}

/**
 * Delete plugin posts in batches and remove child attachments for each batch first.
 *
 * @param array<int,string> $post_types
 */
function blr_ba_delete_plugin_posts(array $post_types): void {
    $previous_ids_signature = '';
    $max_iterations = 10000;
    $iteration = 0;

    do {
        $iteration++;
        if ($iteration > $max_iterations) {
            break;
        }

        $post_ids = array_values(array_unique(array_map('intval', (array) get_posts([
            'post_type' => $post_types,
            'post_status' => 'any',
            'posts_per_page' => 100,
            'orderby' => 'ID',
            'order' => 'ASC',
            'fields' => 'ids',
            'no_found_rows' => true,
        ]))));

        if (empty($post_ids)) {
            break;
        }

        $signature = implode(',', $post_ids);
        if ($signature === $previous_ids_signature) {
            break;
        }
        $previous_ids_signature = $signature;

        blr_ba_delete_attachment_batch(static function () use ($post_ids): array {
            return array_map('intval', (array) get_posts([
                'post_type' => 'attachment',
                'post_status' => 'any',
                'posts_per_page' => 100,
                'post_parent__in' => $post_ids,
                'orderby' => 'ID',
                'order' => 'ASC',
                'fields' => 'ids',
                'no_found_rows' => true,
            ]));
        });

        foreach ($post_ids as $post_id) {
            if ($post_id > 0) {
                wp_delete_post($post_id, true);
            }
        }
    } while (true);
}

$post_types = [
    'blr_contact',
    'blr_release',
    'blr_track',
    'blr_event',
    'blr_outreach',
    'blr_outreach_log',
    'blr_task',
    'blr_finance_record',
];

blr_ba_delete_plugin_posts($post_types);

blr_ba_delete_attachment_batch(static function (): array {
    return array_map('intval', (array) get_posts([
        'post_type' => 'attachment',
        'post_status' => 'any',
        'posts_per_page' => 100,
        'orderby' => 'ID',
        'order' => 'ASC',
        'fields' => 'ids',
        'no_found_rows' => true,
        'meta_query' => [
            'relation' => 'OR',
            [
                'key' => '_blr_ba_managed_attachment',
                'value' => '1',
            ],
            [
                'key' => '_blr_ba_owner_context',
                'compare' => 'EXISTS',
            ],
        ],
    ]));
});

$options = [
    \BLR\Backline\Core\SettingsPage::OPT_DASHBOARD_SLUG,
    \BLR\Backline\Core\SettingsPage::OPT_ALLOWED_USERS,
    \BLR\Backline\Core\SettingsPage::OPT_DEFAULT_FROM_NAME,
    \BLR\Backline\Core\SettingsPage::OPT_DEFAULT_FROM_EMAIL,
    \BLR\Backline\Core\SettingsPage::OPT_DEFAULT_REPLY_TO,
    \BLR\Backline\Core\SettingsPage::OPT_THEME_PRIMARY,
    \BLR\Backline\Core\SettingsPage::OPT_REMOVE_DATA_ON_UNINSTALL,
    \BLR\Backline\Core\SettingsPage::OPT_PLUGIN_VERSION,
    \BLR\Backline\Core\SettingsPage::OPT_REWRITE_FLUSH_REQUIRED,
    \BLR\Backline\Core\SettingsPage::OPT_SIDEBAR_LOGO_ID,
    \BLR\Backline\Core\SettingsPage::OPT_ENABLED_MODULES,
    \BLR\Backline\Core\SettingsPage::OPT_OPERATOR_CAPS,
    \BLR\Backline\Core\SettingsPage::OPT_USER_MODULE_ACCESS,
    \BLR\Backline\Core\SettingsPage::OPT_USER_EXTRA_CAPS,
    'blr_ba_mailer_mode',
    'blr_ba_smtp_host',
    'blr_ba_smtp_port',
    'blr_ba_smtp_encryption',
    'blr_ba_smtp_username',
    'blr_ba_smtp_password',
    'blr_ba_smtp_auth',
    'blr_ba_smtp_from_name',
    'blr_ba_smtp_from_email',
    'blr_ba_smtp_reply_to',
    'blr_ba_seeded_release_types',
    'blr_ba_seeded_release_statuses',
    'blr_ba_migrated_release_types',
    'blr_ba_migrated_release_types_page',
];

foreach ($options as $option_name) {
    delete_option($option_name);
}

global $wpdb;
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- One-time uninstall cleanup for transient-style lock options.
$lock_options = $wpdb->get_col("SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE 'blr_ba_outreach_lock_%'");
foreach ($lock_options as $option_name) {
    delete_option((string) $option_name);
}

$transient_option_prefixes = [
    '_transient_blr_ba_calendar_events_',
    '_transient_timeout_blr_ba_calendar_events_',
    '_transient_blr_ba_contact_import_errors_',
    '_transient_timeout_blr_ba_contact_import_errors_',
    '_transient_blr_ba_contact_meta_options_',
    '_transient_timeout_blr_ba_contact_meta_options_',
    '_transient_blr_ba_outreach_runner_recent',
    '_transient_timeout_blr_ba_outreach_runner_recent',
    '_transient_blr_ba_outreach_stats_',
    '_transient_timeout_blr_ba_outreach_stats_',
    '_transient_blr_ba_signup_rl_',
    '_transient_timeout_blr_ba_signup_rl_',
    '_transient_blr_ba_signup_cd_',
    '_transient_timeout_blr_ba_signup_cd_',
];

foreach ($transient_option_prefixes as $option_prefix) {
    $like = $wpdb->esc_like($option_prefix) . '%';
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- One-time uninstall cleanup for plugin transients.
    $matching_options = $wpdb->get_col($wpdb->prepare("SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", $like));
    foreach ((array) $matching_options as $option_name) {
        delete_option((string) $option_name);
    }
}

$table_name = (string) \BLR\Backline\Modules\Notifications\Module::table_name();
$table_name = preg_replace('/[^A-Za-z0-9_]/', '', $table_name);
$expected_prefix = preg_replace('/[^A-Za-z0-9_]/', '', (string) $wpdb->prefix);
if (is_string($table_name) && $table_name !== '' && $expected_prefix !== '' && str_starts_with($table_name, $expected_prefix)) {
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange -- One-time uninstall cleanup for plugin-owned notifications table.
    $wpdb->query($wpdb->prepare('DROP TABLE IF EXISTS %i', $table_name));
}

$user_ids = get_users([
    'fields' => 'ID',
]);

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

    $avatar_id = absint(get_user_meta($user_id, 'blr_ba_avatar_id', true));
    if ($avatar_id > 0) {
        wp_delete_attachment($avatar_id, true);
    }

    delete_user_meta($user_id, 'blr_ba_avatar_id');
    delete_user_meta($user_id, \BLR\Backline\Core\SettingsPage::USER_META_THEME_MODE);
}

wp_cache_flush();
wp_clear_scheduled_hook('blr_ba_process_outreach_campaign');
wp_clear_scheduled_hook('blr_ba_outreach_queue_healthcheck');
