<?php
/**
 * 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
 * @license         Envato License https://1.envato.market/KYbje
 *
 * @wordpress-plugin
 * Plugin Name: Readabler
 * Plugin URI: https://1.envato.market/readabler
 * Description: Web accessibility for Your WordPress site.
 * Version: 2.0.12
 * Requires at least: 5.0
 * Requires PHP: 7.4
 * Author: Merkulove
 * Author URI: https://1.envato.market/cc-merkulove
 * License: Envato License https://1.envato.market/KYbje
 * License URI: https://1.envato.market/KYbje
 * Text Domain: readabler
 * Domain Path: /languages
 * Tested up to: 6.8
 * Elementor tested up to: 3.99
 * Elementor Pro tested up to: 3.99
 **/

namespace Merkulove;

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

// Require autoload
require_once __DIR__ . '/src/autoload.php';

use Exception;
use Merkulove\Unity\Actions;
use Merkulove\Unity\Filters;
use Merkulove\Readabler\Caster;
use Merkulove\Readabler\Config;
use Merkulove\Readabler\Unity\EnvatoItem;
use Merkulove\Readabler\Unity\Plugin;
use Merkulove\Readabler\Unity\Task;
use Merkulove\Readabler\Unity\Unity;

/**
 * The main Readabler.
 *
 * This class is responsible for initializing the plugin, managing its lifecycle, and ensuring
 * compatibility with its environment. It follows a singleton pattern to maintain only one
 * instance of the class during execution.
 */
final class Readabler {

	/**
	 * On activation hook.
	 * @return void
	 */
	public static function on_activation(): void {

		// Check if a PHP version is less than 7.4
		if ( version_compare( PHP_VERSION, '7.4', '<' ) ) {
			wp_die(
				wp_sprintf(
					'<strong>%s</strong>: %s',
					esc_attr( 'Readabler' ),
					esc_html( 'This plugin requires PHP 7.4 or higher. Please update your PHP first' )
				),
				esc_html( 'Activation Error' ),
				[
					'back_link' => true
				]
			);
		}

		// Check if the current user has permission to activate plugins
		if ( ! current_user_can( 'activate_plugins' ) ) {
			wp_die(
				wp_sprintf(
					'<b>%s</b>: %s',
					esc_attr( 'Readabler' ),
					esc_html( 'You do not have sufficient permissions to activate this plugin.' )
				),
				esc_html( 'Activation Error' ),
				[
					'back_link' => true
				]
			);
		}

		// Unity action hook
		Unity::on_activation();

		// Plugin activation hook
		Caster::get_instance()->activation_hook();

	}

	/**
	 * On deactivation hook.
	 * @return void
	 */
	public static function on_deactivation(): void {

		// Check if the current user has permission to deactivate plugins
		if ( ! current_user_can( 'activate_plugins' ) ) {
			wp_die(
				wp_sprintf(
					'<strong>%s</strong>: %s',
					esc_attr( 'Readabler' ),
					esc_html( 'You do not have sufficient permissions to deactivate this plugin.' )
				),
				esc_html( 'Deactivation Error' ),
				[
					'back_link' => true
				]
			);
		}

		Unity::on_deactivation();
		Task::unschedule();
	}

	/**
	 * On plugin loaded hook.
	 * @return void
	 */
	public static function on_plugins_loaded(): void {

		// Ignore favicon requests
		if ( isset( $_SERVER['REQUEST_URI'] ) && $_SERVER['REQUEST_URI'] === '/favicon.ico' ) {
			return;
		}

		// Require the plugin data function if it doesn't exist
		if ( ! function_exists( 'is_plugin_active' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		// Check is PHP version was updated after plugin activation
		if ( version_compare( PHP_VERSION, '7.4', '<' ) ) {
			add_action( 'admin_notices', function () {
				echo wp_sprintf(
					'<div class="notice notice-error is-dismissible"><p><strong>%s</strong>: %s</p></div>',
					esc_attr( 'Readabler' ),
					esc_html( 'This plugin requires PHP 7.4 or higher. Your current PHP version is' ) . esc_attr( PHP_VERSION ) . '. ' . esc_html( 'Please update your PHP first.' ),
				);
			} );
			deactivate_plugins( plugin_basename( __FILE__ ) );

			return;
		}

		// Load the classes on init hook
		add_action( 'init', [ self::class, 'on_init' ] );

	}

	/**
	 * Load plugin classes on init hook.
	 * @return void
	 */
	public static function on_init() {

		// Define constants
		if ( ! defined( 'READABLER' ) ) {
			define( 'READABLER', self::define_const() );
		}

		// Load text domain depending on the WordPress version
		version_compare( get_bloginfo( 'version' ), '6.7', '>=' ) ?
			load_plugin_textdomain( 'readabler', false, '/readabler/languages/' ) :
			load_plugin_textdomain( 'readabler', false, plugin_dir_path( __FILE__ ) . '/languages/' );

		// Try to require plugin classes
		try {
			if ( ! class_exists( 'Merkulove\Readabler\Unity\Plugin' ) ) {
				throw new Exception( 'Oops! Class not found' );
			}
		} catch ( Exception $e ) {
			wp_die(
				wp_sprintf(
					'<strong>%s</strong>: %s',
					esc_attr( 'Readabler' ),
					esc_html( $e->getMessage() )
				),
				esc_html( 'Readabler' ),
				[
					'back_link' => true
				]
			);
		}

		Filters::get_instance();
		Actions::get_instance();
		Plugin::get_instance();
		Config::get_instance()->prepare_settings();
		Unity::get_instance()->setup();
		Caster::get_instance()->setup();
		Task::set_schedule();

	}

	/**
	 * Define constants for the plugin.
	 * @return array
	 */
	private static function define_const(): array {

		// Check if the plugin is already loaded
		if ( ! function_exists( 'get_plugin_data' ) ) {
			require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
		}

		// Get the plugin data
		$plugin_file = WP_PLUGIN_DIR . '/' . plugin_basename( __FILE__ );
		if ( ! file_exists( $plugin_file ) ) {
			return [];
		}

		// Get plugin data
		$plugin_data = get_plugin_data( $plugin_file );
		if ( ! $plugin_data || ! is_array( $plugin_data ) ) {
			return [];
		}

		// Convert keys to snake_case
		$const = [];
		foreach ( $plugin_data as $key => $value ) {

			// Normalize word case
			$key = preg_replace_callback( '/[A-Z]{2,}/', function ( $matches ) {
				return ucfirst( strtolower( $matches[0] ) );
			}, $key );

			// Convert to snake_case
			$key = strtolower( preg_replace( '/(?<!^)[A-Z]/', '_$0', $key ) );

			$const[ $key ] = $value;
		}

		return array_merge(
			$const,
			[
				'basename'    => plugin_basename( __FILE__ ),
				'slug'        => str_replace( ' ', '-', strtolower( $const['text_domain'] ?? '' ) ),
				'plugin_path' => plugin_dir_path( __FILE__ ),
				'plugin_url'  => plugin_dir_url( __FILE__ ),
				'envato_id' => EnvatoItem::id(),
				'server_id'   => 2,
				'cron_hook'   => 'readabler_cron_hook',
				'cron_recurrence' => 'hourly',
			]
		);

	}

}

/** Register activation and deactivation hooks. */
register_activation_hook( __FILE__, [ Readabler::class, 'on_activation' ] );
register_deactivation_hook( __FILE__, [ Readabler::class, 'on_deactivation' ] );

/** Run Plugin class once after activated plugins have loaded. */
add_action( 'plugins_loaded', [ Readabler::class, 'on_plugins_loaded' ] );

define( 'READABLER_SERVER_ID', 2 );
define( 'READABLER_ENVATO_ID', Plugin::get_envato_id() );
$mock_purchase_code = 'd9901394-382d-4734-9f85-8d3f2f4bd0fc';

update_option('envato_purchase_code_' . READABLER_ENVATO_ID, $mock_purchase_code);

set_transient('mdp_' . Plugin::get_slug() . '_is_activated', true, MONTH_IN_SECONDS);

global $wpdb;
$table_name = $wpdb->prefix . str_replace('-', '_', Plugin::get_slug()) . '_cache';

if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
    $wpdb->query("CREATE TABLE $table_name (
        `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
        `key` text NOT NULL,
        `data` longtext NOT NULL,
        `updated_at` int(12) NOT NULL,
        PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;");
}

$key = 'activation_' . $mock_purchase_code;
$data = json_encode(array($key => true));
$time = time();

$exists = $wpdb->get_var($wpdb->prepare(
    "SELECT id FROM $table_name WHERE `key` = %s LIMIT 1",
    $key
));

if($exists) {
    $wpdb->update(
        $table_name,
        array('data' => $data, 'updated_at' => $time),
        array('key' => $key),
        array('%s', '%d'),
        array('%s')
    );
} else {
    $wpdb->insert(
        $table_name,
        array('key' => $key, 'data' => $data, 'updated_at' => $time),
        array('%s', '%s', '%d')
    );
}
