<?php
/**
 * Postomatic utility methods for handling options and security.
 *
 * @package Postomatic
 */

namespace Postomatic;

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

/**
 * Class Utils.
 *
 * Contains utility methods for the Postomatic plugin.
 */
class Utils {

	/**
	 * Generates a secure cryptographic key.
	 *
	 * @param  int $length Length of the key to generate (default: 64).
	 * @return string The generated secure key.
	 */
	public static function generate_secure_key( $length = 64 ) {
		// Generate secure random bytes.
		$random_bytes = random_bytes( $length );

		// Convert bytes to a hexadecimal string.
		$secure_key = bin2hex( $random_bytes );

		// Return the secure key (it will be twice as long as $length).
		return substr( $secure_key, 0, $length );
	}

	/**
	 * Updates or adds the Postomatic code option.
	 *
	 * @param  string $value Option value to set.
	 * @return bool   True if option was updated, false otherwise.
	 */
	public static function update_or_add_code_option( $value ) {
		$option_name = Constants::OPTION_CODE;

		if ( false !== get_option( $option_name ) ) {
			return update_option( $option_name, $value );
		}

		return add_option( $option_name, $value );
	}

	/**
	 * Gets the Postomatic code option.
	 *
	 * @return mixed The option value or false if not exists.
	 */
	public static function get_code_option() {
		return get_option( Constants::OPTION_CODE );
	}

	/**
	 * Updates or adds the WordPress API secure key option.
	 *
	 * @param  string $value Option value to set.
	 * @return bool   True if option was updated, false otherwise.
	 */
	public static function update_or_add_wp_api_secure_key( $value ) {
		$option_name = Constants::OPTION_API_WP_SECURE_KEY;

		if ( false !== get_option( $option_name ) ) {
			return update_option( $option_name, $value );
		}

		return add_option( $option_name, $value );
	}

	/**
	 * Gets the WordPress API secure key option.
	 *
	 * @return mixed The option value or false if not exists.
	 */
	public static function get_wp_api_secure_key() {
		return get_option( Constants::OPTION_API_WP_SECURE_KEY );
	}

	/**
	 * Updates or adds the API service key option.
	 *
	 * @param  string $value Option value to set.
	 * @return bool   True if option was updated, false otherwise.
	 */
	public static function update_or_add_api_service_key( $value ) {
		$option_name = Constants::OPTION_API_SERVICE_KEY;

		if ( false !== get_option( $option_name ) ) {
			return update_option( $option_name, $value );
		}

		return add_option( $option_name, $value );
	}

	/**
	 * Gets the API service key option.
	 *
	 * @return mixed The option value or false if not exists.
	 */
	public static function get_api_service_key() {
		return get_option( Constants::OPTION_API_SERVICE_KEY );
	}

	/**
	 * Updates or adds the is_validating option.
	 *
	 * @param  string $value Option value to set.
	 * @return bool   True if option was updated, false otherwise.
	 */
	public static function update_or_add_is_validating( $value ) {
		$option_name = Constants::OPTION_API_IS_VALIDATING;

		if ( false !== get_option( $option_name ) ) {
			return update_option( $option_name, $value );
		}

		return add_option( $option_name, $value );
	}

	/**
	 * Gets the is_validating option.
	 *
	 * @return mixed The option value or false if not exists.
	 */
	public static function get_is_validating() {
		return get_option( Constants::OPTION_API_IS_VALIDATING );
	}

	/**
	 * Checks if a provided token matches the stored secure key.
	 *
	 * @param  string $token The token to validate.
	 * @return bool   True if token is valid, false otherwise.
	 */
	public static function check_authorization( $token ) {
		return self::get_wp_api_secure_key() === $token;
	}

	/**
	 * Saves a one-time code with the current timestamp.
	 *
	 * @param  string $code The code to save.
	 * @return void
	 */
	public static function save_one_time_code( $code ) {
		// Store the code as a string directly.
		update_option( Constants::OPTION_API_PER_POST_ONE_TIME_CODE, $code, false );
	}

	/**
	 * Checks if a one-time code exists.
	 *
	 * @param  string $code The code to check.
	 * @return bool   True if code exists, false otherwise.
	 */
	public static function check_one_time_code_exists( $code ) {
		$stored_code = get_option( Constants::OPTION_API_PER_POST_ONE_TIME_CODE, '' );

		// If stored code is a string, compare directly.
		if ( is_string( $stored_code ) ) {
			return $stored_code === $code;
		}

		// For backward compatibility, check if it's in an array.
		if ( is_array( $stored_code ) ) {
			return isset( $stored_code[ $code ] );
		}

		return false;
	}

	/**
	 * Gets and removes a one-time code.
	 *
	 * @param  string $code The code to get and remove.
	 * @return void
	 */
	public static function get_and_remove_one_time_code( $code ) {
		$stored_code = get_option( Constants::OPTION_API_PER_POST_ONE_TIME_CODE, '' );

		// If stored code is a string and matches the provided code, remove it.
		if ( is_string( $stored_code ) && $stored_code === $code ) {
			delete_option( Constants::OPTION_API_PER_POST_ONE_TIME_CODE );

			return;
		}

		// For backward compatibility, handle array format.
		if ( is_array( $stored_code ) ) {
			if ( isset( $stored_code[ $code ] ) ) {
				unset( $stored_code[ $code ] );
				update_option( Constants::OPTION_API_PER_POST_ONE_TIME_CODE, $stored_code, false );
			}
		}
	}

	/**
	 * Generates a unique, readable identifier for autopilot tasks.
	 *
	 * @return string A unique identifier that is a mix of characters and numbers.
	 */
	public static function generate_autopilot_identifier() {
		// Define character sets for the identifier.
		$chars   = 'ABCDEFGHJKLMNPQRSTUVWXYZ'; // Uppercase letters (excluding easily confused I and O).
		$numbers = '23456789'; // Numbers (excluding easily confused 0 and 1).

		// Generate a timestamp-based prefix to ensure uniqueness.
		$prefix = strtoupper( substr( uniqid(), -4 ) );

		// Generate 3 random characters.
		$random_chars = '';
		for ( $i = 0; $i < 3; $i++ ) {
			$random_chars .= $chars[ wp_rand( 0, strlen( $chars ) - 1 ) ];
		}

		// Generate 3 random numbers.
		$random_numbers = '';
		for ( $i = 0; $i < 3; $i++ ) {
			$random_numbers .= $numbers[ wp_rand( 0, strlen( $numbers ) - 1 ) ];
		}

		// Combine all parts with hyphens for readability.
		$identifier = $prefix . '-' . $random_chars . '-' . $random_numbers;

		return $identifier;
	}
}
