<?php
declare( strict_types=1 );

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

/**
 * SFD License Call-Home Client
 *
 * Verifies this RC install against the SFD server at itoversight.ca.
 * Caches the result to avoid hammering the endpoint.
 */
final class RC_License_Client {

	/**
	 * How long a successful verification is cached (seconds).
	 */
	const CACHE_TTL = 43200; // 12 hours.

	/**
	 * How long a failed verification is cached (seconds).
	 */
	const CACHE_TTL_FAIL = 1800; // 30 minutes.

	/**
	 * SFD verify endpoint. Override via RC_SFD_VERIFY_URL constant.
	 */
	const DEFAULT_VERIFY_URL = 'https://itoversight.ca/wp-json/sfd/v1/verify';

	/**
	 * Product SKU this plugin reports as. Override via RC_SFD_PRODUCT_SKU constant.
	 */
	const DEFAULT_PRODUCT_SKU = 'RC-FULL';

	/**
	 * Run verification and return the result.
	 *
	 * @param bool $force_refresh Bypass cache.
	 * @return array { valid: bool, status: string, message: string, domain_match: bool }
	 */
	public static function verify( bool $force_refresh = false ): array {
		$cache_key = 'rc_sfd_license_check';

		if ( ! $force_refresh ) {
			$cached = get_transient( $cache_key );
			if ( is_array( $cached ) ) {
				return $cached;
			}
		}

		$key    = self::get_license_key();
		$domain = self::get_domain();
		$sku    = self::get_product_sku();

		if ( '' === $key ) {
			$result = array(
				'valid'        => false,
				'status'       => 'no_key',
				'message'      => 'No license key configured.',
				'domain_match' => false,
			);
			set_transient( $cache_key, $result, self::CACHE_TTL_FAIL );
			return $result;
		}

		$url = self::get_verify_url();
		$body = wp_json_encode(
			array(
				'license_key' => $key,
				'domain'      => $domain,
				'product_sku' => $sku,
			)
		);

		$response = wp_remote_post(
			$url,
			array(
				'timeout' => 30,
				'headers' => array( 'Content-Type' => 'application/json' ),
				'body'    => $body,
				'sslverify' => true,
			)
		);

		if ( is_wp_error( $response ) ) {
			$result = array(
				'valid'        => false,
				'status'       => 'http_error',
				'message'      => 'Could not contact license server: ' . $response->get_error_message(),
				'domain_match' => false,
			);
			set_transient( $cache_key, $result, self::CACHE_TTL_FAIL );
			return $result;
		}

		$code = wp_remote_retrieve_response_code( $response );
		$raw  = wp_remote_retrieve_body( $response );
		$json = json_decode( $raw, true );

		if ( ! is_array( $json ) ) {
			$result = array(
				'valid'        => false,
				'status'       => 'bad_response',
				'message'      => 'License server returned HTTP ' . $code . ' with unexpected response: ' . substr( $raw, 0, 200 ),
				'domain_match' => false,
			);
			set_transient( $cache_key, $result, self::CACHE_TTL_FAIL );
			return $result;
		}

		$result = array(
			'valid'        => (bool) ( $json['valid'] ?? false ),
			'status'       => sanitize_text_field( $json['status'] ?? 'unknown' ),
			'message'      => sanitize_text_field( $json['message'] ?? 'Unknown response.' ),
			'domain_match' => (bool) ( $json['domain_match'] ?? false ),
		);

		$ttl = $result['valid'] ? self::CACHE_TTL : self::CACHE_TTL_FAIL;
		set_transient( $cache_key, $result, $ttl );

		return $result;
	}

	/**
	 * Get the stored license key.
	 *
	 * Order of precedence:
	 * 1. RC_SFD_LICENSE_KEY constant.
	 * 2. RC_Build_Hash::LICENSE_KEY (baked into customer ZIPs).
	 * 3. rc_sfd_license_key option (manually entered in Settings).
	 *
	 * @return string
	 */
	public static function get_license_key(): string {
		if ( defined( 'RC_SFD_LICENSE_KEY' ) ) {
			return sanitize_text_field( RC_SFD_LICENSE_KEY );
		}
		if ( defined( 'RC_Build_Hash::LICENSE_KEY' ) && '' !== constant( 'RC_Build_Hash::LICENSE_KEY' ) ) {
			$key = constant( 'RC_Build_Hash::LICENSE_KEY' );
			if ( is_string( $key ) && '' !== $key ) {
				return sanitize_text_field( $key );
			}
		}
		$value = get_option( 'rc_sfd_license_key', '' );
		return is_string( $value ) ? sanitize_text_field( $value ) : '';
	}

	/**
	 * Store a license key.
	 *
	 * @param string $key License key.
	 * @return void
	 */
	public static function set_license_key( string $key ): void {
		update_option( 'rc_sfd_license_key', sanitize_text_field( $key ) );
		delete_transient( 'rc_sfd_license_check' );
	}

	/**
	 * Get the current site domain.
	 *
	 * @return string
	 */
	public static function get_domain(): string {
		if ( defined( 'RC_LICENSED_DOMAIN' ) && '' !== RC_LICENSED_DOMAIN ) {
			return strtolower( sanitize_text_field( RC_LICENSED_DOMAIN ) );
		}
		$host = wp_parse_url( home_url(), PHP_URL_HOST );
		return $host ? strtolower( sanitize_text_field( $host ) ) : '';
	}

	/**
	 * Get product SKU reported to SFD.
	 *
	 * @return string
	 */
	public static function get_product_sku(): string {
		if ( defined( 'RC_SFD_PRODUCT_SKU' ) ) {
			return strtoupper( sanitize_text_field( RC_SFD_PRODUCT_SKU ) );
		}
		return self::DEFAULT_PRODUCT_SKU;
	}

	/**
	 * Get the SFD verify endpoint URL.
	 *
	 * @return string
	 */
	public static function get_verify_url(): string {
		if ( defined( 'RC_SFD_VERIFY_URL' ) ) {
			return RC_SFD_VERIFY_URL;
		}
		return self::DEFAULT_VERIFY_URL;
	}

	/**
	 * Whether the install is currently licensed according to the last check.
	 *
	 * @return bool
	 */
	public static function is_licensed(): bool {
		$result = self::verify();
		return $result['valid'];
	}

	/**
	 * Clear cached verification result.
	 *
	 * @return void
	 */
	public static function clear_cache(): void {
		delete_transient( 'rc_sfd_license_check' );
	}
}
