<?php

namespace WcElectronInvoice;

if (! defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}

use function WcElectronInvoice\Functions\getActiveAddon;
use function WcElectronInvoice\Functions\getListKeyValue;
use WcElectronInvoice\WooCommerce\Fields\GeneralFields;

if (! defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}

/**
 * Integrations
 */
class Integrations
{
    public const DE_DOCUMENT_CORRIDOR_PEPPOL  = 'peppol';
    public const DE_DOCUMENT_CORRIDOR_ZUGFERD = 'zugferd';
    public const CHANNEL_NONE   = 'none';
    public const CHANNEL_FIC    = 'fic';
    public const CHANNEL_ARUBA  = 'aruba';
    public const CHANNEL_SDIPEC = 'sdi_pec';
    public const CHANNEL_SDIPOP = 'sdi_pop';
    public const CHANNEL_PEPPOL = 'peppol';
    public const CHANNEL_KSEF   = 'ksef';
    public const CHANNEL_ZOHO   = 'zoho';
    public const ACTIONS_NONE   = 'none';
    public const ACTIONS_SDI    = 'sdi';
    public const ACTIONS_PEPPOL = 'peppol';
    public const ACTIONS_KSEF   = 'ksef';
    public const ACTIONS_ZOHO   = 'zoho';

    /**
     * $addonPlugins
     *
     * @var string[]
     */
    public static $addonPlugins = array();

    /**
     * Addons product sku code
     *
     * @var string[]
     */
    public static $addonListCode = [
        'WP-POP-FIC'     => 'fattureincloud',
        'WP-POP-FIC-RC'  => 'fattureincloud-receipts',
        'WP-POP-FIC-MS'  => 'fattureincloud-stock',
        'WP-POP-AR'      => 'aruba',
        'WP-POP-SDI-PEC' => 'sdi-pec',
        'WP-POP-CZM-PMS' => 'cozmos', // is this useful?
        'WP-POP-PMPRO'   => 'pmpro',  // is this useful?
    ];

    /**
     * $addonCore
     *
     * @var string[]
     */
    public static $addonCore = array(
        'aruba'                   => WC_EL_INV_DIR . 'addon/to/aruba/index',
        'fattureincloud'          => WC_EL_INV_DIR . 'addon/to/fattureincloud/index',
        'fattureincloud-receipts' => WC_EL_INV_DIR . 'addon/to/fattureincloud-receipts/index',
        'fattureincloud-stock'    => WC_EL_INV_DIR . 'addon/to/fattureincloud-stock/index',
        'sdi-pec'                 => WC_EL_INV_DIR . 'addon/to/sdi-pec/index',
        'cozmos'                  => WC_EL_INV_DIR . 'addon/for/cozmos/index',
        'pmpro'                   => WC_EL_INV_DIR . 'addon/for/pmpro/index',
    );

    /**
     * Addon options toggled from the Integrations screen.
     *
     * @var string[]
     */
    private static $supportedAddonOptions = [
        'wc_el_inv-addon-fattureincloud',
        'wc_el_inv-addon-fattureincloud-receipts',
        'wc_el_inv-addon-fattureincloud-stock',
        'wc_el_inv-addon-aruba',
        'wc_el_inv-addon-sdi-pec',
        'wc_el_inv-addon-cozmos',
        'wc_el_inv-addon-pmpro',
        'wc_el_inv-addon-sdi-via-pop',
        'wc_el_inv-addon-peppol-via-pop',
        'wc_el_inv-addon-ksef-via-pop',
        'wc_el_inv-addon-zoho-via-pop',
    ];

    /**
     * Membership entrypoints can coexist and must not be normalized as mutually exclusive.
     *
     * @var string[]
     */
    private static $membershipAddonOptions = [
        'wc_el_inv-addon-cozmos',
        'wc_el_inv-addon-pmpro',
    ];

    /**
     * Construct
     */
    public function __construct($plugins = array())
    {
        self::$addonPlugins = array_merge($plugins, self::$addonPlugins);
    }

    /**
     * haveIntegrationActive
     *
     * @return bool
     */
    public static function haveIntegrationActive($integration = null): bool
    {
        // SDI via POP is not in the list as here we control the activation of
        // third party integrations (FIC, ARUBA, etc...), while SDI via POP is a "native" integration
        $options = [
            'wc_el_inv-addon-fattureincloud',
            'wc_el_inv-addon-sdi-pec',
            'wc_el_inv-addon-aruba',
        ];

        if ($integration) {
            return boolval(get_option("wc_el_inv-addon-{$integration}"));
        }

        foreach ($options as $option) {
            if (boolval(get_option($option))) {
                return true;
            }
        }

        return false;
    }

    /**
     * Resolve the active invoicing channel.
     *
     * The result is deterministic and exclusive:
     * one channel or "none".
     *
     * @return string
     */
    public static function resolveActiveInvoiceChannel(): string
    {
        if ((bool)get_option('wc_el_inv-addon-zoho-via-pop', false)) {
            $zohoData = class_exists(__NAMESPACE__ . '\\ZohoApi')
                ? \WcElectronInvoice\ZohoApi::getZohoPOPIntegrationData()
                : (object)['zoho_integration' => false];

            return ! empty($zohoData->zoho_integration) ? self::CHANNEL_ZOHO : self::CHANNEL_NONE;
        }

        $channels = [
            self::CHANNEL_FIC    => (bool)get_option('wc_el_inv-addon-fattureincloud') &&
                                    class_exists('WooPoPToFattureInCloud\\Plugin'),
            self::CHANNEL_ARUBA  => (bool)get_option('wc_el_inv-addon-aruba') &&
                                    class_exists('WooPoPToFattureAruba\\Plugin'),
            self::CHANNEL_SDIPEC => (bool)get_option('wc_el_inv-addon-sdi-pec') &&
                                    class_exists('WooPoPToSdIPec\\Plugin'),
            self::CHANNEL_SDIPOP => (bool)get_option('wc_el_inv-addon-sdi-via-pop', false) &&
                                    self::isSdiPopIntegrationActive(),
            self::CHANNEL_PEPPOL => (bool)get_option('wc_el_inv-addon-peppol-via-pop', false) &&
                                    self::isPeppolIntegrationActive(),
            self::CHANNEL_KSEF   => (bool)get_option('wc_el_inv-addon-ksef-via-pop', false) &&
                                    self::isKsefCountryContext(),
            self::CHANNEL_ZOHO   => false,
        ];

        $defaultChannels = $channels;
        $channels        = apply_filters('wc_el_inv-invoice_channels_status', $channels);
        if (! is_array($channels)) {
            $channels = $defaultChannels;
        }

        if (! empty($channels[self::CHANNEL_SDIPOP]) && ! empty($channels[self::CHANNEL_PEPPOL])) {
            $shopCountry = self::getNormalizedShopCountry();

            if (self::isSdiCountryContext($shopCountry)) {
                $channels[self::CHANNEL_PEPPOL] = false;
            } elseif (self::isPeppolCountryContext($shopCountry)) {
                $channels[self::CHANNEL_SDIPOP] = false;
            } else {
                $channels[self::CHANNEL_PEPPOL] = false;
            }
        }

        $defaultPriority = [
            self::CHANNEL_FIC,
            self::CHANNEL_ARUBA,
            self::CHANNEL_SDIPEC,
            self::CHANNEL_SDIPOP,
            self::CHANNEL_PEPPOL,
            self::CHANNEL_KSEF,
            self::CHANNEL_ZOHO,
        ];

        $priority = apply_filters('wc_el_inv-invoice_channel_priority', $defaultPriority);

        if (! is_array($priority) || empty($priority)) {
            $priority = $defaultPriority;
        }

        foreach ($priority as $channel) {
            if (! is_string($channel) || '' === $channel) {
                continue;
            }
            if (isset($channels[$channel]) && (bool)$channels[$channel]) {
                return (string)$channel;
            }
        }

        return self::CHANNEL_NONE;
    }

    /**
     * Check if the provided channel is the resolved active one.
     *
     * @param string $channel
     *
     * @return bool
     */
    public static function isInvoiceChannelActive(string $channel): bool
    {
        return self::resolveActiveInvoiceChannel() === $channel;
    }

    /**
     * Check if at least one invoicing channel is active.
     *
     * @return bool
     */
    public static function hasAnyInvoiceChannelActive(): bool
    {
        return self::CHANNEL_NONE !== self::resolveActiveInvoiceChannel();
    }

    /**
     * Returns normalized configured shop country (fallback to saved option).
     *
     * @return string
     */
    public static function getNormalizedShopCountry(): string
    {
        $shopCountry = strtoupper(trim((string)GeneralFields::getGeneralInvoiceOptionCountryState()));
        if ('' === $shopCountry) {
            $shopCountry = strtoupper(trim((string)get_option(GeneralFields::$optionPrefix . 'general_store_country', '')));
        }

        return $shopCountry;
    }

    /**
     * Return the configured Germany document corridor.
     *
     * Local option is the primary source. Filters and cached remote payloads can
     * override it until the dedicated local setting is fully rolled out.
     *
     * @return string
     */
    public static function getGermanyDocumentCorridor(): string
    {
        $corridor = trim((string)get_option('wc_el_inv-de_document_corridor', ''));

        if ('' === $corridor) {
            $cachedRemote = get_option('wc_el_inv-account_document_preferences', []);
            if (is_array($cachedRemote) && isset($cachedRemote['de_document_corridor'])) {
                $corridor = trim((string)$cachedRemote['de_document_corridor']);
            }
        }

        $corridor = strtolower(trim((string)apply_filters('wc_el_inv-de_document_corridor', $corridor)));

        return $corridor;
    }

    /**
     * Returns true when the current DE context must use the ZUGFeRD bundle flow.
     *
     * @return bool
     */
    public static function isGermanyZugferdContext(): bool
    {
        return 'DE' === self::getNormalizedShopCountry() &&
               self::DE_DOCUMENT_CORRIDOR_ZUGFERD === self::getGermanyDocumentCorridor();
    }

    /**
     * Returns true if provided country belongs to configured UBL countries.
     * If UBL list is unavailable, any non-empty country is considered allowed.
     *
     * @param string $country
     *
     * @return bool
     */
    public static function isUblCountry(string $country): bool
    {
        $country = strtoupper(trim($country));
        if ('' === $country) {
            return false;
        }

        if (defined('WC_EL_INV_UBL_COUNTRIES') && is_array(WC_EL_INV_UBL_COUNTRIES) && ! empty(WC_EL_INV_UBL_COUNTRIES)) {
            return in_array($country, WC_EL_INV_UBL_COUNTRIES, true);
        }

        return true;
    }

    /**
     * Returns true if the SDI-POP integration is active (live or sandbox).
     *
     * @return bool
     */
    public static function isSdiPopIntegrationActive(): bool
    {
        return 'active' === get_option('wc_el_inv-active_sdipop_integration') ||
               'active' === get_option('wc_el_inv-active_sdipop_integration_sandbox');
    }

    /**
     * Returns true if the PEPPOL integration is active (live or sandbox).
     *
     * @return bool
     */
    public static function isPeppolIntegrationActive(): bool
    {
        return 'active' === get_option('wc_el_inv-active_peppol_integration') ||
               'active' === get_option('wc_el_inv-active_peppol_integration_sandbox');
    }

    /**
     * Returns true if country is SDI context (IT/SM).
     *
     * @param string|null $country
     *
     * @return bool
     */
    public static function isSdiCountryContext(?string $country = null): bool
    {
        $country = strtoupper(trim((string)$country));
        if ('' === $country) {
            $country = self::getNormalizedShopCountry();
        }

        return in_array($country, ['IT', 'SM'], true);
    }

    /**
     * Returns true if country is PEPPOL context (non IT/SM and UBL-enabled).
     *
     * @param string|null $country
     *
     * @return bool
     */
    public static function isPeppolCountryContext(?string $country = null): bool
    {
        $country = strtoupper(trim((string)$country));
        if ('' === $country) {
            $country = self::getNormalizedShopCountry();
        }

        if ('' === $country || self::isSdiCountryContext($country)) {
            return false;
        }

        return self::isUblCountry($country);
    }

    /**
     * Returns true if current context should be treated as PEPPOL.
     * Active channel takes precedence; country acts as robust fallback.
     *
     * @return bool
     */
    public static function isPeppolContext(): bool
    {
        return self::ACTIONS_PEPPOL === self::resolveNativeActionsContext();
    }

    /**
     * Returns true if current context should be treated as SDI.
     * Active channel takes precedence; country acts as robust fallback.
     *
     * @return bool
     */
    public static function isSdiContext(): bool
    {
        return self::ACTIONS_SDI === self::resolveNativeActionsContext();
    }

    /**
     * Returns true if country is KSeF context (Poland).
     *
     * @param string|null $country
     *
     * @return bool
     */
    public static function isKsefCountryContext(?string $country = null): bool
    {
        $country = strtoupper(trim((string)$country));
        if ('' === $country) {
            $country = self::getNormalizedShopCountry();
        }

        return 'PL' === $country;
    }

    /**
     * Returns true if current context should be treated as KSeF.
     *
     * @return bool
     */
    public static function isKsefContext(): bool
    {
        return self::ACTIONS_KSEF === self::resolveNativeActionsContext();
    }

    /**
     * Resolve which native actions context should be used.
     *
     * @param string|null $country
     *
     * @return string
     */
    public static function resolveNativeActionsContext(?string $country = null): string
    {
        $activeChannel = self::resolveActiveInvoiceChannel();
        if (self::CHANNEL_ZOHO === $activeChannel) {
            return self::ACTIONS_ZOHO;
        }

        $country = strtoupper(trim((string)$country));
        if ('' === $country) {
            $country = self::getNormalizedShopCountry();
        }

        if (self::isKsefCountryContext($country)) {
            return self::ACTIONS_KSEF;
        }

        if (self::isSdiCountryContext($country)) {
            return self::ACTIONS_SDI;
        }

        if (self::isPeppolCountryContext($country)) {
            return self::ACTIONS_PEPPOL;
        }

        if (in_array($activeChannel, [
            self::CHANNEL_SDIPOP,
            self::CHANNEL_SDIPEC,
            self::CHANNEL_FIC,
            self::CHANNEL_ARUBA,
        ], true)) {
            return self::ACTIONS_SDI;
        }

        if (self::CHANNEL_PEPPOL === $activeChannel) {
            return self::ACTIONS_PEPPOL;
        }

        if (self::CHANNEL_ZOHO === $activeChannel) {
            return self::ACTIONS_ZOHO;
        }

        return self::ACTIONS_NONE;
    }

    /**
     * Resolve which fiscal corridor should drive document endpoint generation actions.
     *
     * Unlike send/sync actions, document generation must remain tied to the
     * country corridor even when an exclusive connector like Zoho is active.
     *
     * @param string|null $country
     *
     * @return string
     */
    public static function resolveDocumentEndpointContext(?string $country = null): string
    {
        $country = strtoupper(trim((string)$country));
        if ('' === $country) {
            $country = self::getNormalizedShopCountry();
        }

        if (self::isKsefCountryContext($country)) {
            return self::ACTIONS_KSEF;
        }

        if (self::isSdiCountryContext($country)) {
            return self::ACTIONS_SDI;
        }

        if (self::isPeppolCountryContext($country)) {
            return self::ACTIONS_PEPPOL;
        }

        return self::ACTIONS_NONE;
    }

    /**
     * Append configured native integration and webhook actions.
     *
     * @param string      $output
     * @param mixed       $id
     * @param array|null  $item
     * @param string|null $provider
     *
     * @return string
     */
    public static function appendConfiguredActions(string $output, $id, ?array $item = null, ?string $provider = 'woocommerce'): string
    {
        foreach (self::getConfiguredActionCallbacks() as $callback) {
            if (! is_callable($callback)) {
                continue;
            }

            $output = call_user_func($callback, $output, $id, $item, $provider ?: 'woocommerce');
        }

        if (\WcElectronInvoice\Functions\usePoPWebhook()) {
            $output = \WcElectronInvoice\Functions\webHookActions($output, $id, $item, $provider ?: 'woocommerce');
        }

        return $output;
    }

    /**
     * Resolve configured native action callbacks for current context.
     *
     * @return array<int, callable>
     */
    private static function getConfiguredActionCallbacks(): array
    {
        $callbacks = [];

        if (self::CHANNEL_ZOHO === self::resolveActiveInvoiceChannel()) {
            $zohoApi = __NAMESPACE__ . '\\ZohoApi';
            if (class_exists($zohoApi)) {
                $callbacks[] = [$zohoApi, 'actions'];
            }

            return $callbacks;
        }

        if (self::isGermanyZugferdContext()) {
            return $callbacks;
        }

        $context   = self::resolveNativeActionsContext();

        if (self::ACTIONS_SDI === $context && ! self::haveIntegrationActive()) {
            $invoiceApi = __NAMESPACE__ . '\\InvoiceApi';
            if (class_exists($invoiceApi)) {
                $callbacks[] = [$invoiceApi, 'actions'];
            }
        }

        if (self::ACTIONS_PEPPOL === $context) {
            $peppolApi = __NAMESPACE__ . '\\PeppolApi';
            if (class_exists($peppolApi)) {
                $callbacks[] = [$peppolApi, 'actions'];
            }
        }

        if (self::ACTIONS_KSEF === $context) {
            $ksefApi = __NAMESPACE__ . '\\KsefApi';
            if (class_exists($ksefApi)) {
                $callbacks[] = [$ksefApi, 'actions'];
            }
        }

        return $callbacks;
    }

    /**
     * Load
     *
     * @return void
     */
    public function load()
    {
        if (! empty(self::$addonPlugins)) {
            add_action('init', [$this, 'disable']);
            add_action('wp_ajax_integration_save_option', [$this, 'save']);
            add_action('wc_el_inv-after_init', [$this, 'init']);
        }
    }

    /**
     * disableAddonPlugin
     *
     * @return void
     */
    public function disable()
    {
        $oneTimeExecutionOption = 'addon_plugins_deactivation_completed';
        if (get_option($oneTimeExecutionOption)) {
            return;
        }

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

        $addonPluginsPath = self::$addonPlugins;
        foreach ($addonPluginsPath as $pluginSlug => $pluginOption) {
            $pluginPath = $pluginSlug . '/index.php';
            if (is_plugin_active($pluginPath)) {
                deactivate_plugins($pluginPath);
                if (! self::isMembershipAddonOption($pluginOption)) {
                    update_option($pluginOption, "1");
                }
            } else {
                if (! self::isMembershipAddonOption($pluginOption)) {
                    update_option($pluginOption, "0");
                }
            }
        }

        update_option($oneTimeExecutionOption, true);
    }

    /**
     * saveAddonIntegration
     *
     * @return void|null
     */
    public function save()
    {
        if (is_admin()) {
            if (! check_ajax_referer('ajax_option_save_nonce', 'security')) {
                return null;
            }

            $optionName  = sanitize_text_field(\WcElectronInvoice\Functions\filterInput($_POST, 'option_name',
                FILTER_UNSAFE_RAW)) ?: '';
            $optionValue = sanitize_text_field(\WcElectronInvoice\Functions\filterInput($_POST, 'option_value',
                FILTER_UNSAFE_RAW)) ?: '';
            $optionValue = 1 === (int)$optionValue ? "1" : "0";

            if (! in_array($optionName, self::$supportedAddonOptions, true)) {
                wp_send_json(array(
                    'message' => 'Invalid integration option.',
                    'plugin'  => $optionName ?: null,
                    'status'  => 'inactive',
                    'success' => false,
                ));
            }

            if ("1" === $optionValue && ! $this->canEnableAddonOption($optionName)) {
                wp_send_json(array(
                    'message' => 'Integration not available for current account level/configuration.',
                    'plugin'  => $optionName,
                    'status'  => 'inactive',
                    'success' => false,
                ));
            }

            if (! empty($optionName)) {
                if (self::isInvoiceChannelOption($optionName) && "1" === $optionValue) {
                    $this->deactivateExclusiveInvoiceChannels($optionName);
                }

                update_option($optionName, $optionValue);

                if ('wc_el_inv-addon-zoho-via-pop' === $optionName && class_exists(__NAMESPACE__ . '\\ZohoApi')) {
                    \WcElectronInvoice\ZohoApi::clearZohoPOPIntegrationDataCache();
                }

                wp_send_json(array(
                    'message' => $optionName . ': option saved',
                    'plugin'  => $optionName,
                    'status'  => 1 === (int)$optionValue ? 'active' : 'inactive',
                    'success' => true,
                ));
            } else {
                wp_send_json(array(
                    'message' => 'Empty option name',
                    'plugin'  => null,
                    'status'  => 'inactive',
                    'success' => false,
                ));
            }
        }
    }

    /**
     * init
     *
     * @return void
     */
    public function init()
    {
        // Get allowed addon list
        $allowedAddon = Plugin::allowedAddon();
        $list         = getListKeyValue($allowedAddon, 'item_code', 'status');
        $level        = \WcElectronInvoice\Wizard::popGetUserLevel();

        $this->normalizeAddonOptions($level, $list);

        // Get status from list
        $statusFic    = getActiveAddon('WP-POP-FIC', $list);
        $statusFicRc  = getActiveAddon('WP-POP-FIC-RC', $list);
        $statusFicMs  = getActiveAddon('WP-POP-FIC-MS', $list);
        $statusAruba  = getActiveAddon('WP-POP-AR', $list);
        $statusSdiPec = getActiveAddon('WP-POP-SDI-PEC', $list);
        $statusCzmPms = getActiveAddon('WP-POP-CZM-PMS', $list);
        $statusPmPro  = getActiveAddon('WP-POP-PMPRO', $list);

        // Get status option
        $sdiPecActive     = boolval(get_option('wc_el_inv-addon-sdi-pec'));
        $arubaActive      = boolval(get_option('wc_el_inv-addon-aruba'));
        $ficActive        = boolval(get_option('wc_el_inv-addon-fattureincloud'));
        $ficReceiptActive = boolval(get_option('wc_el_inv-addon-fattureincloud-receipts'));
        $ficStockActive   = boolval(get_option('wc_el_inv-addon-fattureincloud-stock'));
        $czmActive        = boolval(get_option('wc_el_inv-addon-cozmos'));
        $pmproActive      = boolval(get_option('wc_el_inv-addon-pmpro'));

        $proOnly = ! \WcElectronInvoice\Wizard::isUserLevelGte($level, 'pro');

        if ($statusFic && ! $proOnly) {
            if (! $arubaActive && ! $sdiPecActive && $ficActive) {
                require_once untrailingslashit(self::$addonCore['fattureincloud'] . '.php');
            }
        }
        if ($statusFicRc && ! $proOnly) {
            if (! $arubaActive && ! $sdiPecActive && $ficActive && $ficReceiptActive) {
                require_once untrailingslashit(self::$addonCore['fattureincloud-receipts'] . '.php');
            }
        }
        if ($statusFicMs && ! $proOnly) {
            if (! $arubaActive && ! $sdiPecActive && $ficActive && $ficStockActive) {
                require_once untrailingslashit(self::$addonCore['fattureincloud-stock'] . '.php');
            }
        }
        if ($statusAruba && ! $proOnly) {
            if (! $ficActive && ! $sdiPecActive && $arubaActive) {
                require_once untrailingslashit(self::$addonCore['aruba'] . '.php');
            }
        }
        if ($statusSdiPec && ! $proOnly) {
            if (! $arubaActive && ! $ficActive && $sdiPecActive) {
                require_once untrailingslashit(self::$addonCore['sdi-pec'] . '.php');
            }
        }
        $loadedAddonProvider = false;

        if (\WcElectronInvoice\Functions\isCozmoslabsPaidMemberSubscriptionsActive() && $statusCzmPms && $czmActive) {
            require_once untrailingslashit(self::$addonCore['cozmos'] . '.php');
            $loadedAddonProvider = true;
        }
        if (\WcElectronInvoice\Functions\isPaidMembershipsProActive() && $statusPmPro && $pmproActive) {
            require_once untrailingslashit(self::$addonCore['pmpro'] . '.php');
            $loadedAddonProvider = true;
        }

        // Membership entrypoints are loaded after the core provider enqueue pass.
        // Re-run provider registration so late-loaded providers become available.
        if ($loadedAddonProvider) {
            do_action('wc_el_inv-enqueue_orders_provider');
            do_action('wc_el_inv-enqueue_taxes_provider');
            do_action('wc_el_inv-enqueue_products_provider');
        }
    }

    /**
     * Normalize addon options to avoid stale active flags after license changes.
     *
     * @param string $level
     * @param array  $allowedAddonList
     *
     * @return void
     */
    private function normalizeAddonOptions($level, array $allowedAddonList): void
    {
        $addonCodeByOption = [
            'wc_el_inv-addon-fattureincloud'          => 'WP-POP-FIC',
            'wc_el_inv-addon-fattureincloud-receipts' => 'WP-POP-FIC-RC',
            'wc_el_inv-addon-fattureincloud-stock'    => 'WP-POP-FIC-MS',
            'wc_el_inv-addon-aruba'                   => 'WP-POP-AR',
            'wc_el_inv-addon-sdi-pec'                 => 'WP-POP-SDI-PEC',
            'wc_el_inv-addon-cozmos'                  => 'WP-POP-CZM-PMS',
            'wc_el_inv-addon-pmpro'                   => 'WP-POP-PMPRO',
        ];

        foreach ($addonCodeByOption as $optionName => $addonCode) {
            if (self::isMembershipAddonOption($optionName)) {
                continue;
            }

            if (! getActiveAddon($addonCode, $allowedAddonList) && boolval(get_option($optionName))) {
                update_option($optionName, "0");
            }
        }

        if (! \WcElectronInvoice\Wizard::isUserLevelGte($level, 'pro')) {
            $proOnlyOptions = [
                'wc_el_inv-addon-fattureincloud',
                'wc_el_inv-addon-fattureincloud-receipts',
                'wc_el_inv-addon-fattureincloud-stock',
                'wc_el_inv-addon-aruba',
                'wc_el_inv-addon-sdi-pec',
            ];

            foreach ($proOnlyOptions as $optionName) {
                if (boolval(get_option($optionName))) {
                    update_option($optionName, "0");
                }
            }
        }

        $sdiContextOptions = [
            'wc_el_inv-addon-fattureincloud',
            'wc_el_inv-addon-fattureincloud-receipts',
            'wc_el_inv-addon-fattureincloud-stock',
            'wc_el_inv-addon-aruba',
            'wc_el_inv-addon-sdi-pec',
            'wc_el_inv-addon-sdi-via-pop',
        ];

        if (! self::isSdiCountryContext()) {
            foreach ($sdiContextOptions as $optionName) {
                if (boolval(get_option($optionName))) {
                    update_option($optionName, "0");
                }
            }
        }

        if (! \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic')) {
            update_option('wc_el_inv-addon-sdi-via-pop', "0");
            update_option('wc_el_inv-addon-peppol-via-pop', "0");
        }

        if (! self::isSdiPopIntegrationActive()) {
            update_option('wc_el_inv-addon-sdi-via-pop', "0");
        }

        if (! self::isPeppolIntegrationActive()) {
            update_option('wc_el_inv-addon-peppol-via-pop', "0");
        }

        if (! self::isPeppolCountryContext()) {
            update_option('wc_el_inv-addon-peppol-via-pop', "0");
        }

        if (! \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic')) {
            update_option('wc_el_inv-addon-ksef-via-pop', "0");
        }

        $ksefData = \WcElectronInvoice\KsefApi::getKsefPOPIntegrationData();
        if (! $ksefData->ksef_integration) {
            update_option('wc_el_inv-addon-ksef-via-pop', "0");
        }

        if (! self::isKsefCountryContext()) {
            update_option('wc_el_inv-addon-ksef-via-pop', "0");
        }

        if (! \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic')) {
            update_option('wc_el_inv-addon-zoho-via-pop', "0");
        }
    }

    /**
     * Validate if an addon option can be enabled for current level/account.
     *
     * @param string $optionName
     *
     * @return bool
     */
    private function canEnableAddonOption(string $optionName): bool
    {
        $level = \WcElectronInvoice\Wizard::popGetUserLevel();

        if ('wc_el_inv-addon-sdi-via-pop' === $optionName) {
            return \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic') &&
                   self::isSdiCountryContext() &&
                   self::isSdiPopIntegrationActive();
        }

        if ('wc_el_inv-addon-peppol-via-pop' === $optionName) {
            return \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic') &&
                   self::isPeppolCountryContext() &&
                   self::isPeppolIntegrationActive();
        }

        if ('wc_el_inv-addon-ksef-via-pop' === $optionName) {
            $ksefData = \WcElectronInvoice\KsefApi::getKsefPOPIntegrationData();

            return \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic') &&
                   self::isKsefCountryContext() &&
                   $ksefData->ksef_integration;
        }

        if ('wc_el_inv-addon-zoho-via-pop' === $optionName) {
            $zohoData = class_exists(__NAMESPACE__ . '\\ZohoApi')
                ? \WcElectronInvoice\ZohoApi::getZohoPOPIntegrationData()
                : (object)['zoho_integration' => false];

            return \WcElectronInvoice\Wizard::isUserLevelGte($level, 'basic') &&
                   ! empty($zohoData->zoho_integration);
        }

        $addonCodeByOption = [
            'wc_el_inv-addon-fattureincloud'          => 'WP-POP-FIC',
            'wc_el_inv-addon-fattureincloud-receipts' => 'WP-POP-FIC-RC',
            'wc_el_inv-addon-fattureincloud-stock'    => 'WP-POP-FIC-MS',
            'wc_el_inv-addon-aruba'                   => 'WP-POP-AR',
            'wc_el_inv-addon-sdi-pec'                 => 'WP-POP-SDI-PEC',
            'wc_el_inv-addon-cozmos'                  => 'WP-POP-CZM-PMS',
            'wc_el_inv-addon-pmpro'                   => 'WP-POP-PMPRO',
        ];

        if (! isset($addonCodeByOption[$optionName])) {
            return false;
        }

        $proOnlyOptions = [
            'wc_el_inv-addon-fattureincloud',
            'wc_el_inv-addon-fattureincloud-receipts',
            'wc_el_inv-addon-fattureincloud-stock',
            'wc_el_inv-addon-aruba',
            'wc_el_inv-addon-sdi-pec',
        ];

        $sdiContextOptions = [
            'wc_el_inv-addon-fattureincloud',
            'wc_el_inv-addon-fattureincloud-receipts',
            'wc_el_inv-addon-fattureincloud-stock',
            'wc_el_inv-addon-aruba',
            'wc_el_inv-addon-sdi-pec',
        ];

        if (in_array($optionName, $proOnlyOptions, true) &&
            ! \WcElectronInvoice\Wizard::isUserLevelGte($level, 'pro')
        ) {
            return false;
        }

        if (in_array($optionName, $sdiContextOptions, true) && ! self::isSdiCountryContext()) {
            return false;
        }

        $allowedAddon = Plugin::allowedAddon();
        $list         = getListKeyValue($allowedAddon, 'item_code', 'status');

        return getActiveAddon($addonCodeByOption[$optionName], $list);
    }

    /**
     * @param string $optionName
     *
     * @return bool
     */
    private static function isMembershipAddonOption(string $optionName): bool
    {
        return in_array($optionName, self::$membershipAddonOptions, true);
    }

    /**
     * Return whether the provided option belongs to the exclusive invoice-channel set.
     *
     * @param string $optionName
     *
     * @return bool
     */
    private static function isInvoiceChannelOption(string $optionName): bool
    {
        return in_array($optionName, self::getInvoiceChannelOptions(), true);
    }

    /**
     * Return the exclusive invoice-channel options.
     *
     * @return string[]
     */
    private static function getInvoiceChannelOptions(): array
    {
        return [
            'wc_el_inv-addon-fattureincloud',
            'wc_el_inv-addon-aruba',
            'wc_el_inv-addon-sdi-pec',
            'wc_el_inv-addon-sdi-via-pop',
            'wc_el_inv-addon-peppol-via-pop',
            'wc_el_inv-addon-ksef-via-pop',
            'wc_el_inv-addon-zoho-via-pop',
        ];
    }

    /**
     * Deactivate every mutually exclusive invoice-channel option except the selected one.
     *
     * @param string $selectedOption
     *
     * @return void
     */
    private function deactivateExclusiveInvoiceChannels(string $selectedOption): void
    {
        foreach (self::getInvoiceChannelOptions() as $optionName) {
            if ($optionName === $selectedOption) {
                continue;
            }

            update_option($optionName, "0");
        }

        if ('wc_el_inv-addon-fattureincloud' !== $selectedOption) {
            update_option('wc_el_inv-addon-fattureincloud-receipts', "0");
            update_option('wc_el_inv-addon-fattureincloud-stock', "0");
        }
    }
}
