<?php
/**
 * UserFinder — finds users in a role who haven't logged in for N months.
 *
 * Uses WP_User_Query with a meta_query. Considers both the explicit
 * `_platform_helm_last_login` meta AND a fallback to `user_registered`
 * (NOT EXISTS meta_query branch) so users who registered before the plugin
 * was installed are correctly classified as "inactive" if they're past
 * the threshold.
 *
 * @package Platform\Helm\Modules\GhostPurge
 */

declare( strict_types = 1 );

namespace Platform\Helm\Modules\GhostPurge;

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

final class UserFinder {

	/**
	 * Return user IDs matching the given role + inactivity threshold.
	 *
	 * @return int[]
	 */
	public function find_inactive_user_ids( string $role, int $months ): array {
		if ( '' === $role || $months <= 0 ) {
			return [];
		}
		$cutoff_ts = strtotime( "-{$months} months" );
		if ( false === $cutoff_ts ) {
			return [];
		}
		$cutoff_mysql = gmdate( 'Y-m-d H:i:s', $cutoff_ts );

		// Branch A: users who DO have last_login meta and it's older than cutoff.
		$query_a = new \WP_User_Query( [
			'role'        => $role,
			'fields'      => 'ID',
			'number'      => -1,
			'count_total' => false,
			'meta_query'  => [
				[
					'key'     => GhostPurgeModule::LAST_LOGIN_META,
					'value'   => $cutoff_ts,
					'compare' => '<',
					'type'    => 'NUMERIC',
				],
			],
		] );
		$ids_a = array_map( 'intval', (array) $query_a->get_results() );

		// Branch B: users with NO last_login meta whose user_registered is older
		// than the cutoff. (Brand-new accounts after plugin install with no
		// login yet are caught by user_registered.)
		$query_b = new \WP_User_Query( [
			'role'         => $role,
			'fields'       => 'ID',
			'number'       => -1,
			'count_total'  => false,
			'meta_query'   => [
				[
					'key'     => GhostPurgeModule::LAST_LOGIN_META,
					'compare' => 'NOT EXISTS',
				],
			],
			'date_query'   => [
				[
					'column' => 'user_registered',
					'before' => $cutoff_mysql,
					'inclusive' => true,
				],
			],
		] );
		$ids_b = array_map( 'intval', (array) $query_b->get_results() );

		$ids = array_values( array_unique( array_merge( $ids_a, $ids_b ) ) );

		// Never delete administrators — even if the role argument was a typo.
		return array_values( array_filter( $ids, function ( int $id ): bool {
			$u = get_userdata( $id );
			if ( ! $u ) {
				return false;
			}
			return ! in_array( 'administrator', (array) $u->roles, true );
		} ) );
	}

	/**
	 * @return array<string,string>  role_slug => display_name
	 */
	public function purgeable_roles(): array {
		$roles = wp_roles();
		if ( ! $roles instanceof \WP_Roles ) {
			return [];
		}
		$names = $roles->get_names();
		unset( $names['administrator'] );
		return $names;
	}
}
