<?php
/**
 * This file is reponsible to manage addons for the plugin.
 *
 * @package Webdigit
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Manage addons.
 */
class WDGPT_Addons_Manager {

	/**
	 * The addons manager instance.
	 *
	 * @var WDGPT_Addons_Manager
	 */
	private static $instance = null;

	/**
	 * The addons url.
	 *
	 * @var string
	 */
	private $url = 'https://www.smartsearchwp.com/wp-content/addons.json';

	/**
	 * Constructor.
	 */
	private function __construct() {
	}

	/**
	 * Get the instance of the class.
	 *
	 * @return WDGPT_Addons_Manager
	 */
	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Retrieve the addons from the server.
	 *
	 * @return array|bool
	 */
	public function retrieve_addons() {
		/*
		Fix performance issue while controlling the addons licence*/
		// Vérifier d'abord si on a un cache transient
		$cached_addons = get_transient( 'wdgpt_addons_cache' );

		if ( false !== $cached_addons ) {
			return $cached_addons;
		}

		// Si pas de cache, faire l'appel API
		$response = wp_remote_get( $this->url );
		if ( is_wp_error( $response ) ) {
			if ( WDGPT_DEBUG_MODE ) {
				WDGPT_Error_Logs::wdgpt_log_error( 'retrieve_addons: API error ' . $response->get_error_message(), 200, 'install_addon' );
			}
			return false;
		}
		$body   = wp_remote_retrieve_body( $response );
		$addons = json_decode( $body, true );

		if ( $addons ) {
			// Mettre le résultat dans le cache pendant 12 heures
			set_transient( 'wdgpt_addons_cache', $addons, 12 * HOUR_IN_SECONDS );
		}

		return $addons;
	}

	/**
	 * Retrieve the specific addon from the server.
	 *
	 * @param string $id The addon's id.
	 *
	 * @return array|bool
	 */
	public function retrieve_addon( $id ) {
		$addons = $this->retrieve_addons();
		if ( ! is_array( $addons ) ) {
			return false;
		}
		foreach ( $addons as $addon ) {
			if ( isset( $addon['id'] ) && (int) $addon['id'] === (int) $id ) {
				return $addon;
			}
		}
		return false;
	}

	/**
	 * Show the addon's details.
	 *
	 * @param array $addon The addon's details.
	 *
	 * @return void
	 */
	public function show_details( $addon ) {
		$required_version = $addon['required_version'];
		$current_version  = WDGPT_CHATBOT_VERSION;
		$required_version = version_compare( $current_version, $required_version, '>=' );
		if ( ! $required_version ) {
			?>
			<p class="wdgpt-addons-catalog-warning">
				<i class="fas fa-exclamation-triangle"></i>
				<?php
				printf(
					/* translators: %s: required version of the plugin */
					esc_html( __( 'This addon will require at least version %s of the plugin to function.', 'webdigit-chatbot' ) ),
					esc_html( $addon['required_version'] )
				);
				?>
			</p>
			<?php
		}
	}

	/**
	 * Install an addon on the website.
	 *
	 * @param array  $addon The addon to install.
	 * @param string $action The action to perform on the addon.
	 *
	 * @return bool True if the addon was installed, false otherwise.
	 */
	public function install_addon( $addon, $action = 'install' ) {
		$id              = isset( $addon['id'] ) ? $addon['id'] : 'n/a';
		$activation_slug = isset( $addon['activation_slug'] ) ? $addon['activation_slug'] : 'n/a';
		$action_query    = '';
		switch ( $action ) {
			case 'install':
				$action_query = 'addon_installed';
				break;
			case 'update':
				$action_query = 'addon_updated';
				break;
			default:
				// Les seules actions possibles sont 'install' et 'update'
				// Si nous arrivons ici, c'est une erreur inattendue
				$action_query = '';
				break;
		}
		$id              = $addon['id'];
		$activation_slug = $addon['activation_slug'];

		$url = site_url();
		$url = str_replace( array( 'http://', 'https://' ), '', $url );

		$license_capabilities = WDGPT_License_Manager::instance()->get_license_capabilities();
		try {
			if ( $addon['free'] ) {
				if ( $license_capabilities['premium'] ) {
					$license_key = WDGPT_License_Manager::instance()->get_license_key( 'premium' )['license_key'];
				} else {
					$license_key = WDGPT_License_Manager::instance()->get_license_key( 'free' )['license_key'];
				}
			} else {
				$license_key = WDGPT_License_Manager::instance()->get_license_key( 'premium' )['license_key'];
			}
		} catch ( Exception $e ) {
			WDGPT_Error_Logs::wdgpt_log_error( 'Addon install: license exception | ' . $e->getMessage(), 200, 'addon_install_error' );
			return false;
		}

		$source = 'https://www.smartsearchwp.com/wp-json/sswp/addon/download?id=' . $id . '&license=' . $license_key . '&url=' . $url;

		$response = wp_remote_get( $source );
		if ( is_wp_error( $response ) ) {
			WDGPT_Error_Logs::wdgpt_log_error( 'Addon install: download failed | ' . $response->get_error_message(), 200, 'addon_install_error' );
			return false;
		}

		$response_code = wp_remote_retrieve_response_code( $response );
		$body          = wp_remote_retrieve_body( $response );

		if ( 403 === (int) $response_code || 404 === (int) $response_code ) {
			WDGPT_Error_Logs::wdgpt_log_error(
				sprintf( 'Addon install: download refused (HTTP %d) | %s', $response_code, is_string( $body ) && strlen( $body ) < 500 ? $body : wp_remote_retrieve_response_message( $response ) ),
				200,
				'addon_install_error'
			);
			if ( 403 === (int) $response_code ) {
				delete_transient( 'wdgpt_license_transient' );
			}
			return false;
		}

		if ( strpos( $body, 'license key is expired' ) !== false ) {
			WDGPT_Error_Logs::wdgpt_log_error( 'Addon install: license key is expired', 200, 'addon_install_error' );
			delete_transient( 'wdgpt_license_transient' );
			return false;
		}

		if ( ! class_exists( 'Plugin_Upgrader', false ) ) {
			require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
		}

		$upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() );

		if ( 'update' === $action ) {
			delete_plugins( array( $activation_slug ) );
		}

		$result = $upgrader->install( $source );

		if ( ! $result || is_wp_error( $result ) ) {
			$msg = is_wp_error( $result ) ? $result->get_error_message() : 'unknown';
			WDGPT_Error_Logs::wdgpt_log_error( 'Addon install: Plugin_Upgrader failed | ' . $msg, 200, 'addon_install_error' );
			return false;
		}

		$result = activate_plugin( $activation_slug );
		if ( is_wp_error( $result ) ) {
			WDGPT_Error_Logs::wdgpt_log_error( 'Addon install: activation failed | slug=' . $activation_slug . ' | ' . $result->get_error_message(), 200, 'addon_install_error' );
			return false;
		}

		return true;
	}

	/**
	 * Activate an addon on the website.
	 *
	 * @param array $addon The addon to activate.
	 *
	 * @return bool True if the addon was activated, false otherwise.
	 */
	public function activate_addon( $addon ) {
		if ( file_exists( WP_PLUGIN_DIR . '/' . $addon['activation_slug'] ) ) {
			activate_plugin( $addon['activation_slug'] );
			return true;
		}
		return false;
	}

	/**
	 * Deactivate an addon from the website.
	 *
	 * @param array $addon The addon to deactivate.
	 *
	 * @return bool True if the addon was deactivated, false otherwise.
	 */
	public function deactivate_addon( $addon ) {
		if ( file_exists( WP_PLUGIN_DIR . '/' . $addon['activation_slug'] ) ) {
			deactivate_plugins( $addon['activation_slug'] );
			return true;
		}
		return false;
	}

	/**
	 * Uninstall an addon from the website.
	 *
	 * @param array $addon The addon to uninstall.
	 *
	 * @return bool True if the addon was uninstalled, false otherwise.
	 */
	public function uninstall_addon( $addon ) {
		require_once ABSPATH . 'wp-admin/includes/plugin.php';
		$this->deactivate_addon( $addon );
		$activation_slug = $addon['activation_slug'];
		$result          = delete_plugins( array( $activation_slug ) );
		if ( ! $result || is_wp_error( $result ) ) {
			return false;
		}
		return true;
	}
}
