<?php

declare(strict_types=1);

namespace ShieldX\Support;

defined('ABSPATH') || exit;

final class AdminFlashNotice
{
    private const TTL_SECONDS = 300;

    /** @var array<string,string> */
    private static $requestMessages = [];

    /**
     * @param array<string,mixed> $query
     * @param array<int,string> $messageKeys
     * @return array<string,mixed>
     */
    public static function protectQuery(array $query, array $messageKeys): array
    {
        foreach ($messageKeys as $messageKey) {
            if (!array_key_exists($messageKey, $query) || !is_scalar($query[$messageKey])) {
                continue;
            }

            $message = (string) $query[$messageKey];
            if ($message === '' || $message === '1') {
                continue;
            }

            self::store($messageKey, $message);
            $query[$messageKey] = '1';
        }

        return $query;
    }

    public static function store(string $messageKey, string $message): void
    {
        $messageKey = self::sanitizeKey($messageKey);
        $message = self::sanitizeMessage($message);
        if ($messageKey === '' || $message === '' || !function_exists('set_transient')) {
            return;
        }

        $transientKey = self::transientKey($messageKey);
        self::$requestMessages[$transientKey] = $message;
        set_transient($transientKey, $message, self::TTL_SECONDS);
    }

    public static function flag(string $messageKey, string $message): string
    {
        self::store($messageKey, $message);

        return '1';
    }

    public static function consume(string $messageKey): string
    {
        $messageKey = self::sanitizeKey($messageKey);
        if ($messageKey === '' || !function_exists('get_transient')) {
            return '';
        }

        $transientKey = self::transientKey($messageKey);
        if (isset(self::$requestMessages[$transientKey])) {
            if (function_exists('delete_transient')) {
                delete_transient($transientKey);
            }

            return self::$requestMessages[$transientKey];
        }

        $message = get_transient($transientKey);
        if (function_exists('delete_transient')) {
            delete_transient($transientKey);
        }

        $message = is_scalar($message) ? self::sanitizeMessage((string) $message) : '';
        if ($message !== '') {
            self::$requestMessages[$transientKey] = $message;
        }

        return $message;
    }

    private static function transientKey(string $messageKey): string
    {
        $blogId = function_exists('get_current_blog_id') ? max(0, (int) get_current_blog_id()) : 0;
        $userId = function_exists('get_current_user_id') ? max(0, (int) get_current_user_id()) : 0;
        $sessionToken = function_exists('wp_get_session_token') ? (string) wp_get_session_token() : '';
        $identity = implode('|', [(string) $blogId, (string) $userId, $sessionToken, $messageKey]);

        return 'shieldx_admin_flash_' . substr(hash('sha256', $identity), 0, 40);
    }

    private static function sanitizeKey(string $messageKey): string
    {
        return function_exists('sanitize_key')
            ? sanitize_key($messageKey)
            : strtolower((string) preg_replace('/[^a-z0-9_-]+/i', '', $messageKey));
    }

    private static function sanitizeMessage(string $message): string
    {
        $message = function_exists('sanitize_text_field')
            ? sanitize_text_field($message)
            : trim((string) preg_replace('/<[^>]*>/', '', $message));

        return substr($message, 0, 2000);
    }
}
