<?php

declare( strict_types=1 );

namespace StrykeWP\Modules;

use StrykeWP\Core\Logger;
use StrykeWP\Core\OptionManager;

/**
 * Abstract base class for STRYKE WP modules.
 *
 * Provides no-op defaults for lifecycle methods so concrete modules
 * only need to override what they actually use.
 *
 * @package StrykeWP\Modules
 */
abstract class AbstractModule implements ModuleInterface {

	protected Logger        $logger;
	protected OptionManager $options;

	/**
	 * Injects shared services without triggering hook registration.
	 *
	 * Called by ModuleRegistry::enable() / disable() before lifecycle hooks so
	 * that on_enable() / on_disable() can safely use $this->logger / $this->options
	 * even when the module was disabled (and therefore not booted) at plugins_loaded.
	 *
	 * @param Logger        $logger  Shared logger.
	 * @param OptionManager $options Shared option manager.
	 */
	final public function init( Logger $logger, OptionManager $options ): void {
		$this->logger  = $logger;
		$this->options = $options;
	}

	/**
	 * {@inheritDoc}
	 *
	 * Stores shared services for subclass use, then delegates to
	 * boot_module() which subclasses override to register their hooks.
	 */
	final public function boot( Logger $logger, OptionManager $options ): void {
		$this->init( $logger, $options );
		$this->boot_module();
	}

	/**
	 * Subclasses override this to register WordPress hooks.
	 *
	 * Guaranteed to be called only when the module is enabled and
	 * after $this->logger / $this->options have been set.
	 */
	protected function boot_module(): void {
		// No-op default — override in concrete modules.
	}

	/**
	 * {@inheritDoc} — no-op default.
	 */
	public function on_enable(): void {}

	/**
	 * {@inheritDoc} — no-op default.
	 */
	public function on_disable(): void {}

	/**
	 * {@inheritDoc} — default shows a "no settings" notice.
	 * Override in concrete modules that have their own settings UI.
	 */
	public function render_settings(): void {
		?>
		<div class="stryke-notice stryke-notice--info">
			<span class="dashicons dashicons-info" aria-hidden="true"></span>
			<?php esc_html_e( 'Dieses Modul hat keine eigenen Einstellungen.', 'stryke-wp' ); ?>
		</div>
		<?php
	}

	// ---------------------------------------------------------------------------
	// Convenience helpers available to all modules
	// ---------------------------------------------------------------------------

	/**
	 * Retrieves an option scoped to this module.
	 *
	 * @param string $key     Setting key.
	 * @param mixed  $default Default value.
	 * @return mixed
	 */
	protected function get_option( string $key, mixed $default = null ): mixed {
		return $this->options->module_get( $this->get_id(), $key, $default );
	}

	/**
	 * Stores an option scoped to this module.
	 *
	 * @param string $key   Setting key.
	 * @param mixed  $value Value to store.
	 * @return bool
	 */
	protected function set_option( string $key, mixed $value ): bool {
		return $this->options->module_set( $this->get_id(), $key, $value );
	}
}
