<?php
/**
 * PeachPay PayPal Credentials Manager.
 *
 * Handles secure storage and retrieval of merchant's PayPal API credentials
 * (client_id, client_secret). Client secret is encrypted at rest.
 *
 * @package PeachPay
 */

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

/**
 * Manages PayPal API credentials for manual (direct) integration.
 */
final class PeachPay_PayPal_Credentials {

	/**
	 * Option key for storing credentials (same as legacy for backward compatibility).
	 */
	const OPTION_KEY = 'peachpay_paypal_connect';

	/**
	 * Prefix for encrypted values (allows reading legacy plain values).
	 */
	const ENCRYPTED_PREFIX = 'enc:';

	/**
	 * Encryption method.
	 */
	const ENCRYPTION_METHOD = 'aes-256-cbc';

	/**
	 * Gets the encryption key derived from WordPress salts.
	 *
	 * @return string The encryption key.
	 */
	private static function get_encryption_key() {
		$salt = defined( 'LOGGED_IN_SALT' ) ? LOGGED_IN_SALT : 'peachpay-paypal-default-salt';
		return hash( 'sha256', $salt, true );
	}

	/**
	 * Encrypts a value.
	 *
	 * @param string $value The value to encrypt.
	 * @return string The encrypted value with prefix (base64 encoded).
	 */
	private static function encrypt( $value ) {
		if ( empty( $value ) ) {
			return '';
		}

		$iv        = openssl_random_pseudo_bytes( openssl_cipher_iv_length( self::ENCRYPTION_METHOD ) );
		$encrypted = openssl_encrypt( $value, self::ENCRYPTION_METHOD, self::get_encryption_key(), 0, $iv );

		return self::ENCRYPTED_PREFIX . base64_encode( $iv . $encrypted ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
	}

	/**
	 * Decrypts a value. If not prefixed with ENCRYPTED_PREFIX, returns as-is (legacy plain).
	 *
	 * @param string $value The stored value (encrypted with prefix or plain).
	 * @return string The decrypted value.
	 */
	private static function decrypt( $value ) {
		if ( empty( $value ) ) {
			return '';
		}

		if ( strpos( $value, self::ENCRYPTED_PREFIX ) !== 0 ) {
			return $value;
		}

		$data      = base64_decode( substr( $value, strlen( self::ENCRYPTED_PREFIX ) ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
		$iv_length = openssl_cipher_iv_length( self::ENCRYPTION_METHOD );

		if ( false === $data || strlen( $data ) < $iv_length ) {
			return '';
		}

		$iv        = substr( $data, 0, $iv_length );
		$encrypted = substr( $data, $iv_length );
		$decrypted = openssl_decrypt( $encrypted, self::ENCRYPTION_METHOD, self::get_encryption_key(), 0, $iv );

		return false !== $decrypted ? $decrypted : '';
	}

	/**
	 * Gets raw credentials from options (client_secret may be encrypted).
	 *
	 * @return array The raw credentials array.
	 */
	private static function get_raw_credentials() {
		return get_option( self::OPTION_KEY, array() );
	}

	/**
	 * Checks if PayPal manual credentials are configured.
	 *
	 * @return bool True if client_id and client_secret are present.
	 */
	public static function is_configured() {
		$raw = self::get_raw_credentials();
		return ! empty( $raw['client_id'] ) && ! empty( $raw['client_secret'] );
	}

	/**
	 * Gets the client ID.
	 *
	 * @return string The client ID.
	 */
	public static function get_client_id() {
		$raw = self::get_raw_credentials();
		return isset( $raw['client_id'] ) ? $raw['client_id'] : '';
	}

	/**
	 * Gets the client secret (decrypted if stored encrypted).
	 *
	 * @return string The client secret.
	 */
	public static function get_client_secret() {
		$raw = self::get_raw_credentials();
		if ( ! isset( $raw['client_secret'] ) ) {
			return '';
		}
		return self::decrypt( $raw['client_secret'] );
	}

	/**
	 * Gets the merchant ID.
	 *
	 * @return string The merchant ID.
	 */
	public static function get_merchant_id() {
		$raw = self::get_raw_credentials();
		return isset( $raw['merchant_id'] ) ? trim( (string) $raw['merchant_id'] ) : '';
	}

	/**
	 * Gets all credentials for use by Integration (e.g. get_manual_credentials).
	 * client_secret is returned decrypted.
	 *
	 * @return array Keys: client_id, client_secret, merchant_id, connected_at.
	 */
	public static function get_all() {
		$raw = self::get_raw_credentials();
		return array(
			'client_id'     => isset( $raw['client_id'] ) ? $raw['client_id'] : '',
			'client_secret' => self::get_client_secret(),
			'merchant_id'   => self::get_merchant_id(),
			'connected_at'  => isset( $raw['connected_at'] ) ? $raw['connected_at'] : '',
		);
	}

	/**
	 * Saves PayPal credentials. Validates with PayPal OAuth first; encrypts client_secret at rest.
	 *
	 * @param array $credentials Keys: client_id, client_secret, merchant_id (optional).
	 * @return array Result with 'success' and 'message' keys.
	 */
	public static function save_credentials( $credentials ) {
		$client_id     = isset( $credentials['client_id'] ) ? trim( (string) $credentials['client_id'] ) : '';
		$client_secret = isset( $credentials['client_secret'] ) ? $credentials['client_secret'] : '';
		$merchant_id   = isset( $credentials['merchant_id'] ) ? trim( (string) $credentials['merchant_id'] ) : '';

		if ( empty( $client_id ) || empty( $client_secret ) ) {
			return array(
				'success' => false,
				'message' => __( 'Both Client ID and Client Secret are required.', 'peachpay-for-woocommerce' ),
			);
		}

		if ( ! function_exists( 'peachpay_paypal_validate_credentials' ) ) {
			return array(
				'success' => false,
				'message' => __( 'PayPal validation is not available.', 'peachpay-for-woocommerce' ),
			);
		}

		$validation = peachpay_paypal_validate_credentials( $client_id, $client_secret );
		if ( ! $validation['success'] ) {
			return array(
				'success' => false,
				'message' => $validation['message'],
			);
		}

		$stored = array(
			'client_id'     => $client_id,
			'client_secret' => self::encrypt( $client_secret ),
			'merchant_id'   => $merchant_id,
			'connected_at'  => current_time( 'mysql' ),
		);

		update_option( self::OPTION_KEY, $stored );

		if ( function_exists( 'delete_transient' ) ) {
			delete_transient( 'peachpay_paypal_access_token' );
			delete_transient( 'peachpay_paypal_access_token_test' );
			delete_transient( 'peachpay_paypal_access_token_live' );
		}

		return array(
			'success' => true,
			'message' => __( 'PayPal credentials saved successfully! Your PayPal account is now connected.', 'peachpay-for-woocommerce' ),
		);
	}

	/**
	 * Deletes all stored PayPal credentials and clears access token cache.
	 *
	 * @return bool True on success.
	 */
	public static function delete_credentials() {
		update_option( self::OPTION_KEY, array() );
		if ( function_exists( 'delete_transient' ) ) {
			delete_transient( 'peachpay_paypal_access_token' );
			delete_transient( 'peachpay_paypal_access_token_test' );
			delete_transient( 'peachpay_paypal_access_token_live' );
		}
		return true;
	}
}