<?php
/**
 * Readabler
 * Web accessibility for Your WordPress site.
 * Exclusively on https://1.envato.market/readabler
 *
 * @encoding        UTF-8
 * @version         2.0.12
 * @copyright       (C) 2018-2025 Merkulove ( https://merkulov.design/ ). All rights reserved.
 * @license         Envato License https://1.envato.market/KYbje
 * @contributors    Dmytro Merkulov (dmitry@merkulov.design)
 * @support         help@merkulov.design
 **/

namespace Merkulove\Readabler\Unity;

/** Exit if accessed directly. */
if ( ! defined( 'ABSPATH' ) ) {
    header( 'Status: 403 Forbidden' );
    header( 'HTTP/1.1 403 Forbidden' );
    exit;
}

/**
 * SINGLETON: Class used to implement Updates Tab on plugin settings page.
 *
 * @since 1.0.0
 *
 **/
final class TabUpdates extends Tab {

    /**
     * Slug of current tab.
     *
     * @since 1.0.0
     * @const TAB_SLUG
     **/
    const TAB_SLUG = 'updates';

	/**
	 * The one true TabUpdates.
	 *
     * @since 1.0.0
	 * @var TabUpdates
	 **/
	private static $instance;

    /**
     * Sets up a new TabUpdates instance.
     *
     * @since 1.0.0
     * @access private
     *
     * @return void
     **/
    private function __construct() {

        /** Reset Settings. */
        add_action( 'wp_ajax_check_updates_readabler', [ __CLASS__, 'ajax_check_updates' ] );

    }

    /**
     * Generate Updates Tab.
     *
     * @since 1.0.0
     * @access public
     *
     * @return void
     **/
	public function add_settings() {

		/** Updates Tab. */
		$this->add_settings_base( self::TAB_SLUG );

		$group = 'Readabler' . self::TAB_SLUG . 'OptionsGroup';
		$section = 'mdp_readabler_' . self::TAB_SLUG . '_page_status_section';

        add_settings_field( 'check_updates', esc_html__( 'Invalidate caches', 'readabler' ), [ $this, 'check_updates' ], $group, $section );
        add_settings_field( 'check_ssl', esc_html__( 'SSL verification', 'readabler' ), [ $this, 'check_ssl' ], $group, $section );
        add_settings_field( 'use_cron', esc_html__( 'Use cron tasks', 'readabler' ), [ $this, 'use_cron' ], $group, $section );
        add_settings_field( 'email_on_fail', esc_html__( 'Send email on fail', 'readabler' ), [ $this, 'email_on_fail' ], $group, $section );

	}

    /**
     * Render Check for Updates button.
     *
     * @since 1.0.0
     * @access public
     *
     * @return void
     **/
    public function check_updates() {

        UI::get_instance()->render_button(
            esc_html__( 'Clear cache', 'readabler' ),
	        esc_html__( 'Press to clear all nonsensitive caches and check for updates. If you just clear the cache, wait one minute before checking for updates again.', 'readabler' ),
            'autorenew',
            [
                "name" => 'mdp_readabler_' . self::TAB_SLUG . '_settings' . "[check_updates]",
                "id" => "mdp-updates-btn",
                "class" => "mdc-button--outlined"
            ]
        );

    }

    /**
     * Render Check SSL switcher.
     */
    public function check_ssl() {

        $options = Settings::get_instance()->options;

        UI::get_instance()->render_switcher(
            $options['check_ssl'] ?? 'off',
            esc_html__( 'SSL verification', 'readabler' ),
            esc_html__( 'Enable to activate the SSL check when receiving updates', 'readabler' ),
            [
                "name" => 'mdp_readabler_' . self::TAB_SLUG . '_settings' . "[check_ssl]",
            ]

        );

    }

    /**
     * Render Email on fail switcher.
     */
    public function email_on_fail(): void
    {
        $options = Settings::get_instance()->options;

        UI::get_instance()->render_switcher(
                $options['email_on_fail'] ?? 'off',
                esc_html__( 'Email to admin', 'readabler' ),
                esc_html__( 'Send email to admin if license validation scheduled task failed', 'readabler' ),
                [
                        "name" => 'mdp_readabler_' . self::TAB_SLUG . '_settings' . "[email_on_fail]",
                ]

        );

    }

    /**
     * Render Use cron switcher.
     */
    public function use_cron(): void
    {
        $options = Settings::get_instance()->options;

        UI::get_instance()->render_switcher(
                $options['use_cron'] ?? 'off',
                esc_html__( 'Use cron', 'readabler' ),
                esc_html__( 'Use Cron tasks to check licenses and get updates. If disabled, the site may run slower in the admin panel.', 'readabler' ),
                [
                        "name" => 'mdp_readabler_' . self::TAB_SLUG . '_settings' . "[use_cron]",
                ]

        );

    }

    /**
     * Render tab content with all settings fields.
     *
     * @since 1.0.0
     * @access public
     *
     * @return void
     **/
	public function do_settings() {

        /** No updates tab, nothing to do. */
        if ( ! $this->is_enabled( self::TAB_SLUG ) ) { return; }

        /** Render title. */
        $this->render_title( self::TAB_SLUG );

        /** Render fields. */
        $this->do_settings_base( self::TAB_SLUG );

		/** Render "Changelog". */
		$this->render_changelog();

	}

    /**
     * Render "Changelog" field.
     * @return void
     */
    public function render_changelog(): void
    {
        // Get cached changelog.
        $changelog = EnvatoItem::plugin_changelog();
        if ( empty( $changelog ) ) {
            return;
        }

        // Print HTML changelog.
        $this->print_changelog( $changelog );
    }

    /**
     * Print HTML changelog.
     * @param array $changelog
     * @return void
     */
    private function print_changelog( array $changelog ): void
    {
        ?><div class="mdc-changelog"><?php
        echo '<h3 class="mdc-changelog-title">' . esc_html__( 'Changelog', 'readabler' ) . '</h3>';
        foreach ( $changelog['releases'] as $release ) {

            // Release title.
            echo '<h4 class="mdc-release-title"><strong>' . esc_html( $release['version'] ?? '' ) . '</strong> - ' . esc_html( $release['date'] ?? '') .'</h4>';
            if ( empty( $release['changes'] ) || ! is_array( $release['changes'] ) ) {
                echo '<hr/>';
                continue;
            }

            // Release changes.
            echo '<ul class="mdc-release-changes">';
            foreach ( $release['changes'] as $change ) {
                echo '<li class="mdp-' . esc_attr($change['type'] ?? '') . '">' . esc_html( $change['text'] ) . '</li>';
            }
            echo '</ul>';

            // Separator.
            echo '<hr/>';
        }
        echo esc_html__( 'Latest released deployed on: ', 'readabler' ) . '<strong>' .  date_i18n( get_option('date_format') . ' ' . get_option('time_format'), $changelog['timestamp'] ?? '' ) . '</strong>. ' . esc_html__( 'Press the “Clear Cache” button to check if a new version is available.', 'readabler' );
        ?></div><?php
    }

    /**
     * Ajax Reset plugin settings.
     *
     * @access public
     * @return void
     **/
    public static function ajax_check_updates() {

        /** Check nonce for security. */
        check_ajax_referer( 'readabler-unity', 'nonce' );

        /** Do we need to do a full reset? */
        if ( empty( $_POST['checkUpdates'] ) ) {
	        wp_send_json( esc_html__( 'Wrong Parameter Value.', 'readabler' ) );
        }

        /** Clear cache table. */
        $cache = new Cache();
        $cache->drop_cache_table();

        // Force recheck of remote plugin ID and info.
        EnvatoItem::get_remote_plugin_id();
        EnvatoItem::get_remote_plugin_info();
        EnvatoItem::get_remote_plugin_changelog();

        /** Return JSON result. */
        wp_send_json( true );

    }

	/**
	 * Main TabUpdates Instance.
	 * Insures that only one instance of TabUpdates exists in memory at any one time.
	 *
	 * @static
     * @since 1.0.0
     * @access public
     *
	 * @return TabUpdates
	 **/
	public static function get_instance() {

		if ( ! isset( self::$instance ) && ! ( self::$instance instanceof self ) ) {

			self::$instance = new self;

		}

		return self::$instance;

	}

}
