<?php
/**
 * Postomatic Plugin - Code Manager Class.
 *
 *   PHP Version 5.6
 *
 * @package  Postomatic
 * @category Plugin
 * @license  GPL-2.0-or-later https://www.gnu.org/licenses/gpl-2.0.html
 * @link     https://buildomatics.com/postomatics
 * @since    1.0.0
 * @requires PHP >= 8.0
 */

namespace Postomatic;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Codemanager Class.
 *
 * Manages the storage, validation, and removal of one-time authorization codes.
 *
 * @category Plugin
 * @license  GPL-2.0-or-later https://www.gnu.org/licenses/gpl-2.0.html
 * @link     https://buildomatics.com/postomatics
 * @since    1.0.0
 */
class Codemanager {

	/**
	 * The option name for storing one-time codes.
	 *
	 * @var string
	 */
	private $option_name = Constants::OPTION_API_PER_POST_ONE_TIME_CODE;

	/**
	 * Add a new code to the storage.
	 *
	 * @param string $new_code The code to store.
	 *
	 * @return void
	 */
	public function add_codes( $new_code ) {
		$this->update_codes( $this->sanitize_code( $new_code ) );
	}

	/**
	 * Check if a code exists.
	 *
	 * @param string $code The code to check.
	 *
	 * @return bool
	 */
	public function code_exists( $code ) {
		$stored_code = $this->get_code();

		return $stored_code === $this->sanitize_code( $code );
	}

	/**
	 * Delete a specific code.
	 *
	 * @param string $code The code to delete.
	 *
	 * @return bool True if deleted, false if not found.
	 */
	public function delete_code( $code ) {
		$stored_code    = $this->get_code();
		$sanitized_code = $this->sanitize_code( $code );

		if ( $stored_code === $sanitized_code ) {
			delete_option( $this->option_name );

			return true;
		}

		return false;
	}

	/**
	 * Get all stored codes.
	 *
	 * @return mixed The stored code(s).
	 */
	private function get_code() {
		$option_value = get_option( $this->option_name, '' );

		return $option_value;
	}

	/**
	 * Update the codes in database.
	 *
	 * @param mixed $code The code(s) to update.
	 *
	 * @return void
	 */
	public function update_codes( $code ) {
		// If we have an array with one element, just store the element as a string.
		update_option( $this->option_name, $code );
	}

	/**
	 * Sanitize code input.
	 *
	 * @param string $code The code to sanitize.
	 *
	 * @return string
	 */
	private function sanitize_code( $code ) {
		// Sanitize the code to prevent security issues.
		return sanitize_text_field( $code );
	}

	/**
	 * Generate a one-time code using API key and current time.
	 *
	 * @return string Generated one-time code.
	 */
	public function generate_one_time_code(): string {
		// Get the API key.
		$api_key = Utils::get_api_service_key();

		// If API key is not available, generate a secure random key.
		if ( empty( $api_key ) ) {
			$api_key = wp_generate_password( 32, true, true );
		}

		// Get current time as a salt.
		$time_salt = time();

		// Combine API key and time salt.
		$base_string = $api_key . '|' . $time_salt . '|' . wp_rand();

		// Generate a hash.
		$hash = md5( $base_string );

		// Format the hash into a readable code (similar to the JS implementation).
		$parts = array(
			substr( $hash, 0, 8 ),
			substr( $hash, 8, 8 ),
			substr( $hash, 16, 8 ),
			substr( $hash, 24, 8 ),
		);

		return implode( '-', $parts );
	}
}
