<?php

/**
 * Module to process plugin uninstallation.
 *
 * @package northmill-online-shared
 */
declare (strict_types=1);
namespace Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Uninstallers;

use Northmill_Online_Shared_Checkout\Automattic\WooCommerce\Utilities\LoggingUtil;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Abstract_Plugin_Shared;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Abstracts\Hub_API\Hub_Accounts\Invalid_Hub_Accounts;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Abstracts\Hub_API\Hub_Accounts\Options_Page_Processing;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Abstracts\Hub_API\Hub_Accounts\WP_Repository;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Helpers\Hook_Helpers;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Abstract_Module;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Admin\Pages\Page\Admin_Settings;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Debug_Module;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Sync\Customers\Customer_Sync;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Sync\Orders\Models\Order_Base_Model;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Sync\Receipt_Sync_Module;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Sync\Receipts\Receipt_Status_Module;
defined('ABSPATH') || exit;
/**
 * Class Plugin_Uninstaller_Module
 */
class Plugin_Uninstaller_Module extends Abstract_Module
{
    /**
     * Runs on plugin uninstallation.
     */
    final public static function plugin_uninstall(): void
    {
        $plugin_shared = Abstract_Plugin_Shared::base_plugin_instance();
        self::prepare_for_uninstallation($plugin_shared);
        $plugin_shared->cron->deactivate();
        if ($plugin_shared->uninstaller->is_uninstall_cleaner_enabled()) {
            self::uninstall_delete_options($plugin_shared);
            self::uninstall_delete_transients($plugin_shared);
            self::uninstall_delete_logs($plugin_shared);
            self::uninstall_delete_CPTs();
            self::uninstall_delete_user_meta();
            self::uninstall_delete_post_meta();
            self::uninstall_delete_term_meta();
            Hook_Helpers::do_scoped_action('northmill_online_shared_uninstall_delete_data_after');
            flush_rewrite_rules();
        }
    }
    /**
     * Load data needed for uninstallation.
     *
     * @param Abstract_Plugin_Shared $plugin_shared Plugin shared instance.
     *
     * @return void
     */
    private static function prepare_for_uninstallation(Abstract_Plugin_Shared $plugin_shared): void
    {
        $plugin_shared->updater->setup();
        $plugin_shared->sync->bookkeeping->setup();
        $plugin_shared->sync->setup_external_syncers();
        Hook_Helpers::do_scoped_action('northmill_online_shared_uninstall_prepare_for_uninstallation');
    }
    /**
     * Delete options on uninstallation.
     *
     * @param Abstract_Plugin_Shared $plugin_shared Plugin shared instance.
     *
     * @noinspection SqlNoDataSourceInspection
     */
    private static function uninstall_delete_options(Abstract_Plugin_Shared $plugin_shared): void
    {
        global $wpdb;
        delete_option(Admin_Settings::get_settings_id());
        delete_option($plugin_shared->uninstaller->get_option_name());
        delete_option($plugin_shared->upgrader->get_package_version_option_name());
        delete_option($plugin_shared->upgrader->get_package_updates_option_name());
        delete_option(Invalid_Hub_Accounts::OPTION_NAME);
        delete_option(Options_Page_Processing::OPTION_HUB_ACCOUNTS_UPDATED);
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'northmill_notice_closed_%'");
        foreach ($plugin_shared->sync->get_syncers() as $syncer) {
            $options = $syncer->get_option_names();
            foreach ($options as $option) {
                delete_option($option);
            }
        }
    }
    /**
     * Delete transients on uninstallation.
     *
     * @param Abstract_Plugin_Shared $plugin_shared Plugin shared instance.
     */
    private static function uninstall_delete_transients(Abstract_Plugin_Shared $plugin_shared): void
    {
        delete_transient(Debug_Module::TRANSIENT_NAME);
        $plugin_shared->updater->delete_all_transients();
    }
    /**
     * Delete logs on uninstallation.
     *
     * @param Abstract_Plugin_Shared $plugin_shared Plugin shared instance.
     */
    private static function uninstall_delete_logs(Abstract_Plugin_Shared $plugin_shared): void
    {
        $log_dir = LoggingUtil::get_log_directory();
        $log_prefix = $plugin_shared->package_info->get_service_name();
        if (is_dir($log_dir)) {
            $files = scandir($log_dir);
            if ($files) {
                foreach ($files as $file) {
                    if (str_starts_with($file, $log_prefix)) {
                        $file_path = $log_dir . $file;
                        if (is_file($file_path)) {
                            wp_delete_file($file_path);
                        }
                    }
                }
            }
        }
    }
    /**
     * Delete CPTs on uninstallation.
     */
    private static function uninstall_delete_CPTs(): void
    {
        $shared_custom_post_types = array(WP_Repository::CPT_KEY);
        $custom_post_types = Hook_Helpers::apply_scoped_filters('northmill_online_shared_uninstall_delete_cpts', $shared_custom_post_types);
        $posts = get_posts(array('post_type' => $custom_post_types, 'post_status' => 'any', 'numberposts' => -1, 'fields' => 'ids'));
        foreach ($posts as $post_id) {
            wp_delete_post($post_id, \true);
        }
        Hook_Helpers::do_scoped_action('northmill_online_shared_uninstall_delete_cpts_after', $custom_post_types);
    }
    /**
     * Delete user meta on uninstallation.
     *
     * @noinspection SqlNoDataSourceInspection*/
    private static function uninstall_delete_user_meta(): void
    {
        global $wpdb;
        $user_meta_keys = array(Customer_Sync::META_KEY_CUSTOMER_ID);
        $user_meta_keys = Hook_Helpers::apply_scoped_filters('northmill_online_shared_uninstall_delete_user_meta_keys', $user_meta_keys);
        foreach ($user_meta_keys as $meta_key) {
            $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->usermeta}\n                 WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Delete post meta on uninstallation.
     *
     * @noinspection SqlNoDataSourceInspection*/
    private static function uninstall_delete_post_meta(): void
    {
        global $wpdb;
        $meta_keys = array();
        $meta_keys['shop_order'] = array(Receipt_Sync_Module::ORDER_META_RECEIPT_RESPONSE, Receipt_Sync_Module::ORDER_META_RECEIPT_ID, Receipt_Sync_Module::ORDER_META_RECEIPT_VOUCHER_ID, Receipt_Sync_Module::ORDER_META_RECEIPT_REATTEMPTS, Receipt_Status_Module::RECEIPT_STATUS_META_KEY, Order_Base_Model::META_KEY_HUB_ORDER_ID, Order_Base_Model::META_KEY_ORDER_TYPE, Order_Base_Model::META_KEY_SYNC_STATUS, Order_Base_Model::META_KEY_FULLY_PAID, Order_Base_Model::META_KEY_HASH, Order_Base_Model::META_KEY_LAST_SYNC_RESPONSE, Order_Base_Model::META_KEY_HUB_ACCOUNT_WP_ID);
        $meta_keys['shop_coupon'] = array('nmf_coupon_sync_status');
        $meta_keys = Hook_Helpers::apply_scoped_filters('northmill_online_shared_uninstall_delete_post_meta_keys', $meta_keys);
        foreach ($meta_keys as $post_type => $keys) {
            foreach ($keys as $meta_key) {
                $wpdb->query($wpdb->prepare("DELETE pm\n                     FROM {$wpdb->postmeta} pm\n                     INNER JOIN {$wpdb->posts} p ON pm.post_id = p.ID\n                     WHERE p.post_type = %s\n                     AND pm.meta_key = %s", $post_type, $meta_key));
            }
        }
    }
    /**
     * Delete term meta on uninstallation.
     *
     * @noinspection SqlNoDataSourceInspection*/
    private static function uninstall_delete_term_meta(): void
    {
        global $wpdb;
        $term_meta_keys = array();
        $term_meta_keys = Hook_Helpers::apply_scoped_filters('northmill_online_shared_uninstall_delete_term_meta_keys', $term_meta_keys);
        foreach ($term_meta_keys as $meta_key) {
            $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->termmeta}\n                 WHERE meta_key = %s", $meta_key));
        }
    }
    /**
     * Get the option name for controlling whether to delete data on uninstallation.
     *
     * @return string
     */
    private function get_option_name(): string
    {
        return 'northmill_online_shared_delete_plugin_data_on_uninstall_' . $this->shared->package_info->get_service_name_underscored();
    }
    /**
     * Get the option to controlling whether to  delete data on uninstallation.
     *
     * @return bool
     */
    public function is_uninstall_cleaner_enabled(): bool
    {
        return (bool) get_option($this->get_option_name(), \false);
    }
    /**
     * Enable the option controlling whether to delete data on uninstallation.
     *
     * @return bool Whether the option was successfully updated.
     */
    public function enable_uninstall_cleaner(): bool
    {
        return update_option($this->get_option_name(), \true);
    }
    /**
     * Delete the option controlling whether to delete data on uninstallation.
     *
     * @return bool Whether the option was successfully updated.
     */
    public function disable_uninstall_cleaner(): bool
    {
        return delete_option($this->get_option_name());
    }
}
