<?php
/**
 * Abstract class for gateway settings.
 * Should be extended by all gateway settings classes.
 */

namespace Flo_Checkout\Gateways\Helpers;

use Flo_Checkout\Shared;
use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Loggers\Log_Level_Enum;
use Stringable;
use Throwable;
use WC_Log_Handler_File;

/**
 * Class Abstract_Gateway_Settings
 */
abstract class Abstract_Gateway_Settings {

	/**
	 * Contains subarrays of settings for each gateway.
	 *
	 * @var array
	 */
	private static array $settings = array();

	/**
	 * Get the gateway ID.
	 *
	 * @return string The gateway ID.
	 */
	abstract public static function get_gateway_id(): string;

	/**
	 * Retrieve a specific value from the settings.
	 *
	 * @param string $key The key of the setting to retrieve.
	 *
	 * @return mixed|null The value of the specified setting, or null if the setting does not exist.
	 */
	public static function get( string $key ): mixed {
		if ( ! isset( self::$settings[ static::get_gateway_id() ] ) ) {
			self::$settings[ static::get_gateway_id() ] = get_option( 'woocommerce_' . static::get_gateway_id() . '_settings' );
		}
		return self::$settings[ static::get_gateway_id() ][ $key ] ?? null;
	}

	/**
	 * Update a specific setting.
	 *
	 * @param string $key The key of the setting to update.
	 * @param mixed  $value The value to update the setting with.
	 *
	 * @return void
	 */
	public static function update( string $key, mixed $value ): void {
		$settings = get_option( 'woocommerce_' . static::get_gateway_id() . '_settings' );

		if ( ! is_array( $settings ) ) {
			$settings = array();
		}

		$settings[ $key ]                           = $value;
		self::$settings[ static::get_gateway_id() ] = $settings;
		update_option( 'woocommerce_' . static::get_gateway_id() . '_settings', $settings );
	}

	/**
	 * Check if the gateway is enabled.
	 *
	 * @return bool Returns true if the module is enabled, false otherwise.
	 */
	public static function is_enabled(): bool {
		return self::is_setting_enabled( 'enabled' );
	}

	/**
	 * Check if a specific setting is enabled.
	 *
	 * @param string $key The key of the setting to check.
	 *
	 * @return bool True if the setting is enabled, false otherwise.
	 */
	public static function is_setting_enabled( string $key ): bool {
		return 'yes' === self::get( $key );
	}

	/**
	 * Logs a message to the woocommerce log if logging is enabled
	 *
	 * @param string                       $message The message to log.
	 * @param null|array|string|Stringable $context Context.
	 * @param Log_Level_Enum               $level   Log level.
	 *
	 * @return void
	 */
	public static function log(
		string $message,
		null|array|string|Stringable $context = null,
		Log_Level_Enum $level = Log_Level_Enum::DEBUG
	): void {
		if ( is_string( $level ) ) {
			try {
				$level = Log_Level_Enum::from( $level );
			} catch ( Throwable ) {
				$level = Log_Level_Enum::ERROR;
			}
		}

		if ( 'yes' === self::get( 'log_enabled' ) ) {
			Shared::instance()->logger->log(
				static::get_gateway_id(),
				$message,
				$context,
				$level
			);
		}
	}


	/**
	 * Retrieve the URL of the log file for the gateway.
	 *
	 * @return string The URL of the log file for the gateway.
	 */
	public static function get_log_file_url(): string {
		return add_query_arg(
			array(
				'page'     => 'wc-status',
				'tab'      => 'logs',
				'log_file' => WC_Log_Handler_File::get_log_file_name( static::get_gateway_id() ),
			),
			admin_url( 'admin.php' )
		);
	}

	/**
	 * Retrieve the log file link if the log directory is defined.
	 *
	 * @return string The log file link if the log directory is defined, otherwise an empty string.
	 */
	public static function maybe_get_log_file_link(): string {
		if ( ! defined( 'WC_LOG_DIR' ) ) {
			return '';
		}

		return sprintf(
			'%s%s%s',
			'<a href="' . esc_url( self::get_log_file_url() ) . '" target="_blank">',
			__(
				'View Log',
				'flo-checkout-plugin'
			),
			'</a>'
		);
	}

	/**
	 * Get the settings fields for the payment method.
	 *
	 * @return array An array of form fields settings for BNPL payment method.
	 */
	abstract public static function get_settings_fields(): array;
}
