<?php
/**
 * Tracker
 *
 * Low-level DB write for click and impression events.
 * Separated from AjaxTracker so it can be called from any context
 * (AJAX, REST, CLI) without duplicating the insert logic.
 *
 * @package Relatedly\Tracking
 * @since   2.0.0
 */

namespace Relatedly\Tracking;

defined( 'ABSPATH' ) || exit;

/**
 * Persists click and impression tracking events.
 *
 * @since 2.0.0
 */
class Tracker {

	/**
	 * Record a single tracking event.
	 *
	 * @param int    $source_id    Source post ID (the page the visitor was on).
	 * @param int    $clicked_id   Related post ID that was clicked/seen.
	 * @param string $display_type 'inline' | 'end_content' | 'floating'.
	 * @param string $event_type   'click' | 'impression'.
	 * @param string $ip_address   Visitor IP (already validated).
	 * @param string $user_agent   Visitor user-agent string.
	 * @return bool True on success.
	 * @since 2.0.0
	 */
	public function record(
		int $source_id,
		int $clicked_id,
		string $display_type,
		string $event_type,
		string $ip_address = '',
		string $user_agent = ''
	): bool {
		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
		$result = $wpdb->insert(
			$wpdb->prefix . 'relatedly_clicks',
			[
				'source_post_id'  => $source_id,
				'clicked_post_id' => $clicked_id,
				'display_type'    => $display_type,
				'event_type'      => $event_type,
				'ip_address'      => $ip_address,
				'user_agent'      => $user_agent,
			],
			[ '%d', '%d', '%s', '%s', '%s', '%s' ]
		);

		return false !== $result;
	}

	/**
	 * Record multiple impressions in a single call (batched from JS).
	 *
	 * @param int    $source_id    Source post ID.
	 * @param int[]  $clicked_ids  Array of related post IDs seen.
	 * @param string $display_type 'inline' | 'end_content' | 'floating'.
	 * @param string $ip_address   Visitor IP.
	 * @param string $user_agent   Visitor user-agent.
	 * @return int Number of rows inserted.
	 * @since 2.0.0
	 */
	public function record_batch(
		int $source_id,
		array $clicked_ids,
		string $display_type,
		string $ip_address = '',
		string $user_agent = ''
	): int {
		$count = 0;
		foreach ( $clicked_ids as $clicked_id ) {
			$raw_clicked_id = (int) $clicked_id;
			if ( $raw_clicked_id <= 0 ) {
				continue;
			}

			$this->record( $source_id, absint( $raw_clicked_id ), $display_type, 'impression', $ip_address, $user_agent )
				&& $count++;
		}
		return $count;
	}
}
