<?php
/**
 * Custom Login Logo Link Module
 *
 * Changes the login logo link URL and accessible label.
 *
 * @package CustomLoginLogoLink
 * @since 1.0.0
 */

namespace CustomLoginLogoLink;

use WP_PowerSuite\Core\AbstractModule;
use WP_PowerSuite\Core\OptionStoreModuleSettingsRepository;

class Module extends AbstractModule {

	private const MODULE_ID = 'custom-login-logo-link';
	private const MODULE_VERSION = '1.3.0';

	private bool $login_hooks_registered = false;

	/** @var array<string, mixed> */
	private array $settings = [];

	public function getId(): string {
		return self::MODULE_ID;
	}

	public function getName(): string {
		return __( 'Custom Login Logo Link', 'wp-powersuite' );
	}

	public function getVersion(): string {
		return self::MODULE_VERSION;
	}

	public function getDescription(): string {
		return __( 'Choose where the login logo click goes—usually back to your own site.', 'wp-powersuite' );
	}

	public function getContext(): string|array {
		return [ 'login', 'frontend' ];
	}

	protected function registerHooks(): void {
		add_action( 'login_init', [ $this, 'registerLoginHooks' ], 0 );
		add_action( 'wpps_before_custom_login_render', [ $this, 'registerLoginHooks' ], 0 );
	}

	/**
	 * Register login screen hooks once per request (standard or custom login URL).
	 */
	public function registerLoginHooks(): void {
		if ( $this->login_hooks_registered || $this->isDelegatedToLoginPageCustomizor() ) {
			return;
		}

		$this->login_hooks_registered = true;

		$defaults       = $this->getDefaultSettings();
		$saved          = $this->moduleSettings()->all( [] );
		$this->settings = array_merge( $defaults, is_array( $saved ) ? $saved : [] );

		add_filter( 'login_headerurl', [ $this, 'filterLoginLogoLink' ], 10, 1 );
		add_filter( 'login_headertext', [ $this, 'filterLoginLogoText' ], 10, 1 );
	}

	/**
	 * Login Page Customizer (Pro) takes over the logo link when its Logo Link field is set.
	 */
	private function isDelegatedToLoginPageCustomizor(): bool {
		if ( ! OptionStoreModuleSettingsRepository::isModuleEnabled( 'login-page-customizor' ) ) {
			return false;
		}

		$settings = OptionStoreModuleSettingsRepository::forModule( 'login-page-customizor' )->all( [] );
		if ( ! is_array( $settings ) ) {
			return false;
		}

		if ( ! empty( $settings['hide_logo'] ) && $settings['hide_logo'] !== '0' ) {
			return false;
		}

		$logo_link = isset( $settings['logo_link'] ) ? trim( (string) $settings['logo_link'] ) : '';
		if ( $logo_link !== '' ) {
			return true;
		}

		$source = isset( $settings['logo_source'] ) ? (string) $settings['logo_source'] : 'upload';
		if ( $source === 'site_icon' && get_site_icon_url( 512 ) ) {
			return true;
		}
		if ( $source === 'url' && ! empty( $settings['logo_external_url'] ) ) {
			return true;
		}
		if ( ! empty( $settings['logo_url'] ) ) {
			return true;
		}

		return false;
	}

	/**
	 * @return array<string, string>
	 */
	public function getDefaultSettings(): array {
		return [
			'logo_link_url' => home_url( '/' ),
		];
	}

	public function filterLoginLogoLink( string $url ): string {
		$link = isset( $this->settings['logo_link_url'] ) ? trim( (string) $this->settings['logo_link_url'] ) : '';

		if ( $link === '' ) {
			return home_url( '/' );
		}

		$sanitized = esc_url_raw( $link );

		return $sanitized !== '' ? esc_url( $sanitized ) : home_url( '/' );
	}

	public function filterLoginLogoText( string $text ): string {
		$name = get_bloginfo( 'name', 'display' );

		return is_string( $name ) && $name !== '' ? $name : $text;
	}
}
