<?php

// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedNamespaceFound -- APD is the established namespace shared with the Pro add-on and retained for backward compatibility.
namespace APD\Installation;

use APD\Admin\AdminSettings;
use APD\PostTypes\ProductConfigPostType;
use APD\PostTypes\TemplatePostType;
use APD\PostTypes\ThemePostType;
use APD\PostTypes\UserDesignPostType;
use APD\Support\AssetCatalog;
use APD\Support\Capabilities;
use APD\Theme\DesignerTheme;

defined('ABSPATH') || exit;

class Uninstaller
{
    public static function uninstall() : void
    {
        if (is_multisite()) {
            $siteIds = get_sites([
                'fields' => 'ids',
                'number' => 0,
            ]);

            foreach ($siteIds as $siteId) {
                switch_to_blog((int) $siteId);
                self::purgeCurrentSiteIfRequested();
                restore_current_blog();
            }

            return;
        }

        self::purgeCurrentSiteIfRequested();
    }

    private static function purgeCurrentSiteIfRequested() : void
    {
        $settings = (array) get_option(AdminSettings::OPTION, []);
        if (($settings['delete_data_on_uninstall'] ?? '0') !== '1') {
            return;
        }

        self::deletePluginPosts();
        self::deleteTemporaryPreviews();
        self::deletePluginTransients();
        Capabilities::removeAllRoleCaps();

        foreach (self::optionNames() as $optionName) {
            delete_option($optionName);
        }
    }

    private static function deletePluginPosts() : void
    {
        $postIds = get_posts([
            'post_type' => [
                ProductConfigPostType::TYPE,
                TemplatePostType::TYPE,
                ThemePostType::TYPE,
                UserDesignPostType::TYPE,
            ],
            'post_status' => 'any',
            'posts_per_page' => -1,
            'fields' => 'ids',
            'no_found_rows' => true,
        ]);

        foreach ($postIds as $postId) {
            wp_delete_post((int) $postId, true);
        }
    }

    private static function deleteTemporaryPreviews() : void
    {
        $attachmentIds = get_posts([
            'post_type' => 'attachment',
            'post_status' => 'any',
            'posts_per_page' => -1,
            'fields' => 'ids',
            'meta_key' => '_apd_temporary_preview', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Uninstall must locate all temporary previews owned by this plugin.
            'meta_value' => '1', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- The uninstall query runs once and targets a fixed marker value.
            'no_found_rows' => true,
        ]);

        foreach ($attachmentIds as $attachmentId) {
            wp_delete_attachment((int) $attachmentId, true);
        }
    }

    private static function deletePluginTransients() : void
    {
        global $wpdb;

        foreach (['_transient_apd_', '_transient_timeout_apd_'] as $prefix) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Uninstall must remove every matching transient directly; stale data must not be cached.
            $wpdb->query($wpdb->prepare(
                "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
                $wpdb->esc_like($prefix) . '%'
            ));
        }
    }

    private static function optionNames() : array
    {
        return [
            AdminSettings::OPTION,
            AssetCatalog::OPTION,
            UpgradeManager::DATA_SCHEMA_OPTION,
            UpgradeManager::PLUGIN_VERSION_OPTION,
            UpgradeManager::CLIENT_PERMISSION_DEFAULTS_OPTION,
            'apd_qa_checklist_results',
            'apd_js_translation_locales',
            'apd_license_instance_id',
            DesignerTheme::DRAFT_OPTION,
            DesignerTheme::PUBLISHED_OPTION,
            DesignerTheme::LIBRARY_OPTION,
            DesignerTheme::DRAFTS_OPTION,
            DesignerTheme::STORAGE_VERSION_OPTION,
        ];
    }
}
