<?php
/**
 * BookiFlex Core
 *
 * @package    BookiFlex
 * @subpackage Core
 * @author     BookiFlex
 * @copyright  Copyright (c) 2025 BookiFlex
 * @license    GPL-2.0-or-later
 *
 * @link       https://bookiflex.com
 */

declare(strict_types=1);

namespace BookiFlex\Core\Util;

defined('ABSPATH') || exit;

/**
 * Request utility class for safe access to superglobals.
 *
 * Provides sanitized access to $_GET, $_POST, $_REQUEST following WordPress
 * coding standards. Uses wp_unslash() + appropriate sanitization functions.
 *
 * @package BookiFlex\Core\Util
 */
final class Request
{
    /**
     * Get sanitized string from $_REQUEST.
     *
     * Uses: wp_unslash() + sanitize_text_field()
     *
     * @param string $key     The request parameter key
     * @param string $default Default value if key doesn't exist
     *
     * @return string Sanitized string value
     */
    public static function getString(string $key, string $default = ''): string
    {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if (!isset($_REQUEST[$key])) {
            return $default;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        $value = wp_unslash($_REQUEST[$key]);

        if (!is_string($value)) {
            return $default;
        }

        return sanitize_text_field($value);
    }

    /**
     * Get sanitized positive integer from $_REQUEST.
     *
     * Uses: absint() for positive integers only.
     *
     * @param string $key     The request parameter key
     * @param int    $default Default value if key doesn't exist or is invalid
     *
     * @return int Sanitized positive integer (0 or greater)
     */
    public static function getInt(string $key, int $default = 0): int
    {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if (!isset($_REQUEST[$key])) {
            return $default;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $value = $_REQUEST[$key];

        if (!is_numeric($value)) {
            return $default;
        }

        return absint($value);
    }

    /**
     * Get sanitized key (slug-safe) from $_REQUEST.
     *
     * Uses: sanitize_key() - for page slugs, status values, etc.
     * Only allows lowercase alphanumeric characters, dashes, and underscores.
     *
     * @param string $key     The request parameter key
     * @param string $default Default value if key doesn't exist
     *
     * @return string Sanitized key value
     */
    public static function getKey(string $key, string $default = ''): string
    {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if (!isset($_REQUEST[$key])) {
            return $default;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        $value = wp_unslash($_REQUEST[$key]);

        if (!is_string($value)) {
            return $default;
        }

        return sanitize_key($value);
    }

    /**
     * Get array of positive integers from $_POST.
     *
     * Used for bulk action checkboxes. Returns already sanitized array
     * with only positive integers (values <= 0 are filtered out).
     *
     * @param string $key The POST parameter key
     *
     * @return int[] Array of positive integers
     */
    public static function getIntArray(string $key): array
    {
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        if (!isset($_POST[$key]) || !is_array($_POST[$key])) {
            return [];
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $values = $_POST[$key];

        $result = [];
        foreach ($values as $value) {
            if (is_numeric($value)) {
                $intValue = absint($value);
                if ($intValue > 0) {
                    $result[] = $intValue;
                }
            }
        }

        return $result;
    }

    /**
     * Get sanitized nonce value for wp_verify_nonce().
     *
     * @param string $key The nonce parameter key (default: '_wpnonce')
     *
     * @return string Sanitized nonce value
     */
    public static function getNonce(string $key = '_wpnonce'): string
    {
        // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        if (!isset($_POST[$key])) {
            return '';
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        $value = wp_unslash($_POST[$key]);

        if (!is_string($value)) {
            return '';
        }

        return sanitize_text_field($value);
    }

    /**
     * Check if parameter exists in $_REQUEST.
     *
     * @param string $key The request parameter key
     *
     * @return bool True if parameter exists and is not empty string
     */
    public static function has(string $key): bool
    {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        if (!isset($_REQUEST[$key])) {
            return false;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $value = $_REQUEST[$key];

        if (is_string($value)) {
            return $value !== '';
        }

        return true;
    }
}
