<?php

namespace Shm\ShmUtils;

use Shm\Shm;
use Shm\ShmTypes\StructureType;

/**
 * Utility class for common operations
 * 
 * This class provides various utility methods for data validation,
 * transliteration, and other common operations.
 */
class ShmUtils
{
    /**
     * Validate data against schema
     * 
     * @param array $schema Schema definition
     * @param mixed $data Data to validate (optional, uses request data if null)
     * @throws \Exception If validation fails
     */
    public static function validate(array $schema, $data = null): void
    {
        $schema = Shm::structure($schema);

        if ($data === null) {
            $data = ShmUtils::allRequest();
        }

        $schema->validate($data);
    }

    /**
     * Transliterate Cyrillic text to Latin
     * 
     * @param string $input Input text
     * @return string Transliterated text
     */
    /**
     * Transliteration map for Cyrillic to Latin characters
     */
    private static array $translitMap = [
        'а' => 'a',
        'б' => 'b',
        'в' => 'v',
        'г' => 'g',
        'д' => 'd',
        'е' => 'e',
        'ё' => 'yo',
        'ж' => 'zh',
        'з' => 'z',
        'и' => 'i',
        'й' => 'y',
        'к' => 'k',
        'л' => 'l',
        'м' => 'm',
        'н' => 'n',
        'о' => 'o',
        'п' => 'p',
        'р' => 'r',
        'с' => 's',
        'т' => 't',
        'у' => 'u',
        'ф' => 'f',
        'х' => 'kh',
        'ц' => 'ts',
        'ч' => 'ch',
        'ш' => 'sh',
        'щ' => 'shch',
        'ъ' => '',
        'ы' => 'y',
        'ь' => '',
        'э' => 'e',
        'ю' => 'yu',
        'я' => 'ya',
        'А' => 'A',
        'Б' => 'B',
        'В' => 'V',
        'Г' => 'G',
        'Д' => 'D',
        'Е' => 'E',
        'Ё' => 'Yo',
        'Ж' => 'Zh',
        'З' => 'Z',
        'И' => 'I',
        'Й' => 'Y',
        'К' => 'K',
        'Л' => 'L',
        'М' => 'M',
        'Н' => 'N',
        'О' => 'O',
        'П' => 'P',
        'Р' => 'R',
        'С' => 'S',
        'Т' => 'T',
        'У' => 'U',
        'Ф' => 'F',
        'Х' => 'Kh',
        'Ц' => 'Ts',
        'Ч' => 'Ch',
        'Ш' => 'Sh',
        'Щ' => 'Shch',
        'Ъ' => '',
        'Ы' => 'Y',
        'Ь' => '',
        'Э' => 'E',
        'Ю' => 'Yu',
        'Я' => 'Ya'
    ];

    /**
     * Transliterate Cyrillic text to Latin
     * 
     * @param string $input Input text
     * @return string Transliterated text
     */
    public static function translitIfCyrillic(string $input): string
    {
        // Check if there's at least one Cyrillic character
        if (preg_match('/[\p{Cyrillic}]/u', $input)) {
            return strtr($input, self::$translitMap);
        }

        // Return original if no Cyrillic characters found
        return $input;
    }


    private static ?array $_data = null;

    /**
     * Get request parameter value
     * 
     * @param string $key Parameter key
     * @param mixed $default Default value if key not found
     * @return mixed Parameter value or default
     */
    public static function request(string $key, $default = null)
    {


        if (self::$_data !== null) {
            return self::$_data[$key] ?? $default;
        }


        $get = $_GET;
        $post = $_POST;
        $request = $_REQUEST;
        $requestBody = [];
        $body = file_get_contents('php://input');
        if ($body) {
            $requestBody = json_decode($body, true);
        }

        self::$_data = [...$get, ...$post, ...$request, ...$requestBody];
        return self::$_data[$key] ?? $default;
    }

    public static function allRequest()
    {

        if (self::$_data !== null) {
            return self::$_data;
        }


        $get = $_GET;
        $post = $_POST;
        $request = $_REQUEST;
        $requestBody = [];
        $body = file_get_contents('php://input');
        if ($body) {
            $requestBody = json_decode($body, true);


            if (!is_array($requestBody) && !is_object($requestBody)) {
                $requestBody = [];
            }
        }

        self::$_data  = [...$get, ...$post, ...$request, ...$requestBody];
        return self::$_data;
    }

    public static function privateAccess($valid_username, $valid_password)
    {

        if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
            header('WWW-Authenticate: Basic realm="Restricted Area"');
            header('HTTP/1.0 401 Unauthorized');
            echo 'Authentication required';
            exit;
        } else {
            $username = $_SERVER['PHP_AUTH_USER'];
            $password = $_SERVER['PHP_AUTH_PW'];

            if ($username !== $valid_username || $password !== $valid_password) {
                header('WWW-Authenticate: Basic realm="Restricted Area"');
                header('HTTP/1.0 401 Unauthorized');
                echo 'Invalid credentials';
                exit;
            }
        }
    }

    public static   function num2str($n, $textForms)
    {
        $n = abs($n) % 100;
        $n1 = $n % 10;
        if ($n > 10 && $n < 20) {
            return $textForms[2];
        }
        if ($n1 > 1 && $n1 < 5) {
            return $textForms[1];
        }
        if ($n1 === 1) {
            return $textForms[0];
        }
        return $textForms[2];
    }


    public static function upperCase($str)
    {
        if (empty($str)) {
            return '';
        }

        $result = mb_strtoupper($str);
        return $result;
    }


    public static function cleanKey($key)
    {

        // Удаляем управляющие и невидимые символы, пробелы
        $cleanKey = preg_replace('/[\x00-\x1F\x7F\x{200B}-\x{200D}\x{FEFF}]+/u', '', $key);
        $cleanKey = trim($cleanKey);

        return $cleanKey;
    }

    public static function onlyLetters($str)
    {



        $result = preg_replace('/[^a-zа-я]/ui', '*', $str);
        $result = explode('*', $result ?? "");
        $result = array_diff($result, ['']);



        $text = [];
        foreach ($result as $index => $val) {

            $text[] = $val;
        }
        return ucfirst(implode('', $text));
    }



    public static function isValidKey($key)
    {

        if (!$key) {
            return;
        }


        $validKey = Config::get('validKey', true);

        if (!$validKey) {
            return;
        }




        if (!preg_match('/^[a-zA-Z0-9_*]+$/', $key)) {
            throw new \Exception("Key must contain only letters, numbers, underscores, and asterisks (*). Invalid key: {$key}");
        }
    }
}