<?php
/**
 * Token Service
 *
 * Handles generation and validation of magic link tokens for customer dashboard access.
 *
 * @since   PBOOKING_SINCE
 * @package Nemtly_Booking
 */

namespace NemtlyBooking\Services;

/**
 * Token Service class
 *
 * @since PBOOKING_SINCE
 */
class Token_Service {
    /**
     * Transient prefix for tokens
     *
     * @var string
     */
    private $transient_prefix = 'nemtly_auth_';
    /**
     * Token expiration in seconds (default 15 minutes)
     *
     * @var int
     */
    private $expiration = 900;

    /**
     * Generate a magic link token for an email
     *
     * @since PBOOKING_SINCE
     *
     * @param string $email User email address.
     *
     * @return string|false The generated token or false on failure.
     */
    public function generate_token( $email ) {
        if ( ! is_email( $email ) ) {
            return false;
        }
        // Generate a cryptographically secure random token signed with the site salt
        $random = bin2hex( random_bytes( 32 ) );
        $token  = hash_hmac( 'sha256', $random, wp_salt() );
        // Store email against the token in a transient
        $transient_key = $this->transient_prefix . $token;
        $set           = set_transient( $transient_key, $email, $this->expiration );
        if ( ! $set ) {
            return false;
        }
        return $token;
    }

    /**
     * Validate a token and retrieve the associated email
     *
     * @since PBOOKING_SINCE
     *
     * @param string $token The token to validate.
     *
     * @return string|false The email address if valid, false otherwise.
     */
    public function validate_token( $token ) {
        if ( empty( $token ) ) {
            return false;
        }
        $transient_key = $this->transient_prefix . $token;
        $email         = get_transient( $transient_key );
        if ( false === $email ) {
            return false;
        }
        return $email;
    }

    /**
     * Invalidate (delete) a token
     *
     * @since PBOOKING_SINCE
     *
     * @param string $token The token to invalidate.
     *
     * @return bool True on success, false on failure.
     */
    public function invalidate_token( $token ) {
        if ( empty( $token ) ) {
            return false;
        }
        $transient_key = $this->transient_prefix . $token;
        return delete_transient( $transient_key );
    }

    /**
     * Generate the full Magic Link URL
     *
     * @since PBOOKING_SINCE
     *
     * @param string $token The token.
     * @param string $page_url The URL of the dashboard page.
     *
     * @return string The magic link URL.
     */
    public function get_magic_link_url( $token, $page_url ) {
        return add_query_arg(
            [
                'nemtly_action' => 'login',
                'token'         => $token,
            ],
            $page_url
        );
    }
}
