<?php

namespace Limb_Chatbot\Includes\Services;

/**
 * Tracks the last polling sync timestamp per live-agent WP user.
 *
 * Persisted via wp_usermeta so the value survives across requests.
 * The event listener uses this to decide whether a stale agent needs an
 * email nudge (they have not polled the sync endpoint recently).
 *
 * @package Limb_Chatbot
 * @subpackage Events
 * @since 2.1.0
 */
class User_Sync_Tracker {

	/**
	 * User-meta key for the last-sync Unix timestamp.
	 */
	const META_KEY = '_lbaic_la_last_sync';

	/**
	 * User-meta key for the last-sync Unix timestamp of the native WP admin
	 * settings page (used to decide whether to send "new chat" emails).
	 */
	const META_KEY_ADMIN_SETTINGS_LAST_SYNC = '_lbaic_admin_settings_last_sync';

	/**
	 * Seconds of inactivity before an agent is considered stale.
	 * After this threshold an email is sent alongside the queued local event.
	 */
	const STALE_THRESHOLD_SECONDS = 180; // 3 minutes

	/**
	 * Seconds of inactivity on the native WP admin settings page before an
	 * admin is considered stale (and should receive email nudges).
	 */
	const ADMIN_SETTINGS_STALE_THRESHOLD_SECONDS = 180; // 3 minutes

	/**
	 * Persist a "last sync" timestamp for a given user-meta key.
	 *
	 * @param  int     $wp_user_id
	 * @param  string  $meta_key
	 *
	 * @return void
	 */
	private function record_sync_by_key( int $wp_user_id, string $meta_key ): void {
		update_user_meta( $wp_user_id, $meta_key, time() );
	}

	/**
	 * Read a "last sync" timestamp for a given user-meta key.
	 *
	 * @param  int     $wp_user_id
	 * @param  string  $meta_key
	 *
	 * @return int|null
	 */
	private function get_last_sync_by_key( int $wp_user_id, string $meta_key ): ?int {
		$value = get_user_meta( $wp_user_id, $meta_key, true );

		return ( $value !== '' && $value !== false ) ? (int) $value : null;
	}

	/**
	 * Whether a user is considered stale for the given meta key.
	 *
	 * @param  int     $wp_user_id
	 * @param  string  $meta_key
	 * @param  int     $threshold_seconds
	 *
	 * @return bool
	 */
	private function is_stale_by_key( int $wp_user_id, string $meta_key, int $threshold_seconds ): bool {
		$last = $this->get_last_sync_by_key( $wp_user_id, $meta_key );

		if ( $last === null ) {
			return true;
		}

		return ( time() - $last ) >= $threshold_seconds;
	}

	/**
	 * Record a successful sync for the given WP user.
	 *
	 * Called on every successful poll by the shell-sync endpoint.
	 *
	 * @param  int  $wp_user_id
	 *
	 * @return void
	 */
	public function record( int $wp_user_id ): void {
		$this->record_sync_by_key( $wp_user_id, self::META_KEY );
	}

	/**
	 * Return the Unix timestamp of the last recorded sync, or null if the
	 * agent has never synced.
	 *
	 * @param  int  $wp_user_id
	 *
	 * @return int|null
	 */
	public function get_last_sync( int $wp_user_id ): ?int {
		return $this->get_last_sync_by_key( $wp_user_id, self::META_KEY );
	}

	/**
	 * Whether the agent has not polled within the stale threshold.
	 *
	 * @param  int  $wp_user_id
	 *
	 * @return bool
	 */
	public function is_stale( int $wp_user_id ): bool {
		return $this->is_stale_by_key( $wp_user_id, self::META_KEY, self::STALE_THRESHOLD_SECONDS );
	}

	/**
	 * Record a successful open/sync of the native WP admin settings page for
	 * a given WP user.
	 *
	 * Called from the admin settings page render hook so the plugin can
	 * suppress duplicate email nudges when the admin is actively viewing the
	 * dashboard.
	 *
	 * @param  int  $wp_user_id
	 *
	 * @return void
	 */
	public function record_admin_settings_sync( int $wp_user_id ): void {
		$this->record_sync_by_key( $wp_user_id, self::META_KEY_ADMIN_SETTINGS_LAST_SYNC );
	}

	/**
	 * Return the Unix timestamp of the last recorded "admin settings page"
	 * sync, or null if the admin has never opened the settings page.
	 *
	 * @param  int  $wp_user_id
	 *
	 * @return int|null
	 */
	public function get_admin_settings_last_sync( int $wp_user_id ): ?int {
		return $this->get_last_sync_by_key( $wp_user_id, self::META_KEY_ADMIN_SETTINGS_LAST_SYNC );
	}

	/**
	 * Whether the admin has not opened the settings page recently.
	 *
	 * @param  int  $wp_user_id
	 *
	 * @return bool
	 */
	public function is_admin_settings_stale( int $wp_user_id ): bool {
		return $this->is_stale_by_key(
			$wp_user_id,
			self::META_KEY_ADMIN_SETTINGS_LAST_SYNC,
			self::ADMIN_SETTINGS_STALE_THRESHOLD_SECONDS
		);
	}
}
