<?php
/**
 * Prevent removing the last login method (social-only lockout).
 *
 * @package WP_PowerSuite\OAuth\Accounts
 */

namespace WP_PowerSuite\OAuth\Accounts;

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

final class LoginMethodGuard {

	public const PASSWORD_UNLOCK_META = 'wpps_password_login_ready';

	public const REASON_LAST_LOGIN_METHOD = 'last_login_method';

	/**
	 * @return array{allowed: bool, message: string, reason?: string}
	 */
	public static function canUnlink( int $user_id, string $provider_slug ): array {
		$user_id       = (int) $user_id;
		$provider_slug = sanitize_key( $provider_slug );
		$identities    = SocialAccountStore::getIdentities( $user_id );
		if ( ! isset( $identities[ $provider_slug ] ) ) {
			return [ 'allowed' => false, 'message' => __( 'This connection is not linked.', 'wp-powersuite' ) ];
		}
		$count = count( $identities );
		if ( $count > 1 ) {
			$pass = (bool) apply_filters( 'wpps_social_can_unlink', true, $user_id, $provider_slug );
			if ( ! $pass ) {
				return [ 'allowed' => false, 'message' => __( 'You cannot disconnect this account right now.', 'wp-powersuite' ) ];
			}
			return [ 'allowed' => true, 'message' => '' ];
		}
		if ( self::hasSecondaryLogin( $user_id ) ) {
			return [ 'allowed' => true, 'message' => '' ];
		}
		return [
			'allowed' => false,
			'reason'  => self::REASON_LAST_LOGIN_METHOD,
			'message' => __( 'Add another sign-in method or set a password before disconnecting this one.', 'wp-powersuite' ),
		];
	}

	/**
	 * True if user can sign in without this social provider (password or another provider).
	 */
	public static function hasSecondaryLogin( int $user_id ): bool {
		if ( (int) get_user_meta( $user_id, self::PASSWORD_UNLOCK_META, true ) === 1 ) {
			return true;
		}
		/**
		 * Override when the user has a usable non-social login path.
		 *
		 * @param bool $has     Default false until password meta is set.
		 * @param int  $user_id User ID.
		 */
		return (bool) apply_filters( 'wpps_social_has_password_login', false, $user_id );
	}

	public static function markPasswordReady( int $user_id ): void {
		update_user_meta( (int) $user_id, self::PASSWORD_UNLOCK_META, 1 );
	}

	/**
	 * True for social-linked users who have not set a known password yet (WooCommerce “current password” would be unknown).
	 */
	public static function canSetFirstWcPasswordWithoutCurrent( int $user_id ): bool {
		if ( self::hasSecondaryLogin( $user_id ) ) {
			return false;
		}
		return count( SocialAccountStore::getIdentities( $user_id ) ) > 0;
	}
}
