<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
use Medoo\Medoo;

/**
 * @param string $method
 * @param array $parameters
 * @return array
 */
function bot(string $method, array $parameters = []): array
{
    $url = "https://api.telegram.org/bot" . API_KEY . "/" . $method;
    $client = new Client();
    // مدیریت فایل‌ها برای ارسال
    $multipart = [];
    foreach ($parameters as $key => $value) {
        if ($value instanceof CURLFile) {
            $multipart[] = [
                'name' => $key,
                'contents' => fopen($value->getFilename(), 'r'),
                'filename' => $value->getPostFilename() ?? basename($value->getFilename()),
            ];
        } else {
            $multipart[] = [
                'name' => $key,
                'contents' => is_array($value) ? json_encode($value) : $value,
            ];
        }
    }

    try {
        $response = $client->post($url, [
            'multipart' => $multipart
        ]);

        $body = $response->getBody()->getContents();
        return json_decode($body, true);
    } catch (RequestException $e) {
        if ($e->hasResponse()) {
            $responseBody = $e->getResponse()->getBody()->getContents();
            return json_decode($responseBody, true);
        }
        else return ['ok' => false, 'description' => $e->getMessage()];
    } catch (GuzzleException $e) {
        return [
            'ok' => false,
            'description' => $e->getMessage()
        ];
    }
}

/**
 * @param $chat_id
 * @param $text
 * @param $keyboard
 * @param $reply_to_message_id
 * @param string $parse_mode
 * @param bool $protect_content
 * @param bool $disable_web_page_preview
 * @return array
 */
function SendMessage($chat_id, $text, $keyboard = null, $reply_to_message_id = null, string $parse_mode = 'html', bool $protect_content = false, bool $disable_web_page_preview = true): array
{
    return bot('sendMessage',[
        'chat_id' => $chat_id,
        'text' => $text,
        'reply_markup' => $keyboard,
        'reply_to_message_id' => $reply_to_message_id,
        'parse_mode' => $parse_mode,
        'protect_content' => $protect_content,
        'disable_web_page_preview' => $disable_web_page_preview,
        'allow_sending_without_reply' => true,
    ]);
}

/**
 * @param $chat_id
 * @param $type
 * @param $file_id
 * @param $caption
 * @param $keyboard
 * @param $reply_to_message_id
 * @param string $parse_mode
 * @param bool $protect_content
 * @return array
 */
function SendFile($chat_id, $type, $file_id, $caption = null, $keyboard = null, $reply_to_message_id = null, string $parse_mode = 'html', bool $protect_content = false): array
{
    return bot("send".str_replace("_",'',$type),[
        'chat_id' => $chat_id,
        "$type" => $file_id,
        'caption' => $caption,
        'reply_markup' => $keyboard,
        'reply_to_message_id' => $reply_to_message_id,
        'parse_mode' => $parse_mode,
        'protect_content' => $protect_content,
        'allow_sending_without_reply' => true
    ]);
}

/**
 * @param $chat_id
 * @param string $text
 * @param $message_id
 * @param string|null $keyboard
 * @param string $parse_mode
 * @return array
 */
function editMessageText($chat_id, string $text, $message_id, string $keyboard = null, string $parse_mode = 'html'): array
{
    return bot('editMessageText',[
        'chat_id' => $chat_id,
        'text' => $text,
        'reply_markup' => $keyboard,
        'message_id' => $message_id,
        'parse_mode' => $parse_mode,
        'disable_web_page_preview' => true
    ]);
}

/**
 * @param $chat_id
 * @param $message_id
 * @param $keyboard
 * @return array
 */
function editMessageReplyMarkup($chat_id, $message_id, $keyboard = null): array
{
    return bot('editMessageReplyMarkup',[
        'chat_id' => $chat_id,
        'reply_markup' => $keyboard,
        'message_id' => $message_id
    ]);
}

/**
 * @param $chat_id
 * @param $from_chat_id
 * @param $message_id
 * @param $keyboard
 * @param $reply_to_message_id
 * @param bool $protect_content
 * @return array
 */
function CopyMessage($chat_id, $from_chat_id, $message_id, $keyboard = null, $reply_to_message_id = null, bool $protect_content = false): array
{
    return bot('copyMessage',[
        'chat_id' => $chat_id,
        'from_chat_id' => $from_chat_id,
        'message_id' => $message_id,
        'reply_markup' => $keyboard,
        'reply_to_message_id' => $reply_to_message_id,
        'protect_content' => $protect_content,
        'allow_sending_without_reply' => true
    ]);
}

/**
 * @param $user_id
 * @param $chat_id
 * @return array
 */
function getChatMember($user_id, $chat_id): array
{
    return bot('getChatMember',[
        'chat_id' => $chat_id,
        'user_id' => $user_id
    ]);
}

/**
 * @param $chat_id
 * @return array
 */
function getChat($chat_id): array
{
    return bot('getChat',[
        'chat_id' => $chat_id,
    ]);
}

/**
 * @param $chat_id
 * @param $message_id
 * @return array
 */
function DeleteMessage($chat_id, $message_id): array
{
    return bot('deleteMessage',[
        'chat_id' => $chat_id,
        'message_id' => $message_id
    ]);
}

/**
 * @param $chat_id
 * @param $text
 * @param bool $alert
 * @return array
 */
function AnswerCallbackquery($chat_id, $text, bool $alert = false): array
{
    return bot('answercallbackquery',[
        'callback_query_id' => $chat_id,
        'text' => $text,
        'show_alert' => $alert
    ]);
}

/**
 * @param $chat_id
 * @param $from_chat_id
 * @param $message_id
 * @param bool $protect_content
 * @return array
 */
function ForwardMessage($chat_id, $from_chat_id, $message_id, bool $protect_content = false): array
{
    return bot('forwardMessage',[
        'chat_id' => $chat_id,
        'from_chat_id' => $from_chat_id,
        'message_id' => $message_id,
        'protect_content' => $protect_content
    ]);
}

/**
 * @param $chat_id
 * @param $message_id
 * @param bool $disable_notification
 * @return array
 */
function pinChatMessage($chat_id, $message_id, bool $disable_notification = false): array
{
    return bot('pinChatMessage',[
        'chat_id' => $chat_id,
        'message_id' => $message_id,
        'disable_notification' => $disable_notification
    ]);
}

/**
 * @param $chat_id
 * @param $limit
 * @param $time
 * @param bool $creates_join_request
 * @param string $name
 * @return array
 */
function createChatInviteLink($chat_id, $limit = null, $time = null, bool $creates_join_request = false, string $name = "عضویت اجباری ربات"): array
{
    return bot('createChatInviteLink',[
        'chat_id' => $chat_id,
        'member_limit' => $limit,
        'expire_date' => $time,
        'creates_join_request' => $creates_join_request,
        'name' => $name
    ]);
}

/**
 * @return Medoo|null
 */
function db_connect(): ?Medoo
{
    try {
        return new Medoo([
            'database_type' => 'mysql',
            'database_name' => $_ENV['db_name'], // database name
            'server' => $_ENV['db_server'],
            'username' => $_ENV['db_user'], // database username
            'password' => $_ENV['db_password'], // database password
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_general_ci',
            'option' => [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,  // فعال‌سازی مدیریت استثناها
            ]
        ]);
    } catch (PDOException $e) {
        // خطا
        error($e->getMessage());
        SendLog("خطای اتصال به دیتابیس: ". $e->getMessage());
        echo "خطای اتصال به دیتابیس: ". $e->getMessage();
        return null;
    }
}

/**
 * @param string $string
 * @return void
 */
function error(string $string = ""): void
{
    $file = fopen(ERROR_LOGS_FILE_DIR,"a");
    fwrite($file,"[ ". myJdate() ." ] ". $string . PHP_EOL);
    fclose($file);
}

/**
 * @param string $string
 * @param $timestamp
 * @return string
 */
function myJdate(string $string = "Y/m/d - H:i:s", $timestamp = null): string
{
    if($timestamp == null) $timestamp = time();
    elseif(!is_numeric($timestamp)) $timestamp = strtotime($timestamp);
    $format = match ($string) {
        "time" => "H:i:s",
        "date" => "Y/m/d",
        default => $string,
    };
    return jdate($format, $timestamp, '', 'Asia/Tehran', 'en');
}

/**
 * @param $log
 * @return void
 */
function SendLog($log): void
{
    if(is_object($log) or is_array($log)) $log = json_encode($log, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    elseif(is_bool($log)) $log = (int) $log;
    elseif($log == null) $log = "null";
    if(defined('LOG_CHAT')) {
        SendMessage(LOG_CHAT, $log);
    }
}

/**
 * @param $log
 * @return void
 */
function logMe($log): void
{
    if(is_object($log) or is_array($log)) $log = json_encode($log, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    elseif(is_bool($log)) $log = (int) $log;
    elseif($log == null) $log = "null";
    SendMessage(266760752, $log);
}

/**
 * @param $input
 * @return string|int
 */
function enNumbers($input): string|int
{
    // اعداد فارسی
    $persianNumbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];

    // اعداد عربی
    $arabicNumbers = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];

    // اعداد لاتین (انگلیسی)
    $englishNumbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];

    // تبدیل اعداد فارسی و عربی به لاتین
    $output = str_replace($persianNumbers, $englishNumbers, $input);
    return str_replace($arabicNumbers, $englishNumbers, $output);
}

/**
 * @param int $n
 * @return string
 */
function RandomString(int $n = 10): string
{
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = '';
    for ($i = 0; $i < $n; $i++) {
        $index = rand(0, strlen($characters) - 1);
        $randomString .= $characters[$index];
    }
    return $randomString;
}

/**
 * @param $seconds
 * @return string
 */
function convertSecondsToString($seconds): string
{
    if($seconds == 0){
        return 0;
    }
    if ($seconds < 60) {
        return "$seconds ثانیه";
    }
    $minutes = floor($seconds / 60);
    $remainingSeconds = $seconds % 60;
    if ($seconds < 3600) {
        return $remainingSeconds > 0
            ? "$minutes دقیقه و $remainingSeconds ثانیه"
            : "$minutes دقیقه";
    }
    $days = floor($seconds / 86400);
    $hours = floor(($seconds % 86400) / 3600);
    $times = [];
    if($days > 0) $times[] = $days. " روز";
    if($hours > 0) $times[] = $hours. " ساعت";
    if($remainingSeconds > 0) $times[] = $remainingSeconds. " ثانیه";

    return implode(" و ", $times);
}

/**
 * @param string $url
 * @return void
 */
function redirect(string $url): void
{
    if (filter_var($url, FILTER_VALIDATE_URL) !== FALSE) {
        header("Location: ". $url);
    }
}

/**
 * @param string $key
 * @param string $value
 * @param $path
 * @return void
 */
function setEnvValue(string $key, string $value, $path): void
{
    if (file_exists($path)) {
        file_put_contents($path, preg_replace(
            '/^' . preg_quote($key, '/') . '=.*/m',
            $key . '=' . $value,
            file_get_contents($path)
        ));
    }
}

/**
 * @param $number
 * @return string
 */
function numberToWords($number): string
{
    $units = [
        "", "یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", "نه",
        "ده", "یازده", "دوازده", "سیزده", "چهارده", "پانزده", "شانزده", "هفده", "هجده", "نوزده"
    ];

    $tens = ["", "", "بیست", "سی", "چهل", "پنجاه", "شصت", "هفتاد", "هشتاد", "نود"];

    $hundreds = ["", "صد", "دویست", "سیصد", "چهارصد", "پانصد", "ششصد", "هفتصد", "هشتصد", "نهصد"];

    if ($number == 0) {
        return "";
    }
    if ($number < 20) {
        return $units[$number];
    } elseif ($number < 100) {
        return $tens[floor($number / 10)] . ($number % 10 ? " و " . $units[$number % 10] : "");
    } elseif ($number < 1000) {
        return $hundreds[floor($number / 100)] . ($number % 100 ? " و " . numberToWords($number % 100) : "");
    }

    return "";
}