<?php
/**
 * Magic Link URL Generator and Verifier
 *
 * Generates HMAC-signed URLs for public transcript viewing without login.
 * Business owners receive these links in email notifications.
 *
 * @link       https://github.com/sitestaffr/sitestaffr-plugin
 * @since      1.2.0
 *
 * @package    SiteStaffr
 * @subpackage SiteStaffr/includes
 */

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

/**
 * Magic Link class for generating and verifying signed transcript URLs.
 *
 * Uses HMAC-SHA256 to sign call IDs, allowing secure public access
 * to conversation transcripts without WordPress authentication.
 *
 * @since      1.2.0
 * @package    SiteStaffr
 * @subpackage SiteStaffr/includes
 * @author     SiteStaffr
 */
class SiteStaffr_Magic_Link {

	/**
	 * Generate a signed URL for viewing a call transcript.
	 *
	 * Creates a URL with the call ID and an HMAC-SHA256 signature
	 * that can be verified without requiring WordPress login.
	 *
	 * @since  1.2.0
	 * @param  int    $call_id  The call record ID.
	 * @return string           Signed URL, or empty string if no secret is configured.
	 */
	public static function generate_url( $call_id ) {
		$call_id = absint( $call_id );

		if ( ! $call_id ) {
			return '';
		}

		$secret = self::get_secret();

		if ( ! $secret ) {
			return '';
		}

		$signature = hash_hmac( 'sha256', (string) $call_id, $secret );

		$url = add_query_arg(
			array(
				'sitestaffr_transcript' => $call_id,
				'sig'                   => $signature,
			),
			home_url( '/' )
		);

		return $url;
	}

	/**
	 * Verify an HMAC signature for a call ID.
	 *
	 * Uses timing-safe comparison to prevent timing attacks.
	 *
	 * @since  1.2.0
	 * @param  int    $call_id    The call record ID.
	 * @param  string $signature  The HMAC signature to verify.
	 * @return bool               True if signature is valid, false otherwise.
	 */
	public static function verify( $call_id, $signature ) {
		$call_id = absint( $call_id );

		if ( ! $call_id || empty( $signature ) ) {
			return false;
		}

		$secret = self::get_secret();

		if ( ! $secret ) {
			return false;
		}

		$expected = hash_hmac( 'sha256', (string) $call_id, $secret );

		return hash_equals( $expected, $signature );
	}

	/**
	 * Retrieve the HMAC signing secret from WordPress options.
	 *
	 * Checks per-site secret first, falls back to global secret.
	 * Does NOT auto-generate a secret if none exists.
	 *
	 * @since  1.2.0
	 * @return string  The secret key, or empty string if not configured.
	 */
	private static function get_secret() {
		$secret = get_option( 'sitestaffr_site_api_secret', '' );

		if ( ! empty( $secret ) ) {
			return $secret;
		}

		$secret = get_option( 'sitestaffr_api_secret', '' );

		if ( ! empty( $secret ) ) {
			return $secret;
		}

		return '';
	}
}
