<?php
require_once("config.php");
require_once("class.utils.php");
///////////
class Utils
{
    public $config;

    private $encrypt_method;

    private $secret_key;

    private $secret_iv;

    private $service;

    public function __construct()
    {
        $this->config  = new CONFIG();
        //encrption
        $this->encrypt_method = $this->config->ENCRYPTION_METHOD;
        $this->secret_key = $this->config->SECRET_KEY;
        $this->secret_iv = $this->config->SECRET_PASSWORD;
    }


    public function getDefaultLogo()
    {
        return $this->config->DEFAULT_LOGO;
    }

    public function getDefaultFavIcon()
    {
        return $this->config->DEFAULT_FAVICON;
    }

    public function validateDate($date, $format = 'Y-m-d')
    {
        $d = DateTime::createFromFormat($format, $date);
        return $d && $d->format($format) == $date;
    }
    public function is_session_started()
    {
        if (php_sapi_name() !== 'cli') {
            if (version_compare(phpversion(), '5.4.0', '>='))
                return session_status() === PHP_SESSION_ACTIVE ? true : false;
            else
                return session_id() === '' ? false : true;
        }
        return false;
    }

    public function isExpired(string $datetimeString, $timezone = null): bool
    {
        try {
            // Create a DateTime object from the given string.
            $inputDateTime = new DateTime($datetimeString, $timezone ? new DateTimeZone($timezone) : null);

            // Get the current date and time.
            $currentDateTime = new DateTime('now', $timezone ? new DateTimeZone($timezone) : null);

            // Compare the two DateTime objects.
            // The date has expired if the input date is less than the current date.
            return $inputDateTime < $currentDateTime;
        } catch (Exception $e) {
            // If the date string is invalid or malformed, we can assume it's expired
            // or not valid.
            return true;
        }
    }


    public function joinPaths(...$paths): string
    {
        // Filter out any empty path components
        $paths = array_filter($paths, fn($path) => $path !== '');

        // Remove leading/trailing slashes from all but the first part
        $cleanedPaths = [];
        foreach ($paths as $index => $path) {
            if ($index > 0) {
                $cleanedPaths[] = trim($path, '/');
            } else {
                $cleanedPaths[] = rtrim($path, '/');
            }
        }

        return implode('/', $cleanedPaths);
    }

    public function getBasePath()
    {
        $pathParts = pathinfo(__DIR__);
        return $pathParts["dirname"];
    }

    public function isDBInService()
    {
        return $this->service;
    }

    public function getPageLimit($page_no, $records_per_page = 25)
    {
        $limit = 'LIMIT ' . ($page_no - 1) * $records_per_page  . ',' . $records_per_page;
        return $limit;
    }

    public function getTotalPages($totalitems, $records_per_page = 25)
    {
        return ceil($totalitems / $records_per_page);
    }

    public function encrypt($request)
    {
        $output = false;
        // hash
        $key = hash('sha256', $this->secret_key);
        // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
        $iv = substr(hash('sha256', $this->secret_iv), 0, 16);
        $output = openssl_encrypt($request, $this->encrypt_method, $key, 0, $iv);
        $output = base64_encode($output);
        return $output;
    }


    public function decrypt($request)
    {
        $output = false;
        // hash
        $key = hash('sha256', $this->secret_key);
        // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
        $iv = substr(hash('sha256', $this->secret_iv), 0, 16);
        //decrypt the given text/string/number
        $output = openssl_decrypt(base64_decode($request), $this->encrypt_method, $key, 0, $iv);
        return $output;
    }


    public function isValidEmail($email)
    {
        // The filter_var() function is the safest and easiest way to validate an email.
        return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
    }

    public function passwordEncrypt($password, $type = 'sha256')
    {
        if ($type == "sha256") {
            $passwordhash = hash('sha256', $password);
            return $passwordhash;
        } else {
            return md5($password);
        }
    }

    //create category
    public function createColumn($column, $data)
    {
        $keys = array_keys($data);
        $dataString = "";
        for ($i = 0; $i < count($keys); $i++) {
            $colum_name = $keys[$i] . "_" . $column;
            $colum_key = ":u" . $keys[$i];
            $dataString .= $colum_name . "=" . $colum_key . ", ";
        }
        return trim($dataString, ", ");
    }

    public function createColumn2($column, $data, $keyDiff)
    {
        $keys = array_keys($data);
        $dataString = "";
        for ($i = 0; $i < count($keys); $i++) {
            $colum_name = $keys[$i] . "_" . $column;
            $colum_key = ":u" . $keyDiff . $keys[$i];
            $dataString .= $colum_name . "=" . $colum_key . ", ";
        }
        return trim($dataString, ", ");
    }

    public function generateUUID()
    {
        return sprintf(
            '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
            // 32 bits for "time_low"
            mt_rand(0, 0xffff),
            mt_rand(0, 0xffff),

            // 16 bits for "time_mid"
            mt_rand(0, 0xffff),

            // 16 bits for "time_hi_and_version",
            // four most significant bits holds version number 4
            mt_rand(0, 0x0fff) | 0x4000,

            // 16 bits, 8 bits for "clk_seq_hi_res",
            // 8 bits for "clk_seq_low",
            // two most significant bits holds zero and one for variant DCE1.1
            mt_rand(0, 0x3fff) | 0x8000,

            // 48 bits for "node"
            mt_rand(0, 0xffff),
            mt_rand(0, 0xffff),
            mt_rand(0, 0xffff)
        );
    }

    public function getRandom()
    {
        return rand(1000, 1000000);
    }

    public function UniqueMachineID($salt = "")
    {
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
            $temp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "diskpartscript.txt";
            if (!file_exists($temp) && !is_file($temp)) file_put_contents($temp, "select disk 0\ndetail disk");
            $output = shell_exec("diskpart /s " . $temp);
            $lines = explode("\n", $output);
            $result = array_filter($lines, function ($line) {
                return stripos($line, "ID:") !== false;
            });
            if (count($result) > 0) {
                $result = array_shift(array_values($result));
                $result = explode(":", $result);
                $result = trim(end($result));
            } else $result = $output;
        } else {
            $result = shell_exec("blkid -o value -s UUID");
            if (stripos($result, "blkid") !== false) {
                $result = $_SERVER['HTTP_HOST'];
            }
        }
        return md5($salt . md5($result));
    }

    public function toString($arrayToConvert)
    {
        $dataString = "";
        foreach ($arrayToConvert as $x) {
            $dataString .= $x . ", ";
        }
        return trim($dataString, ", ");
    }
}
