<?php
/**
 * Safe logger: writes to a custom DB table and rotates after 10k rows.
 * Never logs raw secrets; payloads pass through sanitization.
 *
 * @package SuiteMkt3k
 */

namespace SuiteMkt3k\Utils;

use SuiteMkt3k\Installer;

defined( 'ABSPATH' ) || exit;
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching

final class Logger {

	private const MAX_ROWS = 10000;

	public static function info( string $context, string $message, array $meta = array() ): void {
		self::write( 'info', $context, $message, $meta );
	}

	public static function warn( string $context, string $message, array $meta = array() ): void {
		self::write( 'warn', $context, $message, $meta );
	}

	public static function error( string $context, string $message, array $meta = array() ): void {
		self::write( 'error', $context, $message, $meta );
	}

	private static function write( string $level, string $context, string $message, array $meta ): void {
		$settings = (array) get_option( 'suitemkt3k_settings', array() );
		$enabled  = $settings['advanced']['enable_logs'] ?? true;
		if ( ! $enabled && 'error' !== $level ) {
			return;
		}

		global $wpdb;
		$table = Installer::table( 'logs' );
		$wpdb->insert(
			$table,
			array(
				'level'     => Sanitizer::slug( $level ),
				'context'   => Sanitizer::slug( $context, 40 ),
				'message'   => Sanitizer::text( $message, 500 ),
				'meta_json' => wp_json_encode( self::sanitize_meta( $meta ) ),
			),
			array( '%s', '%s', '%s', '%s' )
		);
		self::maybe_rotate( $table );
	}

	private static function sanitize_meta( array $meta ): array {
		$out = array();
		foreach ( $meta as $k => $v ) {
			$k = sanitize_key( (string) $k );
			if ( in_array( $k, array( 'password', 'token', 'secret', 'api_key', 'smtp_password' ), true ) ) {
				$out[ $k ] = '***redacted***';
				continue;
			}
			if ( is_scalar( $v ) ) {
				$str       = (string) $v;
				$out[ $k ] = function_exists( 'mb_substr' ) ? mb_substr( $str, 0, 500 ) : substr( $str, 0, 500 );
			} else {
				$out[ $k ] = wp_json_encode( $v );
			}
		}
		return $out;
	}

	private static function maybe_rotate( string $table ): void {
		global $wpdb;
		$count = (int) $wpdb->get_var(
			$wpdb->prepare( 'SELECT COUNT(*) FROM %i', $table )
		);
		if ( $count <= self::MAX_ROWS ) {
			return;
		}
		$wpdb->query(
			$wpdb->prepare( 'DELETE FROM %i ORDER BY id ASC LIMIT 1000', $table )
		);
	}
}
