<?php
/**
 * Lightweight performance profiling for AI Alt Text operations.
 *
 * @package AIAltTextGenerator
 * @since 2.0.0
 */

namespace AIAltTextGenerator;

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

/**
 * @since 2.0.0
 */
class Performance {

	private const CACHE_KEY = 'wpps_ai_alt_perf_v1';
	private const CACHE_TTL = DAY_IN_SECONDS;
	private const MAX_ENTRIES = 25;

	/**
	 * @param array<string, mixed> $meta
	 */
	public static function record( string $operation, float $duration_ms, array $meta = [] ): void {
		$entries = get_transient( self::CACHE_KEY );
		if ( ! is_array( $entries ) ) {
			$entries = [];
		}

		array_unshift(
			$entries,
			[
				'operation'    => sanitize_key( $operation ),
				'duration_ms'  => round( $duration_ms, 2 ),
				'memory_peak'  => size_format( memory_get_peak_usage( true ) ),
				'recorded_at'  => gmdate( 'Y-m-d H:i:s' ),
				'meta'         => $meta,
			]
		);

		$entries = array_slice( $entries, 0, self::MAX_ENTRIES );
		set_transient( self::CACHE_KEY, $entries, self::CACHE_TTL );
	}

	/**
	 * @template T
	 * @param callable(): T $callback
	 * @return T
	 */
	public static function measure( string $operation, callable $callback, array $meta = [] ) {
		$start = microtime( true );
		$result = $callback();
		self::record( $operation, ( microtime( true ) - $start ) * 1000, $meta );

		return $result;
	}

	/** @return list<array<string, mixed>> */
	public static function getRecent(): array {
		$entries = get_transient( self::CACHE_KEY );

		return is_array( $entries ) ? $entries : [];
	}

	/** @return array<string, mixed> */
	public static function getSummary(): array {
		$entries = self::getRecent();
		if ( $entries === [] ) {
			return [
				'count'       => 0,
				'avg_ms'      => 0,
				'max_ms'      => 0,
				'by_operation'=> [],
				'recent'      => [],
			];
		}

		$durations = array_map( static fn( array $row ): float => (float) ( $row['duration_ms'] ?? 0 ), $entries );
		$by_op     = [];

		foreach ( $entries as $row ) {
			$op = (string) ( $row['operation'] ?? 'unknown' );
			if ( ! isset( $by_op[ $op ] ) ) {
				$by_op[ $op ] = [ 'count' => 0, 'total_ms' => 0.0, 'max_ms' => 0.0 ];
			}
			$ms = (float) ( $row['duration_ms'] ?? 0 );
			++$by_op[ $op ]['count'];
			$by_op[ $op ]['total_ms'] += $ms;
			$by_op[ $op ]['max_ms']    = max( $by_op[ $op ]['max_ms'], $ms );
		}

		foreach ( $by_op as $op => $stats ) {
			$by_op[ $op ]['avg_ms'] = $stats['count'] > 0 ? round( $stats['total_ms'] / $stats['count'], 2 ) : 0;
		}

		return [
			'count'        => count( $entries ),
			'avg_ms'       => round( array_sum( $durations ) / count( $durations ), 2 ),
			'max_ms'       => round( max( $durations ), 2 ),
			'by_operation' => $by_op,
			'recent'       => array_slice( $entries, 0, 10 ),
		];
	}

	public static function clear(): void {
		delete_transient( self::CACHE_KEY );
	}
}
