<?php

/**
 * LolaCore — ActionLogCleanup
 *
 * Purges action log rows older than the configured retention period.
 * Invoked daily by the WP-Cron hook `lolacore_log_cleanup`.
 *
 * @package LolaCore
 * @license GPL-2.0-or-later
 */

declare(strict_types=1);

namespace LolaCore\Actions;

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

/**
 * Deletes expired rows from wp_lolacore_log based on Settings retention days.
 */
class ActionLogCleanup
{
	public const MIN_RETENTION_DAYS = 1;

	public const MAX_RETENTION_DAYS = 3650;

	public const DEFAULT_RETENTION_DAYS = 90;

	/**
	 * Delete log entries older than the configured retention window.
	 *
	 * @return int Number of rows deleted.
	 */
	public static function purgeExpired(): int
	{
		global $wpdb;

		$days  = self::resolveRetentionDays();
		$table = $wpdb->prefix . 'lolacore_log';

		$cutoffTimestamp = strtotime('-' . $days . ' days', (int) current_time('timestamp'));
		if ($cutoffTimestamp === false) {
			return 0;
		}

		$cutoff = gmdate('Y-m-d H:i:s', $cutoffTimestamp);

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom LolaCore table; name is built from $wpdb->prefix only.
		$deleted = $wpdb->query(
			$wpdb->prepare(
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				"DELETE FROM {$table} WHERE executed_at < %s",
				$cutoff,
			),
		);

		return $deleted === false ? 0 : (int) $deleted;
	}

	/**
	 * Reads retention days from lolacore_config (Settings UI key first).
	 */
	public static function resolveRetentionDays(): int
	{
		global $wpdb;
		$table = $wpdb->prefix . 'lolacore_config';

		foreach (array('log_retention_days', 'memory_log_retention_days') as $configKey) {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom LolaCore table; name is built from $wpdb->prefix only.
			$value = $wpdb->get_var(
				$wpdb->prepare(
					// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
					"SELECT config_value FROM {$table} WHERE config_key = %s",
					$configKey,
				),
			);

			if ($value !== null && $value !== '') {
				return self::clampRetentionDays((int) $value);
			}
		}

		return self::DEFAULT_RETENTION_DAYS;
	}

	/**
	 * Keeps retention within a safe, documented range.
	 */
	public static function clampRetentionDays(int $days): int
	{
		return max(self::MIN_RETENTION_DAYS, min(self::MAX_RETENTION_DAYS, $days));
	}
}
