<?php
/**
 * AnyCoin Factory utilities.
 *
 * @package AnyCoin_Payment_Gateway
 */

defined( 'ABSPATH' ) || exit;

/**
 * AnyCoin Payment Gateway Factory.
 *
 * Factory class for creating and managing plugin dependencies.
 * Implements simple dependency injection for better testability.
 */
class AnyCoin_Factory {

	/**
	 * Singleton instances
	 *
	 * @var array
	 */
	private static $instances = [];

	/**
	 * Configuration storage
	 *
	 * @var array
	 */
	private static $config = [];

	/**
	 * Initialize factory with configuration.
	 *
	 * @param array $config Configuration array.
	 */
	public static function init( $config = [] ) {
		self::$config = array_merge(
			[
				'api_url'        => AnyCoin_Constants::DEFAULT_API_URL,
				'wallet_address' => '',
				'view_key'       => '',
				'debug'          => false,
				'test_mode'      => false,
			],
			$config
		);
	}

	/**
	 * Create API instance.
	 *
	 * @param array $override_config Optional configuration override.
	 * @return AnyCoin_API API instance.
	 */
	public static function create_api( $override_config = [] ) {
		$config = array_merge( self::$config, $override_config );
		return new AnyCoin_API( $config );
	}

	/**
	 * Get or create API singleton.
	 *
	 * @param array $override_config Optional configuration override.
	 * @return AnyCoin_API API singleton.
	 */
	public static function get_api( $override_config = [] ) {
		$payload = $override_config;
		if ( is_array( $payload ) ) {
			ksort( $payload );
		}
		$key = 'api_' . md5( wp_json_encode( $payload ) );

		if ( ! isset( self::$instances[ $key ] ) ) {
			self::$instances[ $key ] = self::create_api( $override_config );
		}

		return self::$instances[ $key ];
	}

	/**
	 * Create transaction monitor instance.
	 *
	 * @return AnyCoin_Transaction_Monitor Transaction monitor.
	 */
	public static function create_transaction_monitor() {
		return new AnyCoin_Transaction_Monitor();
	}

	/**
	 * Get or create transaction monitor singleton.
	 *
	 * @return AnyCoin_Transaction_Monitor Transaction monitor singleton.
	 */
	public static function get_transaction_monitor() {
		if ( ! isset( self::$instances['transaction_monitor'] ) ) {
			self::$instances['transaction_monitor'] = self::create_transaction_monitor();
		}

		return self::$instances['transaction_monitor'];
	}

	/**
	 * Create QR generator instance.
	 *
	 * @return AnyCoin_QR_Generator QR generator.
	 */
	public static function create_qr_generator() {
		return new AnyCoin_QR_Generator();
	}

	/**
	 * Get or create QR generator singleton.
	 *
	 * @return AnyCoin_QR_Generator QR generator singleton.
	 */
	public static function get_qr_generator() {
		if ( ! isset( self::$instances['qr_generator'] ) ) {
			self::$instances['qr_generator'] = self::create_qr_generator();
		}

		return self::$instances['qr_generator'];
	}

	/**
	 * Create AJAX handlers instance.
	 *
	 * @return AnyCoin_Ajax_Handlers AJAX handlers.
	 */
	public static function create_ajax_handlers() {
		return new AnyCoin_Ajax_Handlers();
	}

	/**
	 * Get or create AJAX handlers singleton.
	 *
	 * @return AnyCoin_Ajax_Handlers AJAX handlers singleton.
	 */
	public static function get_ajax_handlers() {
		if ( ! isset( self::$instances['ajax_handlers'] ) ) {
			self::$instances['ajax_handlers'] = self::create_ajax_handlers();
		}

		return self::$instances['ajax_handlers'];
	}

	/**
	 * Create payment page handler instance.
	 *
	 * @return AnyCoin_Payment_Page_Handler Payment page handler.
	 */
	public static function create_payment_page_handler() {
		return new AnyCoin_Payment_Page_Handler();
	}

	/**
	 * Get or create payment page handler singleton.
	 *
	 * @return AnyCoin_Payment_Page_Handler Payment page handler singleton.
	 */
	public static function get_payment_page_handler() {
		if ( ! isset( self::$instances['payment_page_handler'] ) ) {
			self::$instances['payment_page_handler'] = self::create_payment_page_handler();
		}

		return self::$instances['payment_page_handler'];
	}

	/**
	 * Create admin instance.
	 *
	 * @return AnyCoin_Admin Admin instance.
	 */
	public static function create_admin() {
		return new AnyCoin_Admin();
	}

	/**
	 * Get or create admin singleton.
	 *
	 * @return AnyCoin_Admin Admin singleton.
	 */
	public static function get_admin() {
		if ( ! isset( self::$instances['admin'] ) ) {
			self::$instances['admin'] = self::create_admin();
		}

		return self::$instances['admin'];
	}

	/**
	 * Create database migration instance.
	 *
	 * @return AnyCoin_Database_Migration Database migration.
	 */
	public static function create_database_migration() {
		return new AnyCoin_Database_Migration();
	}

	/**
	 * Create transaction handler instance.
	 *
	 * @return AnyCoin_Transaction_Handler Transaction handler.
	 */
	public static function create_transaction_handler() {
		return new AnyCoin_Transaction_Handler();
	}

	/**
	 * Create payment gateway instance.
	 *
	 * @return AnyCoin_Payment_Gateway Payment gateway.
	 */
	public static function create_payment_gateway() {
		return new AnyCoin_Payment_Gateway();
	}

	/**
	 * Set configuration value.
	 *
	 * @param string $key   Configuration key.
	 * @param mixed  $value Configuration value.
	 */
	public static function set_config( $key, $value ) {
		self::$config[ $key ] = $value;
	}

	/**
	 * Get configuration value.
	 *
	 * @param string $key            Configuration key.
	 * @param mixed  $default_value  Default value if key not found.
	 * @return mixed Configuration value.
	 */
	public static function get_config( $key, $default_value = null ) {
		return self::$config[ $key ] ?? $default_value;
	}

	/**
	 * Clear all singleton instances (useful for testing).
	 */
	public static function clear_instances() {
		self::$instances = [];
	}

	/**
	 * Check if instance exists.
	 *
	 * @param string $key Instance key.
	 * @return bool True if instance exists.
	 */
	public static function has_instance( $key ) {
		return isset( self::$instances[ $key ] );
	}

	/**
	 * Remove specific instance.
	 *
	 * @param string $key Instance key.
	 */
	public static function remove_instance( $key ) {
		unset( self::$instances[ $key ] );
	}
}
