<?php
/**
 * Audit trail logging for security-related actions.
 *
 * @package ZA_Creative_Login_Shield
 */

defined( 'ABSPATH' ) || exit;

/**
 * Logs and retrieves security audit trail entries.
 */
class ZACLS_Audit_Trail {

	/**
	 * Record an audit log entry.
	 *
	 * @param string $action   Action identifier.
	 * @param string $details  Description of the action.
	 * @param int    $user_id  User ID (defaults to current user).
	 */
	public static function log( $action, $details = '', $user_id = 0 ) {
		global $wpdb;

		if ( ! $user_id ) {
			$user_id = get_current_user_id();
		}

		$wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
			$wpdb->prefix . 'zacls_audit_log',
			array(
				'user_id'    => $user_id,
				'action'     => substr( $action, 0, 100 ),
				'details'    => substr( $details, 0, 500 ),
				'ip'         => ZACLS_Main::get_ip(),
				'created_at' => current_time( 'mysql' ),
			),
			array( '%d', '%s', '%s', '%s', '%s' )
		);
	}

	/**
	 * Get audit log entries with pagination.
	 *
	 * @param int    $limit          Records per page.
	 * @param int    $offset         Offset.
	 * @param string $action_filter  Optional action filter.
	 * @return array
	 */
	public static function get_logs( $limit = 50, $offset = 0, $action_filter = '' ) {
		global $wpdb;

		if ( ! empty( $action_filter ) ) {
			return $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
				$wpdb->prepare(
					"SELECT * FROM {$wpdb->prefix}zacls_audit_log WHERE action = %s ORDER BY created_at DESC LIMIT %d OFFSET %d", // phpcs:ignore WordPress.DB.PreparedSQL
					$action_filter,
					$limit,
					$offset
				),
				ARRAY_A
			);
		}

		return $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
			$wpdb->prepare(
				"SELECT * FROM {$wpdb->prefix}zacls_audit_log ORDER BY created_at DESC LIMIT %d OFFSET %d", // phpcs:ignore WordPress.DB.PreparedSQL
				$limit,
				$offset
			),
			ARRAY_A
		);
	}

	/**
	 * Count audit log entries.
	 *
	 * @param string $action_filter Optional action filter.
	 * @return int
	 */
	public static function count_logs( $action_filter = '' ) {
		global $wpdb;

		if ( ! empty( $action_filter ) ) {
			return (int) $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
				$wpdb->prepare(
					"SELECT COUNT(*) FROM {$wpdb->prefix}zacls_audit_log WHERE action = %s", // phpcs:ignore WordPress.DB.PreparedSQL
					$action_filter
				)
			);
		}

		return (int) $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
			"SELECT COUNT(*) FROM {$wpdb->prefix}zacls_audit_log" // phpcs:ignore WordPress.DB.PreparedSQL
		);
	}

	/**
	 * Get all distinct action types in the log.
	 *
	 * @return array
	 */
	public static function get_unique_actions() {
		global $wpdb;

		return $wpdb->get_col( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
			"SELECT DISTINCT action FROM {$wpdb->prefix}zacls_audit_log ORDER BY action ASC" // phpcs:ignore WordPress.DB.PreparedSQL
		);
	}

	/**
	 * Clear all audit log entries.
	 *
	 * @return bool
	 */
	public static function clear_logs() {
		global $wpdb;

		$result = $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}zacls_audit_log" ); // phpcs:ignore WordPress.DB
		return false !== $result;
	}

	/**
	 * Get summary statistics about the audit log.
	 *
	 * @return array|null
	 */
	public static function get_stats() {
		global $wpdb;

		return $wpdb->get_row( // phpcs:ignore WordPress.DB
			"SELECT
				COUNT(*) as total,
				COUNT(DISTINCT DATE(created_at)) as active_days,
				COUNT(DISTINCT action) as unique_actions
			FROM {$wpdb->prefix}zacls_audit_log",
			ARRAY_A
		);
	}
}
