<?php
/**
 * Uninstall cleanup for Calliope Social Publisher.
 *
 * The plugin preserves data by default. Cleanup only runs when the site owner
 * enables the uninstall setting or defines CALLIOPE_SP_CLEANUP_ON_DELETE.
 * All cleanup steps are defensive so plugin deletion is never blocked by a
 * stale option, transient, upload directory, or host filesystem restriction.
 *
 * @package Calliope_Social_Publisher
 */

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

if (!function_exists('calliope_sp_uninstall_should_cleanup')) {
    /**
     * Decide whether plugin-owned data should be removed on uninstall.
     *
     * @return bool
     */
    function calliope_sp_uninstall_should_cleanup() {
        $enabled = (bool) get_option('calliope_sp_cleanup_on_delete', false);

        if (defined('CALLIOPE_SP_CLEANUP_ON_DELETE')) {
            $enabled = (bool) CALLIOPE_SP_CLEANUP_ON_DELETE;
        }

        /**
         * Filter whether Calliope Social Publisher should remove its data on uninstall.
         *
         * @param bool $enabled Current cleanup decision.
         */
        return (bool) apply_filters('calliope_sp_cleanup_on_delete', $enabled);
    }
}

// Preserve user data by default. WordPress can still delete the plugin files.
if (!calliope_sp_uninstall_should_cleanup()) {
    return;
}

if (!function_exists('calliope_sp_uninstall_delete_options')) {
    /**
     * Delete a list of site and network options safely.
     *
     * @param string[] $option_names Option names.
     * @return void
     */
    function calliope_sp_uninstall_delete_options(array $option_names) {
        foreach ($option_names as $option_name) {
            $option_name = sanitize_key($option_name);
            if ($option_name === '') {
                continue;
            }

            delete_option($option_name);
            delete_site_option($option_name);
        }
    }
}

if (!function_exists('calliope_sp_uninstall_delete_transient_patterns')) {
    /**
     * Delete known transient keys without using wildcard direct database queries.
     *
     * WordPress does not expose a safe wildcard transient deletion API. During
     * uninstall, avoid custom SQL so Plugin Check does not report unescaped
     * table or column identifiers. OAuth state transients that include random
     * suffixes can expire naturally.
     *
     * @param string[] $patterns Transient keys or legacy wildcard patterns.
     * @return void
     */
    function calliope_sp_uninstall_delete_transient_patterns(array $patterns) {
        foreach ($patterns as $pattern) {
            $transient_name = str_replace('%', '', (string) $pattern);
            $transient_name = sanitize_key($transient_name);

            if ($transient_name === '') {
                continue;
            }

            delete_transient($transient_name);
            delete_site_transient($transient_name);
        }
    }
}

if (!function_exists('calliope_sp_uninstall_get_filesystem')) {
    /**
     * Get an initialized WordPress filesystem instance for uninstall cleanup.
     *
     * @return WP_Filesystem_Base|null
     */
    function calliope_sp_uninstall_get_filesystem() {
        global $wp_filesystem;

        if (!function_exists('WP_Filesystem')) {
            require_once ABSPATH . 'wp-admin/includes/file.php';
        }

        if (!WP_Filesystem()) {
            return null;
        }

        return $wp_filesystem;
    }
}

if (!function_exists('calliope_sp_uninstall_delete_upload_dir')) {
    /**
     * Recursively remove a plugin-owned directory under uploads.
     *
     * @param string $dir Directory path.
     * @return void
     */
    function calliope_sp_uninstall_delete_upload_dir($dir) {
        $dir = wp_normalize_path((string) $dir);
        if ($dir === '') {
            return;
        }

        $filesystem = calliope_sp_uninstall_get_filesystem();
        if (!$filesystem || !$filesystem->is_dir($dir)) {
            return;
        }

        $filesystem->delete($dir, true);
    }
}

$calliope_sp_option_names = [
    'calliope_sp_cleanup_on_delete',
    'calliope_sp_connection_backup',
    'calliope_sp_blogger_access_token',
    'calliope_sp_blogger_blog_id',
    'calliope_sp_blogger_blogs_last',
    'calliope_sp_blogger_client_id',
    'calliope_sp_blogger_client_secret',
    'calliope_sp_blogger_connection_status',
    'calliope_sp_blogger_expires_at',
    'calliope_sp_blogger_refresh_token',
    'calliope_sp_bsky_connection_status',
    'calliope_sp_bsky_handle',
    'calliope_sp_bsky_password',
    'calliope_sp_debug_logs',
    'calliope_sp_fb_app_id',
    'calliope_sp_fb_app_secret',
    'calliope_sp_fb_business_id',
    'calliope_sp_fb_businesses_last',
    'calliope_sp_fb_config_id',
    'calliope_sp_fb_connection_status',
    'calliope_sp_fb_expires_at',
    'calliope_sp_fb_last_oauth_debug',
    'calliope_sp_fb_page_access_token',
    'calliope_sp_fb_page_id',
    'calliope_sp_fb_pages_last',
    'calliope_sp_fb_user_access_token',
    'calliope_sp_flipboard_enable_share_button',
    'calliope_sp_flipboard_feed_url',
    'calliope_sp_ig_access_token',
    'calliope_sp_ig_app_id',
    'calliope_sp_ig_app_secret',
    'calliope_sp_ig_connection_status',
    'calliope_sp_ig_expires_at',
    'calliope_sp_ig_page_id',
    'calliope_sp_ig_user_id',
    'calliope_sp_ig_username',
    'calliope_sp_li_access_token',
    'calliope_sp_li_client_id',
    'calliope_sp_li_client_secret',
    'calliope_sp_li_connection_status',
    'calliope_sp_li_expires_at',
    'calliope_sp_li_last_page_target',
    'calliope_sp_li_last_scope_list',
    'calliope_sp_li_last_target_kind',
    'calliope_sp_li_person_id',
    'calliope_sp_mstdn_client_id',
    'calliope_sp_mstdn_client_instance',
    'calliope_sp_mstdn_client_secret',
    'calliope_sp_mstdn_connection_status',
    'calliope_sp_mstdn_instance',
    'calliope_sp_mstdn_token',
    'calliope_sp_pinterest_app_id',
    'calliope_sp_pinterest_app_secret',
    'calliope_sp_pinterest_board_id',
    'calliope_sp_pinterest_boards_last',
    'calliope_sp_pinterest_connection_status',
    'calliope_sp_pinterest_env',
    'calliope_sp_pinterest_refresh_token',
    'calliope_sp_pinterest_token',
    'calliope_sp_threads_access_token',
    'calliope_sp_threads_client_id',
    'calliope_sp_threads_client_secret',
    'calliope_sp_threads_connection_status',
    'calliope_sp_threads_expires_at',
    'calliope_sp_threads_user_id',
    'calliope_sp_telegram_bot_token',
    'calliope_sp_telegram_chat_id',
    'calliope_sp_telegram_connection_status',
    'calliope_sp_telegram_message_thread_id',
    'calliope_sp_tumblr_blog_identifier',
    'calliope_sp_tumblr_connection_status',
    'calliope_sp_tumblr_consumer_key',
    'calliope_sp_tumblr_consumer_secret',
    'calliope_sp_tumblr_token',
    'calliope_sp_tumblr_token_secret',
    // Legacy Facebook options should not survive a full cleanup.
    'sh_fb_app_id',
    'sh_fb_app_secret',
    'sh_fb_config_id',
    'sh_fb_page_access_token',
    'sh_fb_page_id',
    'sh_fb_pages_last',
    'sh_fb_user_access_token',
];

calliope_sp_uninstall_delete_options($calliope_sp_option_names);

$calliope_sp_transient_names = [
    'calliope_sp_fb_oauth_state',
    'calliope_sp_restored_connections_notice',
];

foreach ($calliope_sp_transient_names as $calliope_sp_transient_name) {
    delete_transient($calliope_sp_transient_name);
    delete_site_transient($calliope_sp_transient_name);
}

calliope_sp_uninstall_delete_transient_patterns([
    'calliope_sp_blogger_oauth_%',
    'calliope_sp_fb_oauth_%',
    'calliope_sp_instagram_oauth_%',
    'calliope_sp_linkedin_oauth_%',
    'calliope_sp_mastodon_oauth_%',
    'calliope_sp_pinterest_oauth_%',
    'calliope_sp_threads_oauth_%',
    'calliope_sp_tumblr_oauth_%',
    'calliope_sp_tumblr_req_secret_%',
]);

delete_metadata('post', 0, 'calliope_sp_gb_posted', '', true);
delete_metadata('post', 0, 'calliope_sp_gb_last_log', '', true);

$calliope_sp_uploads = wp_get_upload_dir();
if (!empty($calliope_sp_uploads['basedir'])) {
    $calliope_sp_base_dir = wp_normalize_path((string) $calliope_sp_uploads['basedir']);
    $calliope_sp_uploads_plugin_dir = wp_normalize_path(trailingslashit($calliope_sp_base_dir) . 'calliope-social-publisher');
    $calliope_sp_uploads_meta_dir = wp_normalize_path(trailingslashit($calliope_sp_base_dir) . 'calliope-social-publisher-meta');

    if ($calliope_sp_base_dir !== '' && strpos($calliope_sp_uploads_plugin_dir, $calliope_sp_base_dir) === 0) {
        calliope_sp_uninstall_delete_upload_dir($calliope_sp_uploads_plugin_dir);
    }

    if ($calliope_sp_base_dir !== '' && strpos($calliope_sp_uploads_meta_dir, $calliope_sp_base_dir) === 0) {
        calliope_sp_uninstall_delete_upload_dir($calliope_sp_uploads_meta_dir);
    }
}
