<?php

namespace MatthiasWeb\RealMediaLibrary\Vendor\DevOwl\RealUtils;

use MatthiasWeb\RealMediaLibrary\Vendor\DevOwl\RealUtils\TransientHandler;
use MatthiasWeb\RealMediaLibrary\Vendor\DevOwl\RealUtils\UtilsProvider;
use MatthiasWeb\RealMediaLibrary\Vendor\DevOwl\RealUtils\AbstractInitiator;
// @codeCoverageIgnoreStart
\defined('ABSPATH') or die('No script kiddies please!');
// Avoid direct file request
// @codeCoverageIgnoreEnd
/**
 * Handle welcome page for a specific plugin.
 * @internal
 */
class WelcomePage
{
    use UtilsProvider;
    const PAGE_SUFFIX = '-welcome';
    const COLOR_BADGE_LITE = '#28aa00';
    const COLOR_BADGE_PRO = '#0073aa';
    const EXCLUDE_DESCRIPTION_CONTAINS = 'micro add-on';
    const PLUGIN_SLUG_FIXER = ['real-category-library' => 'real-category-library-lite', 'real-category-library-lite' => 'real-category-library', 'real-media-library' => 'real-media-library-lite', 'real-media-library-lite' => 'real-media-library', 'real-thumbnail-generator' => 'real-thumbnail-generator-lite', 'real-thumbnail-generator-lite' => 'real-thumbnail-generator', 'real-cookie-banner' => 'real-cookie-banner-pro'];
    private $initiator;
    /**
     * C'tor.
     *
     * @param AbstractInitiator $initiator
     * @codeCoverageIgnore
     */
    private function __construct($initiator)
    {
        $this->initiator = $initiator;
    }
    /**
     * Add a link to the welcome page.
     *
     * @param string[] $links
     * @param string $plugin
     */
    public function plugin_row_meta($links, $plugin)
    {
        if ($plugin === \plugin_basename($this->getInitiator()->getPluginFile())) {
            $linkTemplate = '<a href="%s" target="%s">%s</a>';
            $links[] = \sprintf($linkTemplate, $this->getWelcomePageLink(), '_self', \__('Learn more about this plugin', 'devowl-wp-real-utils'));
            $links[] = \sprintf($linkTemplate, $this->getInitiator()->getSupportLink(), '_blank', \__('Support', 'devowl-wp-real-utils'));
            $rateLink = $this->getInitiator()->getRateLink();
            if ($rateLink !== null) {
                $links[] = \sprintf($linkTemplate, $rateLink, '_blank', \__('Rate plugin', 'devowl-wp-real-utils'));
            }
        }
        return $links;
    }
    /**
     * Redirect to the welcome page once the plugin is activated.
     *
     * @param string $plugin
     */
    public function activated_plugin($plugin)
    {
        // phpcs:disable WordPress.Security.NonceVerification.Missing -- activation hook context check, no state mutation based on user data.
        $fromBulkAction = isset($_POST['action']) && \sanitize_text_field(\wp_unslash($_POST['action'])) === 'activate-selected';
        // phpcs:enable
        $isWpCli = \defined('WP_CLI') && \constant('WP_CLI');
        if (!$fromBulkAction && !$isWpCli && $plugin === \plugin_basename($this->getInitiator()->getPluginFile())) {
            $redirectState = TransientHandler::get($this->getInitiator(), TransientHandler::TRANSIENT_REDIRECT_AFTER_ACTIVATE, TransientHandler::TRANSIENT_REDIRECT_AFTER_ACTIVATE_NOT_REGISTERED);
            if ($redirectState === TransientHandler::TRANSIENT_REDIRECT_AFTER_ACTIVATE_NOT_REGISTERED) {
                TransientHandler::set($this->getInitiator(), TransientHandler::TRANSIENT_REDIRECT_AFTER_ACTIVATE, TransientHandler::TRANSIENT_REDIRECT_AFTER_ACTIVATE_AWAITING_REDIRECT);
            }
        }
    }
    /**
     * Do the redirection if necessary. This does a client-side redirection to avoid output buffer issues
     * with already-sent output (e.g. PHP warnings and HTTP header `Location`).
     */
    public function admin_head_probably_redirect()
    {
        if (Core::getInstance()->getAssets()->isScreenBase('plugins')) {
            $redirectState = TransientHandler::get($this->getInitiator(), TransientHandler::TRANSIENT_REDIRECT_AFTER_ACTIVATE, TransientHandler::TRANSIENT_REDIRECT_AFTER_ACTIVATE_NOT_REGISTERED);
            if ($redirectState === TransientHandler::TRANSIENT_REDIRECT_AFTER_ACTIVATE_AWAITING_REDIRECT) {
                TransientHandler::set($this->getInitiator(), TransientHandler::TRANSIENT_REDIRECT_AFTER_ACTIVATE, TransientHandler::TRANSIENT_REDIRECT_AFTER_ACTIVATE_REDIRECTED);
                echo \sprintf('<meta http-equiv="refresh" content="0; URL=%s" />', \esc_url($this->getWelcomePageLink()));
            }
        }
    }
    /**
     * Register welcome page without menu entry.
     */
    public function admin_menu()
    {
        $slug = $this->getInitiator()->getPluginSlug();
        $data = \get_plugin_data($this->getInitiator()->getPluginFile());
        $title = $data['Name'];
        \add_submenu_page('admin.php', $title, $title, 'activate_plugins', $slug . self::PAGE_SUFFIX, [$this, 'welcome_page_output']);
    }
    /**
     * Create output for the welcome page. It does not use React because the interface
     * is not reactive.
     */
    public function welcome_page_output()
    {
        $keyFeaturesCount = \count($this->getInitiator()->getKeyFeatures());
        $ourPluginsOutput = $this->our_plugins_output();
        $string = '<div class="wrap about-wrap full-width-layout" data-slug="%slug">
    <h1>%title</h1>
    <p class="about-text">%subtitle</p>
    <div class="wp-badge" style="background-image: url(\'%logoUrl\');">' . \__('Version', 'devowl-wp-real-utils') . ' %version</div>

    <nav class="nav-tab-wrapper wp-clearfix">
        <a href="#" class="nav-tab nav-tab-active">' . \__('Info', 'devowl-wp-real-utils') . '</a>
        <a target="_blank" href="%supportLink" class="nav-tab">' . \__('Support', 'devowl-wp-real-utils') . '</a>
        <a target="_blank" href="%rateLink" class="nav-tab" style="%styleRateLink">' . \__('Rate plugin', 'devowl-wp-real-utils') . '</a>
    </nav>

    <div class="about-wrap-content">
    	<div class="feature-section has-1-columns column-links">
            %heroButton
            <h2>' . \_n('Key feature', 'Key features', $keyFeaturesCount, 'devowl-wp-real-utils') . '</h2>
    	</div>

		%featuresHtml

        %ourPluginsHeader
    </div>
</div>';
        $pluginData = \get_plugin_data($this->getInitiator()->getPluginFile());
        $heroButton = $this->getInitiator()->getHeroButton();
        $heroButton = isset($heroButton) ? \sprintf('<a href="%s" class="button button-primary button-hero" style="margin-top: 40px;"><strong>%s</strong></a>', \esc_url(\add_query_arg('feature', 'welcome-page', $heroButton[1])), $heroButton[0]) : '';
        $data = ['%slug' => $this->getInitiator()->getPluginSlug(), '%title' => $pluginData['Name'], '%version' => $pluginData['Version'], '%subtitle' => \str_replace('<cite>', \sprintf('<br /><cite>', Core::getInstance()->getBaseAssetsUrl('devowl.io-logo.svg')), $pluginData['Description']), '%logoUrl' => $this->getInitiator()->getAssetsUrl('logo.svg'), '%supportLink' => $this->getInitiator()->getSupportLink(), '%rateLink' => $this->getInitiator()->getRateLink(), '%styleRateLink' => $this->getInitiator()->getRateLink() === null ? 'display:none' : '', '%heroButton' => $heroButton, '%featuresHtml' => $this->transformKeyFeaturesHtml(), '%currentEmail' => \esc_attr(\get_userdata(\get_current_user_id())->user_email), '%ourPluginsHeader' => $ourPluginsOutput['header']];
        echo \str_replace(\array_keys($data), \array_values($data), $string);
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- string is escaped in transformKeyFeaturesHtml.
        echo $ourPluginsOutput['table'];
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- table is escaped in our_plugins_output.
    }
    /**
     * Display our plugins by using the native list table.
     *
     * @see https://github.com/WordPress/WordPress/blob/b9869da1575ad61ffef0ebc6330a7a7f80e5d77c/wp-admin/includes/plugin-install.php#L9
     * @see https://github.com/WordPress/WordPress/blob/b9869da1575ad61ffef0ebc6330a7a7f80e5d77c/wp-admin/includes/class-wp-plugin-install-list-table.php#L154
     */
    public function our_plugins_output()
    {
        // Fake query, because it is hardcoded from $_REQUEST
        $outputTable = '';
        $outputHeader = '';
        $_REQUEST['type'] = 'author';
        $_REQUEST['s'] = 'devowl';
        $_REQUEST['tab'] = 'search';
        $wp_list_table = \_get_list_table('WP_Plugin_Install_List_Table');
        $wp_list_table->order = 'DESC';
        $wp_list_table->orderby = 'last_updated';
        \add_filter('plugins_api_result', [$this, 'prepare_items'], 10, 3);
        $wp_list_table->prepare_items();
        \remove_filter('plugins_api_result', [$this, 'prepare_items'], 10, 3);
        if ($wp_list_table->has_items()) {
            $outputTable .= '<div class="wrap plugin-install-tab-featured" id="plugin-filter">';
            // Get output of table
            \ob_start();
            $wp_list_table->display();
            $outputTable .= \ob_get_contents();
            \ob_end_clean();
            $outputTable .= '</div>';
            $outputHeader .= \sprintf('<hr /><div class="feature-section has-1-columns column-links"><h2>%s</h2></div>', \__('Additional plugins by devowl.io', 'devowl-wp-real-utils'));
        }
        return ['table' => $outputTable, 'header' => $outputHeader];
    }
    /**
     * Filter and sort result from Plugin API call.
     *
     * @param object $res API response
     * @param string $action [query_plugins]
     * @param object $args [per_page, order_by, order]
     * @see https://wordpress.stackexchange.com/a/76644/83335
     */
    public function prepare_items($res, $action, $args)
    {
        if (\property_exists($res, 'plugins')) {
            $pluginDir = \constant('WP_PLUGIN_DIR') . '/';
            foreach ($res->plugins as $key => $plugin) {
                if (\strpos($plugin['description'], self::EXCLUDE_DESCRIPTION_CONTAINS)) {
                    unset($res->plugins[$key]);
                    continue;
                }
                // Remove already installed plugins
                if (\defined('DEVOWL_WP_DEV') && \constant('DEVOWL_WP_DEV')) {
                    // In dev mode, we want to see all plugins
                    continue;
                }
                $slug = $plugin['slug'];
                $fix = isset(self::PLUGIN_SLUG_FIXER[$slug]) ? self::PLUGIN_SLUG_FIXER[$slug] : null;
                $exists = \is_dir($pluginDir . $slug) || $fix !== null && \is_dir($pluginDir . $fix);
                if ($exists) {
                    unset($res->plugins[$key]);
                }
            }
            \uasort($res->plugins, function ($a, $b) {
                return \strnatcmp(\strtolower($b['last_updated']), \strtolower($a['last_updated']));
            });
            return $res;
        }
        return null;
    }
    /**
     * Get key features and transform them to key features HTML including rows' `div`.
     */
    protected function transformKeyFeaturesHtml()
    {
        $features = $this->getInitiator()->getKeyFeatures();
        $chunks = \array_chunk($features, 3);
        $result = '';
        foreach ($chunks as $chunk) {
            $result .= \sprintf('<div class="feature-section has-%d-columns is-fullwidth">%s</div>', \count($chunk), $this->transformChunkedKeyFeaturesHtml($chunk));
        }
        return $result;
    }
    /**
     * Transform given key features to key features HTML. This function does not return only the
     * columns, no row!
     *
     * @param array $features
     */
    protected function transformChunkedKeyFeaturesHtml($features)
    {
        $badgeTemplate = '<span style="margin: 0 5px 0 0;padding: 3px 10px; border-radius: 4px; background: %s; font-style: normal; color: white;">%s</span>';
        foreach ($features as $key => $feature) {
            // Show "Available in" badges (available_in)
            $availableIn = '';
            if (isset($feature['available_in'])) {
                $availableIn .= '<p class="description">' . \__('Available in', 'devowl-wp-real-utils') . ': ';
                foreach ($feature['available_in'] as $badge) {
                    $availableIn .= \sprintf($badgeTemplate, $badge[1], $badge[0]);
                }
                $availableIn .= '</p>';
            }
            // Show highlighting badge (highlight_badge)
            $highlightBadge = '';
            if (isset($feature['highlight_badge'])) {
                $highlightBadgeArr = $feature['highlight_badge'];
                $highlightBadge .= '<p class="description">' . \sprintf($badgeTemplate, $highlightBadgeArr[1], $highlightBadgeArr[0]) . $highlightBadgeArr[2] . '</p>';
            }
            // Generate HTML
            $features[$key] = \sprintf('<div class="column key-feature">
    <p style="height:%dpx"><img src="%s"/></p>
    <h3>%s</h3>
    <p>%s</p>
    %s
    %s
</div>', $this->getInitiator()->getWelcomePageImageHeight(), $feature['image'], $feature['title'], $feature['description'], $availableIn, $highlightBadge);
        }
        return \join('', $features);
    }
    /**
     * Get the welcome page link.
     */
    public function getWelcomePageLink()
    {
        return \admin_url('admin.php?page=' . $this->getInitiator()->getPluginSlug() . self::PAGE_SUFFIX);
    }
    /**
     * Get initiator.
     *
     * @return AbstractInitiator
     * @codeCoverageIgnore
     */
    public function getInitiator()
    {
        return $this->initiator;
    }
    /**
     * Checks if the current open page is the welcome page.
     */
    public function isCurrentPage()
    {
        return \is_admin() && isset($_GET['page']) && \sanitize_text_field(\wp_unslash($_GET['page'])) === $this->getInitiator()->getPluginSlug() . WelcomePage::PAGE_SUFFIX;
    }
    /**
     * Create instance.
     *
     * @param AbstractInitiator $initiator
     * @codeCoverageIgnore
     */
    public static function instance($initiator)
    {
        return new WelcomePage($initiator);
    }
}
