<?php
/**
 * The file that defines the license manager for Pluginer Premium.
 *
 * This class handles license activation, validation, and deactivation
 * through a REST API interface.
 *
 * @link  https://codingfix.com
 * @since 1.0.0
 *
 * @package    Instalist
 * @subpackage Instalist/includes
 * @author     Marco Gasi <
 */

/**
 * Pluginer_License_Manager
 */
class Pluginer_License_Manager {


	// Costanti.
	const OPTION_NAME    = 'pluginer_license_data';
	const PLUGIN_SLUG    = 'pluginer-premium';
	const API_NAMESPACE  = 'pluginer-license/v1';
	const REMOTE_API_URL = 'https://codingfix.com/wp-json/cfx-license-manager/v1/';
	const CRON_HOOK      = 'pluginer_license_cron_hook';

	// -----------------------------
	// License Data
	// -----------------------------

	/**
	 * Recupera i dati della licenza dal database e li valida con il server remoto.
	 *
	 * @return array Dati della licenza.
	 */
	public static function get_license_data() {
		$local = get_option(
			self::OPTION_NAME,
			array(
				'email'   => '',
				'key'     => '',
				'status'  => '',
				'expires' => '',
			)
		);

		// Se non ci sono email o key, ritorna semplicemente ciò che c'è.
		if ( empty( $local['email'] ) || empty( $local['key'] ) ) {
			return $local;
		}

		// Non chiamiamo più la funzione remota qui: get_license_data serve solo per leggere i dati locali.
		// Lo status rimane quello salvato.
		$local['status']  = $local['status'] ?? '';
		$local['expires'] = $local['expires'] ?? '';

		return $local;
	}

	/**
	 * Recupera il namespace API.
	 *
	 * @return string Namespace API.
	 */
	public static function get_api_namespace() {
		return self::API_NAMESPACE;
	}

	/**
	 * Recupera l'url dell'API.
	 *
	 * @return string Namespace API.
	 */
	public static function get_api_url() {
		return self::REMOTE_API_URL;
	}

	/**
	 * Aggiorna i dati della licenza nel database.
	 *
	 * @param array $data Dati della licenza da aggiornare.
	 */
	public static function update_license_data( $data ) {
		$current = self::get_license_data();
		$updated = array_merge( $current, $data );

		$updated = array(
			'email'   => isset( $updated['email'] ) ? sanitize_email( $updated['email'] ) : '',
			'key'     => isset( $updated['key'] ) ? sanitize_text_field( $updated['key'] ) : '',
			'status'  => isset( $updated['status'] ) ? sanitize_text_field( $updated['status'] ) : 'inactive',
			'expires' => isset( $updated['expires'] ) && strtotime( $updated['expires'] )
			? sanitize_text_field( $updated['expires'] )
			: '',
		);

		update_option( self::OPTION_NAME, $updated );
	}

	/**
	 * Genera un identificatore unico per il sito (dominio + path).
	 *
	 * @return string Identificatore unico del sito.
	 */
	public static function get_site_identifier() {
		$parts  = wp_parse_url( home_url() );
		$domain = $parts['host'] ?? '';
		$path   = isset( $parts['path'] ) ? rtrim( $parts['path'], '/' ) : '';
		return strtolower( $domain . $path );
	}

	// -----------------------------
	// Remote API
	// -----------------------------

	/**
	 * Effettua una chiamata all'API remota per la gestione delle licenze.
	 *
	 * @param  string $endpoint Endpoint dell'API.
	 * @param  array  $payload  Dati da inviare nell'API.
	 * @return array Risposta dell'API.
	 */
	private static function call_remote_api( $endpoint, $payload = array() ) {
		$url = self::REMOTE_API_URL . ltrim( $endpoint, '/' );

		$response = wp_remote_post(
			$url,
			array(
				'timeout' => 10,
				'headers' => array( 'Content-Type' => 'application/json' ),
				'body'    => wp_json_encode(
					array_merge(
						$payload,
						array(
							'domain' => self::get_site_identifier(),
						)
					)
				),
			)
		);

		if ( is_wp_error( $response ) ) {
			return array(
				'valid'   => false,
				'message' => 'Errore di connessione al server licenze.',
			);
		}

		$data = json_decode( wp_remote_retrieve_body( $response ), true );
		if ( ! is_array( $data ) ) {
			return array(
				'valid'   => false,
				'message' => 'Risposta non valida dal server licenze.',
			);
		}
		return $data;
	}

	/**
	 * Valida la licenza con il server remoto.
	 *
	 * @param  string $email  Email associata alla licenza.
	 * @param  string $key    Chiave della licenza.
	 * @param  string $domain Dominio del sito (opzionale).
	 * @return array Risposta del server remoto.
	 */
	public static function validate_remote_license( $email, $key, $domain = '' ) {

		$email = sanitize_email( $email );
		$key   = sanitize_text_field( $key );
		if ( empty( $email ) || empty( $key ) ) {
			return array(
				'valid'   => false,
				'message' => 'Email or license key missing.',
			);
		}

		// Se non abbiamo dominio, non chiamiamo il server remoto.
		if ( empty( $domain ) ) {
			return array(
				'valid'   => false,
				'message' => 'No domain provided, skipping remote validation.',
			);
		}

		$payload = array(
			'email'       => $email,
			'license_key' => $key,
			'domain'      => $domain,
		);

		$url = self::REMOTE_API_URL . 'validate';

		$response = wp_remote_post(
			$url,
			array(
				'timeout' => 10,
				'headers' => array( 'Content-Type' => 'application/json' ),
				'body'    => wp_json_encode( $payload ),
			)
		);

		if ( is_wp_error( $response ) ) {
			return array(
				'valid'   => false,
				'message' => 'Errore di connessione al server licenze.',
			);
		}

		$data = json_decode( wp_remote_retrieve_body( $response ), true );

		return $data;
	}


	// -----------------------------
	// REST API
	// -----------------------------

	/**
	 * Registra le rotte REST per la gestione delle licenze.
	 */
	public static function register_routes() {
		register_rest_route(
			self::API_NAMESPACE,
			'/status',
			array(
				'methods'             => 'GET',
				'callback'            => array( __CLASS__, 'rest_get_status' ),
				'permission_callback' => array( __CLASS__, 'permissions_check' ),
			)
		);

		register_rest_route(
			self::API_NAMESPACE,
			'/activate',
			array(
				'methods'             => 'POST',
				'callback'            => array( __CLASS__, 'rest_activate' ),
				'permission_callback' => array( __CLASS__, 'permissions_check' ),
			)
		);

		register_rest_route(
			self::API_NAMESPACE,
			'/deactivate',
			array(
				'methods'             => 'POST',
				'callback'            => array( __CLASS__, 'rest_deactivate' ),
				'permission_callback' => array( __CLASS__, 'permissions_check' ),
			)
		);

		register_rest_route(
			self::API_NAMESPACE,
			'/validate',
			array(
				'methods'             => 'POST',
				'callback'            => array( __CLASS__, 'rest_validate' ),
				'permission_callback' => array( __CLASS__, 'permissions_check' ),
			)
		);
	}

	/**
	 * Controllo permessi base: solo admin.
	 */
	public static function permissions_check() {
		return current_user_can( 'manage_options' );
	}

	/**
	 * Recupera i dati della licenza salvati in locale.
	 */
	public static function rest_get_status() {
		return rest_ensure_response( self::get_license_data() );
	}

	/**
	 * Valida la licenza con il server remoto e aggiorna lo stato locale.
	 *
	 * @return array Risposta del server remoto.
	 */
	private static function do_validate_license(): array {
		$data = self::get_license_data();
		if ( empty( $data['email'] ) || empty( $data['key'] ) ) {
			return rest_ensure_response(
				array(
					'status'  => 'inactive',
					'message' => 'Nessuna licenza impostata.',
				)
			);
		}

		$result = self::call_remote_api(
			'validate',
			array(
				'email'       => $data['email'],
				'license_key' => $data['key'],
			)
		);

		if ( ! empty( $result['valid'] ) && true === $result['valid'] ) {
			self::update_license_data(
				array(
					'status'  => 'active',
					'expires' => $result['expires'] ?? $data['expires'],
				)
			);
			return rest_ensure_response(
				array(
					'status'  => 'active',
					'message' => 'Licenza valida.',
				)
			);
		}

		self::update_license_data(
			array(
				'status' => 'inactive',
			)
		);
		return rest_ensure_response(
			array(
				'status'  => 'inactive',
				'message' => $result['message'] ?? 'Licenza non valida.',
			)
		);
	}

	/**
	 * Attiva la licenza chiamando l'API remota e aggiornando i dati locali.
	 *
	 * @param WP_REST_Request $request La richiesta REST.
	 */
	public static function rest_activate( WP_REST_Request $request ) {
		$email = sanitize_email( $request->get_param( 'email' ) );
		$key   = sanitize_text_field( $request->get_param( 'license_key' ) );
		if ( empty( $email ) || ! is_email( $email ) ) {
			return new WP_Error( 'invalid_email', 'Email non valida.', array( 'status' => 400 ) );
		}
		if ( empty( $key ) ) {
			return new WP_Error( 'invalid_key', 'License key mancante.', array( 'status' => 400 ) );
		}

		$result = self::call_remote_api(
			'activate',
			array(
				'email'       => $email,
				'license_key' => $key,
			)
		);

		if ( ! empty( $result['valid'] ) && true === $result['valid'] ) {
			self::update_license_data(
				array(
					'email'   => $email,
					'key'     => $key,
					'status'  => 'active',
					'expires' => $result['expires'] ?? '',
				)
			);

			return rest_ensure_response(
				array(
					'status'  => 'active',
					'message' => 'License key activated.',
				)
			);
		}

		self::update_license_data(
			array(
				'email'   => $email,
				'key'     => $key,
				'status'  => 'inactive',
				'expires' => '',
			)
		);

		return rest_ensure_response(
			array(
				'status'  => 'inactive',
				'message' => $result['message'] ?? 'Invalid license key.',
			)
		);
	}

	/**
	 * Disattiva la licenza locale.
	 */
	public static function rest_deactivate() {
		self::update_license_data(
			array(
				'email'   => '',
				'key'     => '',
				'status'  => 'inactive',
				'expires' => '',
			)
		);
		return rest_ensure_response(
			array(
				'status'  => 'deactivated',
				'message' => 'Licenza disattivata.',
			)
		);
	}

	/**
	 * Valida la licenza locale con il server remoto.
	 */
	public static function rest_validate() {
		return rest_ensure_response( self::do_validate_license() );
	}

	// -----------------------------
	// Cron
	// -----------------------------

	/**
	 * Pianifica il controllo giornaliero della licenza.
	 */
	public static function schedule_cron() {
		if ( ! wp_next_scheduled( self::CRON_HOOK ) ) {
			wp_schedule_event( time(), 'daily', self::CRON_HOOK );
		}
	}

	/**
	 * Esegue la validazione della licenza tramite cron.
	 */
	public static function cron_validate_license() {
		self::do_validate_license();
	}

	/**
	 * Controlla se la licenza è attiva.
	 *
	 * @return bool True se la licenza è attiva, false altrimenti.
	 */
	public static function is_license_active() {
		$data = self::get_license_data();
		return ( isset( $data['status'] ) && 'active' === $data['status'] );
	}

	/**
	 * Unschedule cron on plugin deactivation
	 */
	public static function unschedule_cron() {
		$timestamp = wp_next_scheduled( self::CRON_HOOK );
		if ( $timestamp ) {
			wp_unschedule_event( $timestamp, self::CRON_HOOK );
		}
	}
}
