<?php
// --- Function getCookieFilePath ---
function getCookieFilePath($server_id, $temp = false)
{
    $dir = __DIR__ . '/../cookies';
    if (!is_dir($dir)) {
        @mkdir($dir, 0775, true);
    }
    return $dir . '/cookie_' . $server_id . ($temp ? '_temp' : '') . '.txt';
}

// --- Helper callXuiApi ---
function callXuiApi($server_info, $endpoint, $method = 'GET', $postData = null)
{
    $serverType = $server_info['type'] ?? 'sanaei';
    $base_path = ($serverType == 'sanaei') ? '/panel' : '/xui';
    if (strpos($endpoint, '/panel/') === 0) {
        $endpoint = str_replace('/panel/', $base_path . '/', $endpoint);
    }
    
    $panel_url = rtrim($server_info['panel_url'], '/');
    $apiToken = trim($server_info['password']);
    $cookie_file = getCookieFilePath($server_info['id']);

    $runCurl = function($useToken) use ($panel_url, $apiToken, $cookie_file, $endpoint, $method, $postData) {
        $ch = curl_init();
        $headers = [
            'Accept: application/json'
        ];
        if ($useToken) {
            $headers[] = 'Authorization: Bearer ' . $apiToken;
        }

        $url = $panel_url . $endpoint;
        
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);

        if (!$useToken) {
            curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
        }

        if (strtoupper($method) == 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            if ($postData !== null) {
                if (is_array($postData) || is_object($postData)) {
                    $headers[] = 'Content-Type: application/json';
                    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
                } else {
                    curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
                }
            }
        }

        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $err = curl_error($ch);
        curl_close($ch);

        if ($response === false) {
            return ['body' => json_encode(['success' => false, 'msg' => "cURL Error: " . $err]), 'code' => $httpCode];
        }

        return ['body' => $response, 'code' => $httpCode];
    };

    // 1. Try with Bearer token first
    $res = $runCurl(true);
    logToDebug("[API CALL Bearer] " . $endpoint . " | HTTP: " . $res['code'] . " | Response: " . $res['body']);
    $decoded = json_decode($res['body']);
    $isJson = (json_last_error() === JSON_ERROR_NONE);

    // 2. Fallback to cookie login if token fails, unauthorized, or not JSON
    if ($res['code'] == 401 || $res['code'] == 403 || !$isJson || !$decoded) {
        logToDebug("[API CALL] Bearer failed, unauthorized or non-JSON, trying fallback login...");
        
        $cookie_dir = dirname($cookie_file);
        if (!is_dir($cookie_dir)) {
            @mkdir($cookie_dir, 0775, true);
        }

        // A. GET request to fetch cookies and extract CSRF token
        $chGet = curl_init();
        curl_setopt_array($chGet, [
            CURLOPT_URL => $panel_url . '/',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_COOKIEJAR => $cookie_file,
            CURLOPT_COOKIEFILE => $cookie_file,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_TIMEOUT => 10,
            CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
        ]);
        $htmlGet = curl_exec($chGet);
        curl_close($chGet);

        $csrfToken = '';
        if ($htmlGet) {
            if (preg_match('/<meta[^>]*name=["\']csrf-token["\'][^>]*content=["\']([^"\']+)["\']/i', $htmlGet, $matches)) {
                $csrfToken = $matches[1];
            } elseif (preg_match('/<meta[^>]*content=["\']([^"\']+)["\'][^>]*name=["\']csrf-token["\']/i', $htmlGet, $matches)) {
                $csrfToken = $matches[1];
            }
        }

        // B. POST request to login
        $headers = [
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
        ];
        if ($csrfToken) {
            $headers[] = 'X-Csrf-Token: ' . $csrfToken;
        }

        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $panel_url . '/login',
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query([
                "username" => $server_info['username'],
                "password" => $server_info['password']
            ]),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_COOKIEJAR => $cookie_file,
            CURLOPT_COOKIEFILE => $cookie_file,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_TIMEOUT => 10
        ]);
        $loginRes = curl_exec($ch);
        $loginCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        logToDebug("[LOGIN TRY] URL: " . $panel_url . "/login | HTTP: " . $loginCode . " | CSRF: " . ($csrfToken ? 'Found' : 'Missing') . " | Resp: " . substr(strip_tags($loginRes), 0, 100));

        // Retry using cookie
        $res = $runCurl(false);
        logToDebug("[API CALL Cookie Retry] " . $endpoint . " | HTTP: " . $res['code'] . " | Response: " . $res['body']);
        $decoded = json_decode($res['body']);

        if (json_last_error() !== JSON_ERROR_NONE) {
            $snippet = substr(strip_tags($res['body']), 0, 150);
            $decoded = (object)[
                'success' => false,
                'msg' => "Response is not JSON (HTTP: " . $res['code'] . "). Content: " . ($snippet ? $snippet : 'Empty')
            ];
            logToDebug("[API ERROR] Non-JSON response received: " . $res['body']);
        }
    }

    return $decoded;
}

// --- Helper findClientByUuidOrPassword ---
function findClientByUuidOrPassword($server_info, $uuid)
{
    $list = callXuiApi($server_info, '/panel/api/clients/list');
    if ($list && isset($list->success) && $list->success && isset($list->obj)) {
        foreach ($list->obj as $client) {
            $clientEmail = $client->email ?? '';
            $cleanEmail = str_replace('@tg.com', '', $clientEmail);
            $cleanUuid = str_replace('@tg.com', '', $uuid);
            if ((isset($client->uuid) && $client->uuid == $uuid) || 
                (isset($client->id) && $client->id == $uuid) || 
                (isset($client->password) && $client->password == $uuid) ||
                ($clientEmail == $uuid) ||
                ($cleanEmail == $cleanUuid)) {
                return $client;
            }
        }
    }
    
    // Fallback: search in inbounds list (for traditional / non-client-centric panels)
    $inbounds = getJson($server_info['id']);
    if ($inbounds && isset($inbounds->obj)) {
        foreach ($inbounds->obj as $row) {
            $settings = json_decode($row->settings ?? '{}');
            if (isset($settings->clients) && is_array($settings->clients)) {
                foreach ($settings->clients as $client) {
                    $clientId = $client->id ?? ($client->password ?? '');
                    $clientEmail = $client->email ?? '';
                    $cleanEmail = str_replace('@tg.com', '', $clientEmail);
                    $cleanUuid = str_replace('@tg.com', '', $uuid);
                    if ($clientId == $uuid || $clientEmail == $uuid || $cleanEmail == $cleanUuid) {
                        $traffic = (object)['up' => 0, 'down' => 0];
                        if (isset($row->clientStats) && is_array($row->clientStats)) {
                            foreach ($row->clientStats as $stat) {
                                if ($stat->email == $clientEmail) {
                                    $traffic = $stat;
                                    break;
                                }
                            }
                        }
                        
                        return (object)[
                            'id' => $clientId,
                            'uuid' => $clientId,
                            'password' => $clientId,
                            'email' => $clientEmail,
                            'totalGB' => $client->totalGB ?? ($traffic->total ?? 0),
                            'expiryTime' => $client->expiryTime ?? ($traffic->expiryTime ?? 0),
                            'up' => $traffic->up ?? 0,
                            'down' => $traffic->down ?? 0,
                            'enable' => $client->enable ?? ($traffic->enable ?? true),
                            'inboundIds' => [$row->id],
                            'limitIp' => $client->limitIp ?? ($traffic->limitIp ?? 0),
                            'flow' => $client->flow ?? '',
                            'subId' => $client->subId ?? '',
                            'comment' => $client->comment ?? ''
                        ];
                    }
                }
            }
        }
    }
    
    return null;
}


// --- Function deleteClient ---
function deleteClient($server_id, $inbound_id, $uuid, $delete = 0)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    
    if (!$server_info) return null;
    
    $client = findClientByUuidOrPassword($server_info, $uuid);
    if (!$client) return null;
    
    $traffic = isset($client->traffic) ? $client->traffic : (object)['up' => 0, 'down' => 0];
    $old_data = [
        'email' => $client->email,
        'id' => isset($client->uuid) ? $client->uuid : (isset($client->id) ? $client->id : ''),
        'limitIp' => isset($client->limitIp) ? $client->limitIp : 0,
        'total' => $client->totalGB,
        'expiryTime' => $client->expiryTime,
        'up' => $traffic->up,
        'down' => $traffic->down,
        'enable' => $client->enable
    ];

    $success = false;
    if ($delete == 1) {
        $base_path = ($server_info['type'] == 'sanaei') ? '/panel' : '/xui';
        $result = callXuiApi($server_info, $base_path . '/api/clients/del/' . urlencode($client->email), 'POST');
        if ($result && isset($result->success) && $result->success) {
            $success = true;
        } else {
            $inboundIds = isset($client->inboundIds) ? (array)$client->inboundIds : [$inbound_id];
            if (empty($inboundIds) || $inboundIds[0] == 0) {
                $inboundIds = [$inbound_id];
            }
            foreach ($inboundIds as $ibId) {
                if ($ibId > 0) {
                    $fbResult = callXuiApi($server_info, $base_path . '/inbound/' . $ibId . '/delClient/' . rawurlencode($uuid), 'POST');
                    if ($fbResult && isset($fbResult->success) && $fbResult->success) {
                        $success = true;
                    }
                }
            }
        }
    } else {
        $success = true;
    }
    
    return $success ? $old_data : null;
}
// --- Function editInboundRemark ---
function editInboundRemark($server_id, $uuid, $newRemark)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $serverType = $server_info['type'];

    $response = getJson($server_id);
    if (!$response)
        return null;
    $response = $response->obj;
    foreach ($response as $row) {
        $clients = json_decode($row->settings)->clients;
        if ($clients[0]->id == $uuid || $clients[0]->password == $uuid) {
            $inbound_id = $row->id;
            $total = $row->total;
            $up = $row->up;
            $down = $row->down;
            $expiryTime = $row->expiryTime;
            $port = $row->port;
            $netType = json_decode($row->streamSettings)->network;
            break;
        }
    }


    $dataArr = array('up' => $up, 'down' => $down, 'total' => $total, 'remark' => $newRemark, 'enable' => 'true',
        'expiryTime' => $row->expiryTime, 'listen' => '', 'port' => $row->port, 'protocol' => $row->protocol, 'settings' => $row->settings,
        'streamSettings' => $row->streamSettings, 'sniffing' => $row->sniffing);


    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];

    $loginUrl = $panel_url . '/login';

    $postFields = array(
        "username" => $serverName,
        "password" => $serverPass
    );

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $loginUrl);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
    curl_setopt($curl, CURLOPT_TIMEOUT, 3);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postFields));
    curl_setopt($curl, CURLOPT_HEADER, 1);
    $response = curl_exec($curl);

    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $header_size);
    $body = substr($response, $header_size);
    preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $header, $matches);
    $cookies = array();
    foreach ($matches[1] as $item) {
        parse_str($item, $cookie);
        $cookies = array_merge($cookies, $cookie);
    }

    $loginResponse = json_decode($body, true);
    if (!$loginResponse['success']) {
        curl_close($curl);
        return $loginResponse;
    }

    if ($serverType == "sanaei")
        $url = "$panel_url/panel/inbound/update/$inbound_id";
    else
        $url = "$panel_url/xui/inbound/update/$inbound_id";

    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_CONNECTTIMEOUT => 15, // timeout on connect
        CURLOPT_TIMEOUT => 15,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => $dataArr,
        CURLOPT_HEADER => false,
        CURLOPT_HTTPHEADER => array(
            'User-Agent:  Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0',
            'Accept:  application/json, text/plain, */*',
            'Accept-Language:  en-US,en;q=0.5',
            'Accept-Encoding:  gzip, deflate',
            'X-Requested-With:  XMLHttpRequest',
            'Cookie: ' . array_keys($cookies)[0] . "=" . $cookies[array_keys($cookies)[0]]
        )
    ));

    $response = curl_exec($curl);
    curl_close($curl);
    return $response = json_decode($response);
}

// --- Function editInboundTraffic ---
function editInboundTraffic($server_id, $uuid, $volume, $days, $editType = null)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $serverType = $server_info['type'];

    $response = getJson($server_id);
    if (!$response)
        return null;
    $response = $response->obj;
    $found = false;
    foreach ($response as $row) {
        $settings = json_decode($row->settings ?? '{}');
        if (isset($settings->clients) && is_array($settings->clients)) {
            foreach ($settings->clients as $client) {
                $clientId = $client->id ?? ($client->password ?? '');
                $clientEmail = $client->email ?? '';
                if ($clientId == $uuid || $clientEmail == $uuid) {
                    $inbound_id = $row->id;
                    $total = $client->totalGB ?? $row->total;
                    
                    $up = 0; $down = 0; $expiryTime = $client->expiryTime ?? $row->expiryTime;
                    if (isset($row->clientStats) && is_array($row->clientStats)) {
                        foreach ($row->clientStats as $stat) {
                            if ($stat->email == $clientEmail) {
                                $up = $stat->up ?? 0;
                                $down = $stat->down ?? 0;
                                $total = $client->totalGB ?? ($stat->total ?? 0);
                                $expiryTime = $client->expiryTime ?? ($stat->expiryTime ?? 0);
                                break;
                            }
                        }
                    } else {
                        $up = $row->up ?? 0;
                        $down = $row->down ?? 0;
                    }
                    
                    $port = $row->port;
                    $netType = json_decode($row->streamSettings ?? '{}')->network ?? 'tcp';
                    $email = $clientEmail;
                    $found = true;
                    break 2;
                }
            }
        }
    }
    if (!$found) return null;
    if ($days != 0) {
        $now_microdate = floor(microtime(true) * 1000);
        $extend_date = (864000 * $days * 100);
        $expire_microdate = ($expiryTime > $now_microdate) ? $expiryTime + $extend_date : $now_microdate + $extend_date;
    }

    if ($volume != 0) {
        $leftGB = $total - $up - $down;
        $extend_volume = floor($volume * 1073741824);
        if ($editType == "renew") {
            $total = $extend_volume;
            $up = 0;
            $down = 0;
            $volume = $extend_volume;
            if ($serverType == "sanaei" || $serverType == "alireza")
                resetClientTraffic($server_id, $email, $inbound_id);
            else
                resetClientTraffic($server_id, $email);
        }
        else
            $total = ($leftGB > 0) ? $total + $extend_volume : $extend_volume;
    }

    $dataArr = array('up' => $up, 'down' => $down, 'total' => is_null($total) ? $row->total : $total, 'remark' => $row->remark, 'enable' => 'true',
        'expiryTime' => is_null($expire_microdate) ? $row->expiryTime : $expire_microdate, 'listen' => '', 'port' => $row->port, 'protocol' => $row->protocol, 'settings' => $row->settings,
        'streamSettings' => $row->streamSettings, 'sniffing' => $row->sniffing);


    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];

    $loginUrl = $panel_url . '/login';

    $postFields = array(
        "username" => $serverName,
        "password" => $serverPass
    );

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $loginUrl);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
    curl_setopt($curl, CURLOPT_TIMEOUT, 3);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postFields));
    curl_setopt($curl, CURLOPT_HEADER, 1);
    $response = curl_exec($curl);

    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $header_size);
    $body = substr($response, $header_size);
    preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $header, $matches);
    $cookies = array();
    foreach ($matches[1] as $item) {
        parse_str($item, $cookie);
        $cookies = array_merge($cookies, $cookie);
    }

    $loginResponse = json_decode($body, true);
    if (!$loginResponse['success']) {
        curl_close($curl);
        return $loginResponse;
    }

    if ($serverType == "sanaei")
        $url = "$panel_url/panel/inbound/update/$inbound_id";
    else
        $url = "$panel_url/xui/inbound/update/$inbound_id";

    $phost = str_ireplace('https://', '', str_ireplace('http://', '', $panel_url));
    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_CONNECTTIMEOUT => 15, // timeout on connect
        CURLOPT_TIMEOUT => 15,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => $dataArr,
        CURLOPT_HEADER => false,
        CURLOPT_HTTPHEADER => array(
            'User-Agent:  Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0',
            'Accept:  application/json, text/plain, */*',
            'Accept-Language:  en-US,en;q=0.5',
            'Accept-Encoding:  gzip, deflate',
            'X-Requested-With:  XMLHttpRequest',
            'Cookie: ' . array_keys($cookies)[0] . "=" . $cookies[array_keys($cookies)[0]]
        )
    ));

    $response = curl_exec($curl);
    curl_close($curl);
    resetIpLog($server_id, $email);
    return $response = json_decode($response);
}

// --- Function changeInboundState ---
function changeInboundState($server_id, $uuid)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $serverType = $server_info['type'];

    $response = getJson($server_id);
    if (!$response)
        return null;
    $response = $response->obj;
    foreach ($response as $row) {
        $settings = json_decode($row->settings, true);
        $clients = $settings['clients'];
        if ($clients[0]['id'] == $uuid || $clients[0]['password'] == $uuid) {
            $inbound_id = $row->id;
            $enable = $row->enable;
            break;
        }
    }

    if (!isset($settings['clients'][0]['subId']) && ($serverType == "sanaei" || $serverType == "alireza"))
        $settings['clients'][0]['subId'] = RandomString(16);
    if (!isset($settings['clients'][0]['enable']) && ($serverType == "sanaei" || $serverType == "alireza"))
        $settings['clients'][0]['enable'] = true;

    $editedClient = $settings['clients'][0];
    $settings['clients'] = array_values($settings['clients']);
    $settings = json_encode($settings, 488);

    $newEnable = $enable == true ? false : true;

    $dataArr = array('up' => $row->up, 'down' => $row->down, 'total' => $row->total, 'remark' => $row->remark, 'enable' => $newEnable,
        'expiryTime' => $row->expiryTime, 'listen' => '', 'port' => $row->port, 'protocol' => $row->protocol, 'settings' => $settings,
        'streamSettings' => $row->streamSettings, 'sniffing' => $row->sniffing);


    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];

    $loginUrl = $panel_url . '/login';

    $postFields = array(
        "username" => $serverName,
        "password" => $serverPass
    );

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $loginUrl);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
    curl_setopt($curl, CURLOPT_TIMEOUT, 3);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postFields));
    curl_setopt($curl, CURLOPT_HEADER, 1);
    $response = curl_exec($curl);

    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $header_size);
    $body = substr($response, $header_size);
    preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $header, $matches);
    $cookies = array();
    foreach ($matches[1] as $item) {
        parse_str($item, $cookie);
        $cookies = array_merge($cookies, $cookie);
    }


    $loginResponse = json_decode($body, true);
    if (!$loginResponse['success']) {
        curl_close($curl);
        return $loginResponse;
    }

    if ($serverType == "sanaei")
        $url = "$panel_url/panel/inbound/update/$inbound_id";
    else
        $url = "$panel_url/xui/inbound/update/$inbound_id";

    $phost = str_ireplace('https://', '', str_ireplace('http://', '', $panel_url));
    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_CONNECTTIMEOUT => 15, // timeout on connect
        CURLOPT_TIMEOUT => 15,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => $dataArr,
        CURLOPT_HEADER => false,
        CURLOPT_HTTPHEADER => array(
            'User-Agent:  Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0',
            'Accept:  application/json, text/plain, */*',
            'Accept-Language:  en-US,en;q=0.5',
            'Accept-Encoding:  gzip, deflate',
            'X-Requested-With:  XMLHttpRequest',
            'Cookie: ' . array_keys($cookies)[0] . "=" . $cookies[array_keys($cookies)[0]]
        )
    ));

    $response = curl_exec($curl);
    curl_close($curl);

    $response = json_decode($response);
    return $response;

}

// --- Function renewInboundUuid ---
function renewInboundUuid($server_id, $uuid)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $serverType = $server_info['type'];

    $response = getJson($server_id);
    if (!$response)
        return null;
    $response = $response->obj;
    foreach ($response as $row) {
        $settings = json_decode($row->settings, true);
        $clients = $settings['clients'];
        if ($clients[0]['id'] == $uuid || $clients[0]['password'] == $uuid) {
            $inbound_id = $row->id;
            $total = $row->total;
            $up = $row->up;
            $down = $row->down;
            $expiryTime = $row->expiryTime;
            $port = $row->port;
            $protocol = $row->protocol;
            $netType = json_decode($row->streamSettings)->network;
            break;
        }
    }

    $newUuid = generateRandomString(42, $protocol);
    if ($protocol == "trojan")
        $settings['clients'][0]['password'] = $newUuid;
    else
        $settings['clients'][0]['id'] = $newUuid;
    if (!isset($settings['clients'][0]['subId']) && ($serverType == "sanaei" || $serverType == "alireza"))
        $settings['clients'][0]['subId'] = RandomString(16);
    if (!isset($settings['clients'][0]['enable']) && ($serverType == "sanaei" || $serverType == "alireza"))
        $settings['clients'][0]['enable'] = true;

    $editedClient = $settings['clients'][0];
    $settings['clients'] = array_values($settings['clients']);
    $settings = json_encode($settings, 488);


    $dataArr = array('up' => $row->up, 'down' => $row->down, 'total' => $row->total, 'remark' => $row->remark, 'enable' => 'true',
        'expiryTime' => $row->expiryTime, 'listen' => '', 'port' => $row->port, 'protocol' => $row->protocol, 'settings' => $settings,
        'streamSettings' => $row->streamSettings, 'sniffing' => $row->sniffing);


    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];

    $loginUrl = $panel_url . '/login';

    $postFields = array(
        "username" => $serverName,
        "password" => $serverPass
    );

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $loginUrl);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
    curl_setopt($curl, CURLOPT_TIMEOUT, 3);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postFields));
    curl_setopt($curl, CURLOPT_HEADER, 1);
    $response = curl_exec($curl);

    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $header_size);
    $body = substr($response, $header_size);
    preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $header, $matches);
    $cookies = array();
    foreach ($matches[1] as $item) {
        parse_str($item, $cookie);
        $cookies = array_merge($cookies, $cookie);
    }

    $loginResponse = json_decode($body, true);
    if (!$loginResponse['success']) {
        curl_close($curl);
        return $loginResponse;
    }

    if ($serverType == "sanaei")
        $url = "$panel_url/panel/inbound/update/$inbound_id";
    else
        $url = "$panel_url/xui/inbound/update/$inbound_id";

    $phost = str_ireplace('https://', '', str_ireplace('http://', '', $panel_url));
    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_CONNECTTIMEOUT => 15, // timeout on connect
        CURLOPT_TIMEOUT => 15,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => $dataArr,
        CURLOPT_HEADER => false,
        CURLOPT_HTTPHEADER => array(
            'User-Agent:  Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0',
            'Accept:  application/json, text/plain, */*',
            'Accept-Language:  en-US,en;q=0.5',
            'Accept-Encoding:  gzip, deflate',
            'X-Requested-With:  XMLHttpRequest',
            'Cookie: ' . array_keys($cookies)[0] . "=" . $cookies[array_keys($cookies)[0]]
        )
    ));

    $response = curl_exec($curl);
    curl_close($curl);
    $response = json_decode($response);
    $response->newUuid = $newUuid;
    return $response;

}

// --- Function changeClientState ---
function changeClientState($server_id, $inbound_id, $uuid)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    if (!$server_info) return null;

    $client = findClientByUuidOrPassword($server_info, $uuid);
    if (!$client) return null;

    $email = $client->email;
    $enable = isset($client->enable) ? $client->enable : true;
    $new_enable = !$enable;

    $groupName = determineClientGroup($email);

    $postData = [
        "email" => $client->email,
        "totalGB" => isset($client->totalGB) ? $client->totalGB : 0,
        "expiryTime" => isset($client->expiryTime) ? $client->expiryTime : 0,
        "tgId" => isset($client->tgId) ? $client->tgId : 0,
        "limitIp" => isset($client->limitIp) ? $client->limitIp : 0,
        "enable" => $new_enable,
        "id" => isset($client->uuid) ? $client->uuid : (isset($client->id) ? $client->id : ''),
        "flow" => isset($client->flow) ? $client->flow : '',
        "subId" => isset($client->subId) ? $client->subId : RandomString(16),
        "comment" => isset($client->comment) ? $client->comment : '',
        "group_name" => $groupName
    ];

    if (isset($client->password)) {
        $postData['password'] = $client->password;
    }

    $result = callXuiApi($server_info, '/panel/api/clients/update/' . urlencode($email), 'POST', $postData);

    if (!$result || !isset($result->success) || !$result->success) {
        return false;
    }
    return true;
}
// --- Function renewClientUuid ---
function renewClientUuid($server_id, $inbound_id, $uuid)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    if (!$server_info) return null;

    $client = findClientByUuidOrPassword($server_info, $uuid);
    if (!$client) return null;

    $email = $client->email;
    $newUuid = "";
    
    if (isset($client->password)) {
        $newUuid = RandomString(16);
        $client->password = $newUuid;
    } else {
        $uuidRes = callXuiApi($server_info, '/panel/api/server/getNewUUID');
        if ($uuidRes && isset($uuidRes->success) && $uuidRes->success && isset($uuidRes->obj)) {
            $newUuid = $uuidRes->obj;
        } else {
            $newUuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
                mt_rand(0, 0xffff), mt_rand(0, 0xffff),
                mt_rand(0, 0xffff),
                mt_rand(0, 0x0fff) | 0x4000,
                mt_rand(0, 0x3fff) | 0x8000,
                mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
            );
        }
        $client->uuid = $newUuid;
    }

    $groupName = determineClientGroup($email);

    $postData = [
        "email" => $client->email,
        "totalGB" => isset($client->totalGB) ? $client->totalGB : 0,
        "expiryTime" => isset($client->expiryTime) ? $client->expiryTime : 0,
        "tgId" => isset($client->tgId) ? $client->tgId : 0,
        "limitIp" => isset($client->limitIp) ? $client->limitIp : 0,
        "enable" => isset($client->enable) ? $client->enable : true,
        "id" => isset($client->uuid) ? $client->uuid : (isset($client->id) ? $client->id : ''),
        "flow" => isset($client->flow) ? $client->flow : '',
        "subId" => isset($client->subId) ? $client->subId : RandomString(16),
        "comment" => isset($client->comment) ? $client->comment : '',
        "group_name" => $groupName
    ];

    if (isset($client->password)) {
        $postData['password'] = $client->password;
    }

    $result = callXuiApi($server_info, '/panel/api/clients/update/' . urlencode($email), 'POST', $postData);

    if (!$result || !isset($result->success) || !$result->success) {
        return null;
    }
    return $newUuid;
}
// --- Function editClientRemark ---
function editClientRemark($server_id, $inbound_id, $uuid, $newRemark)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    if (!$server_info) return null;

    $client = findClientByUuidOrPassword($server_info, $uuid);
    if (!$client) return null;

    $oldEmail = $client->email;

    $groupName = determineClientGroup($newRemark);

    $postData = [
        "email" => $newRemark,
        "totalGB" => isset($client->totalGB) ? $client->totalGB : 0,
        "expiryTime" => isset($client->expiryTime) ? $client->expiryTime : 0,
        "tgId" => isset($client->tgId) ? $client->tgId : 0,
        "limitIp" => isset($client->limitIp) ? $client->limitIp : 0,
        "enable" => isset($client->enable) ? $client->enable : true,
        "id" => isset($client->uuid) ? $client->uuid : (isset($client->id) ? $client->id : ''),
        "flow" => isset($client->flow) ? $client->flow : '',
        "subId" => isset($client->subId) ? $client->subId : RandomString(16),
        "comment" => isset($client->comment) ? $client->comment : '',
        "group_name" => $groupName
    ];

    if (isset($client->password)) {
        $postData['password'] = $client->password;
    }

    $result = callXuiApi($server_info, '/panel/api/clients/update/' . urlencode($oldEmail), 'POST', $postData);

    if (!$result || !isset($result->success) || !$result->success) {
        return false;
    }
    return true;
}

// --- Function determineClientGroup ---
function determineClientGroup($email) {
    global $connection;
    // 1. Check if it's a Gift
    if (stripos($email, 'Gift') !== false) {
        return 'Gift';
    }
    
    // 2. Check if the email itself contains agency indicators
    if (stripos($email, 'agency') !== false || stripos($email, 'agent') !== false) {
        return 'agency';
    }

    // 2.5 Check if the email itself contains Proxy indicator
    if (stripos($email, 'Proxy') !== false) {
        return 'Proxy';
    }

    // 3. Query orders_list to see inbound_id or agent_bought
    $stmt = $connection->prepare("SELECT `agent_bought`, `inbound_id` FROM `orders_list` WHERE `remark` = ? LIMIT 1");
    if ($stmt) {
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $res = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        if (isset($res['inbound_id']) && (intval($res['inbound_id']) == 7 || $res['inbound_id'] == '7')) {
            return 'Proxy';
        }
        if (isset($res['agent_bought']) && $res['agent_bought'] == 1) {
            return 'agency';
        }
    }

    $stmt2 = $connection->prepare("SELECT `agent_bought` FROM `pays` WHERE `description` = ? LIMIT 1");
    if ($stmt2) {
        $stmt2->bind_param("s", $email);
        $stmt2->execute();
        $res2 = $stmt2->get_result()->fetch_assoc();
        $stmt2->close();
        if (isset($res2['agent_bought']) && $res2['agent_bought'] == 1) {
            return 'agency';
        }
    }

    // 4. Default to Client
    return 'Client';
}
// --- Function editClientTraffic ---
function editClientTraffic($server_id, $inbound_id, $uuid, $volume, $days, $editType = null)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    if (!$server_info) return null;

    $client = findClientByUuidOrPassword($server_info, $uuid);
    if (!$client) return null;

    $email = $client->email;
    $totalGB = isset($client->totalGB) ? $client->totalGB : 0;
    $expiryTime = isset($client->expiryTime) ? $client->expiryTime : 0;

    if ($volume != 0) {
        $extend_volume = floor($volume * 1073741824);
        $new_total = ($totalGB > 0) ? $totalGB + $extend_volume : $extend_volume;
        
        if ($editType == "renew") {
            $new_total = $extend_volume;
            callXuiApi($server_info, '/panel/api/clients/resetTraffic/' . urlencode($email), 'POST');
        }
        $client->totalGB = $new_total;
    }

    if ($days != 0) {
        $now_microdate = floor(microtime(true) * 1000);
        $extend_date = (864000 * $days * 100);
        
        $expire_microdate = ($expiryTime > $now_microdate) ? $expiryTime + $extend_date : $now_microdate + $extend_date;
        $client->expiryTime = $expire_microdate;
    }

    $client->enable = true;

    $groupName = determineClientGroup($email);

    $postData = [
        "email" => $client->email,
        "totalGB" => $client->totalGB,
        "expiryTime" => $client->expiryTime,
        "tgId" => isset($client->tgId) ? $client->tgId : 0,
        "limitIp" => isset($client->limitIp) ? $client->limitIp : 0,
        "enable" => true,
        "id" => isset($client->uuid) ? $client->uuid : (isset($client->id) ? $client->id : ''),
        "flow" => isset($client->flow) ? $client->flow : '',
        "subId" => isset($client->subId) ? $client->subId : RandomString(16),
        "comment" => isset($client->comment) ? $client->comment : '',
        "group_name" => $groupName
    ];

    if (isset($client->password)) {
        $postData['password'] = $client->password;
    }

    $result = callXuiApi($server_info, '/panel/api/clients/update/' . urlencode($email), 'POST', $postData);

    if (!$result || !isset($result->success) || !$result->success) {
        // Fallback to traditional inbound update
        $fallback = editInboundTraffic($server_id, $uuid, $volume, $days, $editType);
        if (is_null($fallback)) {
            return (object)['success' => false, 'msg' => 'Fallback inbound update failed or returned null'];
        }
        return $fallback;
    }
    return $result;
}
// --- Function is_radial_iterable ---
function is_radial_iterable($var) {
    return $var !== null && (is_array($var) || is_object($var));
}

// --- Function deleteInbound ---
function deleteInbound($server_id, $uuid, $delete = 0)
{
    global $connection;

    // دریافت اطلاعات سرور
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    if (!$server_info)
        return null;

    $panel_url = $server_info['panel_url'];
    $serverType = $server_info['type'];

    // دریافت لیست اینباندها
    $response = getJson($server_id);
    if (!$response || !isset($response->obj))
        return null;

    $response = $response->obj;
    $inbound_id = null;
    $oldData = null;

    // جستجو برای یافتن کاربر در تمام کلاینت‌های اینباندها
    foreach ($response as $row) {
        $settings = json_decode($row->settings);

        if (!isset($settings->clients) || !is_array($settings->clients)) {
            continue;
        }

        foreach ($settings->clients as $client) {
            $clientId = isset($client->id) ? $client->id : (isset($client->password) ? $client->password : '');
            $clientEmail = $client->email ?? '';
            $cleanEmail = str_replace('@tg.com', '', $clientEmail);
            $cleanUuid = str_replace('@tg.com', '', $uuid);

            if ($clientId == $uuid || $clientEmail == $uuid || $cleanEmail == $cleanUuid) {
                $inbound_id = $row->id;
                $protocol = $row->protocol;
                $uniqid = ($protocol == 'trojan') ? ($client->password ?? '') : ($client->id ?? '');

                $streamSettings = json_decode($row->streamSettings);
                $netType = $streamSettings->network ?? 'tcp';
                $security = $streamSettings->security ?? 'none';

                $oldData = [
                    'total' => $client->totalGB ?? $row->total,
                    'up' => $client->up ?? $row->up,
                    'down' => $client->down ?? $row->down,
                    'volume' => isset($client->totalGB) ? ($client->totalGB - ($client->up ?? 0) - ($client->down ?? 0)) : ((int)$row->total - (int)$row->up - (int)$row->down),
                    'port' => $row->port,
                    'protocol' => $protocol,
                    'expiryTime' => $client->expiryTime ?? $row->expiryTime,
                    'uniqid' => $uniqid,
                    'netType' => $netType,
                    'security' => $security,
                ];
                break 2;
            }
        }
    }

    // اگر کاربر پیدا نشد یا دیتایی وجود نداشت
    if ($inbound_id === null || $oldData === null) {
        return null;
    }

    // عملیات حذف فیزیکی از پنل
    if ($delete == 1) {
        $serverName = $server_info['username'];
        $serverPass = $server_info['password'];

        $loginUrl = $panel_url . '/login';

        $postFields = array(
            "username" => $serverName,
            "password" => $serverPass
        );

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $loginUrl);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
        curl_setopt($curl, CURLOPT_TIMEOUT, 3);
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postFields));
        curl_setopt($curl, CURLOPT_HEADER, 1);
        $loginCurlResponse = curl_exec($curl);

        $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
        $header = substr($loginCurlResponse, 0, $header_size);
        $body = substr($loginCurlResponse, $header_size);
        preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $header, $matches);
        $cookies = array();
        foreach ($matches[1] as $item) {
            parse_str($item, $cookie);
            $cookies = array_merge($cookies, $cookie);
        }

        $loginResponse = json_decode($body, true);

        // اگر لاگین ناموفق بود
        if (!$loginResponse || !isset($loginResponse['success']) || !$loginResponse['success']) {
            curl_close($curl);
            return null; // برگرداندن null به جای ارور
        }

        $base_path = ($serverType == 'sanaei') ? '/panel' : '/xui';
        $inboundClientsCount = 1;
        foreach ($response as $row) {
            if ($row->id == $inbound_id) {
                $sett = json_decode($row->settings);
                if (isset($sett->clients) && is_array($sett->clients)) {
                    $inboundClientsCount = count($sett->clients);
                }
                break;
            }
        }

        if ($inboundClientsCount > 1) {
            $url = $panel_url . $base_path . "/inbound/" . $inbound_id . "/delClient/" . rawurlencode($uuid);
        } else {
            if ($serverType == "sanaei")
                $url = "$panel_url/panel/inbound/del/$inbound_id";
            else
                $url = "$panel_url/xui/inbound/del/$inbound_id";
        }

        // اطمینان از وجود کوکی قبل از ارسال درخواست
        $cookieStr = "";
        if (!empty($cookies)) {
            $key = array_keys($cookies)[0];
            $cookieStr = $key . "=" . $cookies[$key];
        }

        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_CONNECTTIMEOUT => 15,
            CURLOPT_TIMEOUT => 15,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_HEADER => false,
            CURLOPT_HTTPHEADER => array(
                'User-Agent:  Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0',
                'Accept:  application/json, text/plain, */*',
                'Accept-Language:  en-US,en;q=0.5',
                'Accept-Encoding:  gzip, deflate',
                'X-Requested-With:  XMLHttpRequest',
                'Cookie: ' . $cookieStr
            )
        ));
        $response = curl_exec($curl);
        curl_close($curl);
    }

    return $oldData;
}

// --- Function resetIpLog ---
function resetIpLog($server_id, $remark)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    $panel_url = $server_info['panel_url'];
    $serverType = $server_info['type'];


    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];

    $loginUrl = $panel_url . '/login';

    $postFields = array(
        "username" => $serverName,
        "password" => $serverPass
    );

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $loginUrl);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
    curl_setopt($curl, CURLOPT_TIMEOUT, 3);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postFields));
    curl_setopt($curl, CURLOPT_HEADER, 1);
    $response = curl_exec($curl);

    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $header_size);
    $body = substr($response, $header_size);
    preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $header, $matches);
    $cookies = array();
    foreach ($matches[1] as $item) {
        parse_str($item, $cookie);
        $cookies = array_merge($cookies, $cookie);
    }

    $loginResponse = json_decode($body, true);
    if (!$loginResponse['success']) {
        curl_close($curl);
        return $loginResponse;
    }

    if ($serverType == "sanaei")
        $url = $panel_url . "/panel/inbound/clearClientIps/" . urlencode($remark);
    else
        $url = $panel_url . "/xui/inbound/clearClientIps/" . urlencode($remark);

    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_CONNECTTIMEOUT => 15,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_HEADER => false,
        CURLOPT_HTTPHEADER => array(
            'User-Agent:  Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0',
            'Accept:  application/json, text/plain, */*',
            'Accept-Language:  en-US,en;q=0.5',
            'Accept-Encoding:  gzip, deflate',
            'X-Requested-With:  XMLHttpRequest',
            'Cookie: ' . array_keys($cookies)[0] . "=" . $cookies[array_keys($cookies)[0]]
        )
    ));

    $response = curl_exec($curl);
    curl_close($curl);
    return $response = json_decode($response);
}

// --- Function resetClientTraffic ---
function resetClientTraffic($server_id, $remark, $inboundId = null)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    if (!$server_info) return null;

    $result = callXuiApi($server_info, '/panel/api/clients/resetTraffic/' . urlencode($remark), 'POST');
    return $result;
}
// --- Function logToDebug ---
    function logToDebug($text)
    {
        $logDir = dirname(__DIR__) . '/storage/logs';
        if (!is_dir($logDir)) {
            @mkdir($logDir, 0775, true);
        }
        $logFile = $logDir . '/api_debug.txt';
        $time = date("Y-m-d H:i:s");
        @file_put_contents($logFile, "[$time] $text" . PHP_EOL, FILE_APPEND);
    }

// --- Function addInboundAccount ---
function addInboundAccount($server_id, $client_id, $inbound_id, $expiryTime, $remark, $volume, $limitip = 1, $newarr = '', $planId = null)
{
    global $connection;

    set_time_limit(0);
    ignore_user_abort(true);

    $target_inbounds = [];

    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    if (!$server_info) {
        logToDebug("❌ Server Info Not Found");
        return (object)['success' => false, 'msg' => 'Server DB info not found'];
    }

    $flow = "xtls-rprx-vision";
    if ($planId) {
        $stmt = $connection->prepare("SELECT flow, inbound_id FROM `server_plans` WHERE `id`=?");
        $stmt->bind_param("i", $planId);
        $stmt->execute();
        $res = $stmt->get_result()->fetch_assoc();
        $stmt->close();
        if (isset($res['flow']) && $res['flow'] != "None" && $res['flow'] != "")
            $flow = $res['flow'];
        if (!empty($res['inbound_id'])) {
            $target_inbounds = array_map('intval', explode(',', $res['inbound_id']));
        }
    }

    $sharedSubId = RandomString(16);

    logToDebug("---------------- START ORDER ($remark) ----------------");
    logToDebug("🔑 Shared SubID: $sharedSubId");

    $inboundIds = [(int)$inbound_id];
    if (!empty($target_inbounds)) {
        foreach ($target_inbounds as $extra_id) {
            if ($extra_id != $inbound_id) {
                $inboundIds[] = (int)$extra_id;
            }
        }
    }
    $inboundIds = array_unique($inboundIds);

    // پویاسازی اتصال به کل اینباندها در صورت صفر بودن آیدی در پنل‌های غیر مارزبان
    if ($server_info['type'] !== 'marzban' && (in_array(0, $inboundIds) || empty($inboundIds))) {
        $dynamicInboundIds = [];
        $apiUrl = rtrim($server_info['panel_url'], '/') . '/panel/api/inbounds/list';
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json', 'Authorization: Bearer ' . trim($server_info['password'])]);
        $res = curl_exec($ch);
        curl_close($ch);

        $resDecoded = json_decode($res, true);
        if (isset($resDecoded['success']) && $resDecoded['success'] && is_array($resDecoded['obj'])) {
            foreach ($resDecoded['obj'] as $inbound) {
                $ibId = intval($inbound['id']);
                if ($inbound['enable'] && $ibId !== 7) {
                    $dynamicInboundIds[] = $ibId;
                }
            }
        }
        if (!empty($dynamicInboundIds)) {
            $inboundIds = $dynamicInboundIds;
        } else {
            $inboundIds = array_values(array_filter($inboundIds, function($id) { return $id > 0; }));
            if (empty($inboundIds)) {
                $inboundIds = [1];
            }
        }
    }

    $uuid = ($client_id != "") ? $client_id : generateUID();

    $mainResult = addClient($server_info, $inboundIds, $remark, $uuid, $limitip, $volume, $expiryTime, true, $flow, $sharedSubId);

    if (!isset($mainResult['success']) || !$mainResult['success']) {
        logToDebug("❌ Add Client Failed: " . json_encode($mainResult));
        return (object)$mainResult;
    }
    logToDebug("✅ Client ($remark) Created.");

    $parsed = parse_url($server_info['panel_url']);
    $scheme = isset($parsed['scheme']) ? $parsed['scheme'] : 'https';
    $host = isset($parsed['host']) ? $parsed['host'] : $server_info['panel_url'];
    $host = str_replace(['http://', 'https://', '/'], '', $host);

    $subLink = "$scheme://$host:2096/sub/$sharedSubId";

    logToDebug("🔗 Final SubLink: $subLink");
    logToDebug("---------------- END ORDER ----------------");

    return (object)[
        'success' => true,
        'msg' => "اشتراک شما ایجاد شد.",
        'subLink' => $subLink
    ];
}
// --- Function addClient ---
function addClient($server_info_arr, $inbound_id, $email, $uuid, $limitIp, $totalGB, $expiryTime, $enable = true, $flow = "", $forcedSubId = "", $cookie_file = null)
{
    $totalBytes = ($totalGB == 0) ? 0 : floor($totalGB * 1073741824);
    $expiryTimeMs = $expiryTime > 0 ? (int)$expiryTime : 0;
    $subId = ($forcedSubId != "") ? $forcedSubId : RandomString(16);

    $groupName = determineClientGroup($email);

    $newClient = [
        "id" => $uuid,
        "email" => $email,
        "limitIp" => (int)$limitIp,
        "totalGB" => (int)$totalBytes,
        "expiryTime" => $expiryTimeMs,
        "enable" => $enable,
        "tgId" => 0,
        "subId" => $subId,
        "flow" => $flow,
        "group_name" => $groupName,
        "groupName" => $groupName,
        "group" => $groupName
    ];

    $inboundIdsArray = is_array($inbound_id) ? $inbound_id : [(int)$inbound_id];

    $postData = [
        "client" => $newClient,
        "inboundIds" => $inboundIdsArray
    ];

    $result = callXuiApi($server_info_arr, '/panel/api/clients/add', 'POST', $postData);

    if (!$result || !isset($result->success) || !$result->success) {
        $msg = isset($result->msg) ? $result->msg : "Unknown Error";
        return ['success' => false, 'msg' => $msg];
    }

    $parsed = parse_url($server_info_arr['panel_url']);
    $scheme = isset($parsed['scheme']) ? $parsed['scheme'] : 'https';
    $host = isset($parsed['host']) ? $parsed['host'] : $server_info_arr['panel_url'];
    $host = str_replace(['http://', 'https://', '/'], '', $host);
    $subLink = "$scheme://$host:2096/sub/$subId";

    return [
        'success' => true,
        'msg' => "اشتراک شما ایجاد شد.",
        'subLink' => $subLink
    ];
}
// --- Function getNewHeaders ---
function getNewHeaders($netType, $request_header, $response_header, $type)
{
    global $connection;

    // --- اصلاح شروع: تعیین مقادیر پیش‌فرض برای جلوگیری از ارور ---
    $key = "Host";
    $value = "www.google.com";
    $reskey = "Content-Type";
    $resvalue = "application/json";

    // بررسی و پردازش هدر درخواست (Request Header)
    if (!empty($request_header) && strpos($request_header, ':') !== false) {
        $input = explode(':', $request_header, 2); // عدد 2 یعنی حداکثر به 2 تکه تقسیم کن
        if (isset($input[0]))
            $key = trim($input[0]);
        if (isset($input[1]))
            $value = trim($input[1]);
    }

    // بررسی و پردازش هدر پاسخ (Response Header)
    if (!empty($response_header) && strpos($response_header, ':') !== false) {
        $input = explode(':', $response_header, 2);
        if (isset($input[0]))
            $reskey = trim($input[0]);
        if (isset($input[1]))
            $resvalue = trim($input[1]);
    }
    // --- اصلاح پایان ---

    $headers = '';
    if ($netType == 'tcp') {
        if ($type == 'none') {
            $headers = '{
              "type": "none"
            }';
        }
        else {
            $headers = '{
              "type": "http",
              "request": {
                "method": "GET",
                "path": [
                  "/"
                ],
                "headers": {
                   "' . $key . '": [
                     "' . $value . '"
                  ]
                }
              },
              "response": {
                "version": "1.1",
                "status": "200",
                "reason": "OK",
                "headers": {
                   "' . $reskey . '": [
                     "' . $resvalue . '"
                  ]
                }
              }
            }';
        }

    }
    elseif ($netType == 'ws') {
        if ($type == 'none') {
            $headers = '{}';
        }
        else {
            $headers = '{
              "' . $key . '": "' . $value . '"
            }';
        }
    }
    return $headers;
}

// --- Function getConnectionLink ---
function getConnectionLink($server_id, $uniqid, $protocol, $remark, $port, $netType, $inbound_id = 0, $rahgozar = false, $customPath = false, $customPort = 0, $customSni = null)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    if (!$server_info)
        return []; // جلوگیری از ارور در صورت نبود سرور

    $panel_url = $server_info['panel_url'];
    $server_ip = $server_info['ip'];
    $sni = $server_info['sni'];
    $header_type = $server_info['header_type'];
    $request_header = $server_info['request_header'];
    $serverType = $server_info['type'];

    // استخراج هاست از هدر
    $host = "";
    if (preg_match("/^Host:(.*)/i", $request_header, $hostMatch)) {
        $host = trim($hostMatch[1]);
    }

    // تمیزکاری آدرس پنل
    $panel_url_clean = str_ireplace(['http://', 'https://'], '', $panel_url);
    $panel_url_clean = strtok($panel_url_clean, ":");
    if ($server_ip == '')
        $server_ip = $panel_url_clean;

    // دریافت لیست از تابع getJson
    $jsonResult = getJson($server_id);
    $response = isset($jsonResult->obj) ? $jsonResult->obj : [];

    foreach ($response as $row) {
        // پیدا کردن تنظیمات مربوطه
        $found = false;
        $rowSettings = json_decode($row->settings);

        if ($inbound_id == 0) {
            $clients = $rowSettings->clients ?? [];
            if (isset($clients[0]) && (($clients[0]->id ?? '') == $uniqid || ($clients[0]->password ?? '') == $uniqid)) {
                $found = true;
            }
        }
        else {
            if ($row->id == $inbound_id)
                $found = true;
        }

        if ($found) {
            // تنظیم ریمارک
            if ($serverType == "sanaei" || $serverType == "alireza") {
                if (isset($rowSettings->clients)) {
                    foreach ($rowSettings->clients as $c) {
                        if (($c->id ?? '') == $uniqid || ($c->password ?? '') == $uniqid) {
                            $flow = $c->flow ?? '';
                            // $remark = $c->email ?? $remark; 
                            break;
                        }
                    }
                }
            }

            // خواندن تنظیمات استریم با چک کردن null
            $streamSettings = json_decode($row->streamSettings);
            $tlsStatus = $streamSettings->security ?? 'none';
            $netType = $streamSettings->network ?? 'tcp';

            $tcpSettings = $streamSettings->tcpSettings ?? null;
            $wsSettings = $streamSettings->wsSettings ?? null;
            $grpcSettings = $streamSettings->grpcSettings ?? null;
            $tlsSettings = $streamSettings->tlsSettings ?? null;
            $realitySettings = $streamSettings->realitySettings ?? null;
            $xtlsSettings = $streamSettings->xtlsSettings ?? null;

            $path = "";
            $alpn = "";
            $serviceName = "";
            $fp = "";
            $pbk = "";
            $sid = "";
            $spiderX = "";

            // استخراج اطلاعات بر اساس شبکه
            if ($netType == 'tcp' && $tcpSettings) {
                $header_type = $tcpSettings->header->type ?? 'none';
                if (isset($tcpSettings->header->request)) {
                    $path = $tcpSettings->header->request->path[0] ?? '/';
                    $host = $tcpSettings->header->request->headers->Host[0] ?? $host;
                }
            }
            elseif ($netType == 'ws' && $wsSettings) {
                $header_type = $wsSettings->header->type ?? 'none';
                $path = $wsSettings->path ?? '/';
                $host = $wsSettings->headers->Host ?? $host;
            }
            elseif ($netType == 'grpc' && $grpcSettings) {
                $serviceName = $grpcSettings->serviceName ?? '';
            }

            // استخراج اطلاعات امنیتی (TLS/Reality)
            if ($tlsStatus == "reality" && $realitySettings) {
                $fp = $realitySettings->settings->fingerprint ?? 'chrome';
                $spiderX = $realitySettings->settings->spiderX ?? '';
                $pbk = $realitySettings->settings->publicKey ?? '';
                $sid = $realitySettings->shortIds[0] ?? '';
                $sni = $realitySettings->serverNames[0] ?? $sni;
            }
            elseif ($tlsStatus == 'tls' && $tlsSettings) {
                $sni = $tlsSettings->serverName ?? ($tlsSettings->settings->serverName ?? $sni);
                $alpn = $tlsSettings->alpn ?? '';
            }
            elseif ($tlsStatus == 'xtls' && $xtlsSettings) {
                $sni = $xtlsSettings->serverName ?? ($xtlsSettings->settings->serverName ?? $sni);
                $alpn = $xtlsSettings->alpn ?? '';
                $flow = "xtls-rprx-direct";
            }

            break; // تنظیمات پیدا شد، حلقه را قطع کن
        }
    }

    // ساخت لینک خروجی
    $protocol = strtolower($protocol);
    $serverIpList = explode("\n", $server_ip);
    $outputLink = array();

    foreach ($serverIpList as $srv_ip) {
        $srv_ip = trim($srv_ip);
        if (empty($srv_ip))
            continue;

        $finalPort = ($rahgozar && $customPort != 0) ? $customPort : $port;

        // تنظیم SNI و هاست برای رهگذر/دامین
        if ($rahgozar) {
            if (!empty($host)) {
                $parseAdd = parse_url($host);
                $hostDomain = $parseAdd['host'] ?? $parseAdd['path'];
                $explodeAdd = explode(".", $hostDomain);
                if ($customSni != null)
                    $sni = $customSni;
                else {
                    $sni = (count($explodeAdd) >= 3) ? "$uniqid.{$explodeAdd[1]}.{$explodeAdd[2]}" : "$uniqid.$hostDomain";
                }
            }
        }

        $link = "";

        if ($protocol == 'vless' || $protocol == 'trojan') {
            $query = [];
            $query['type'] = $netType;
            $query['security'] = ($rahgozar) ? 'tls' : $tlsStatus;

            if ($netType == 'tcp' && $header_type == 'http')
                $query['headerType'] = 'http';
            if ($netType == 'ws' || ($netType == 'tcp' && $header_type == 'http')) {
                $query['path'] = urlencode($path . ($customPath ? "?ed=2048" : ""));
                if (!empty($host))
                    $query['host'] = $host;
            }

            if ($tlsStatus == 'reality') {
                $query['fp'] = $fp;
                $query['pbk'] = $pbk;
                $query['sni'] = $sni;
                $query['sid'] = $sid;
                if (!empty($spiderX))
                    $query['spx'] = $spiderX;
                if (!empty($flow))
                    $query['flow'] = $flow;
            }
            elseif (!empty($sni)) {
                $query['sni'] = $sni;
            }

            if ($tlsStatus == 'xtls' && !empty($flow))
                $query['flow'] = $flow;

            if ($netType == 'grpc') {
                $query['serviceName'] = $serviceName;
                if ($netType == 'grpc' && $tlsStatus == 'none')
                    $query['mode'] = 'gun'; // for some clients
            }

            // ساخت رشته کوئری
            $queryString = http_build_query($query);
            // اصلاح فرمت کوئری برای سازگاری بهتر (v2ray استاندارد)
            $link = "$protocol://$uniqid@$srv_ip:$finalPort?$queryString#" . rawurlencode($remark);
        }
        elseif ($protocol == 'vmess') {
            $vmessArr = [
                "v" => "2",
                "ps" => $remark,
                "add" => $srv_ip,
                "port" => (string)$finalPort,
                "id" => $uniqid,
                "aid" => "0",
                "net" => $netType,
                "type" => ($header_type != 'none') ? $header_type : "none",
                "host" => !empty($host) ? $host : "",
                "path" => !empty($path) ? $path : "",
                "tls" => ($rahgozar || $tlsStatus == 'tls') ? "tls" : "none"
            ];

            if ($netType == 'grpc') {
                $vmessArr['path'] = $serviceName;
                $vmessArr['type'] = 'gun'; // معمولا gun است
            }
            if (!empty($sni))
                $vmessArr['sni'] = $sni;

            $link = "vmess://" . base64_encode(json_encode($vmessArr));
        }

        if (!empty($link))
            $outputLink[] = $link;
    }

    return $outputLink;
}

// --- Function updateConfig ---
function updateConfig($server_id, $inboundId, $protocol, $netType = 'tcp', $security = 'none', $rahgozar = false)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $security = $server_info['security'];
    $tlsSettings = $server_info['tlsSettings'];
    $header_type = $server_info['header_type'];
    $request_header = $server_info['request_header'];
    $response_header = $server_info['response_header'];
    $serverType = $server_info['type'];
    $xtlsTitle = ($serverType == "sanaei" || $serverType == "alireza") ? "XTLSSettings" : "xtlsSettings";
    $sni = $server_info['sni'];
    if (!empty($sni) && ($serverType == "sanaei" || $serverType == "alireza")) {
        $tlsSettings = json_decode($tlsSettings, true);
        $tlsSettings['serverName'] = $sni;
        $tlsSettings = json_encode($tlsSettings, 488 | JSON_UNESCAPED_UNICODE);
    }

    $response = getJson($server_id);
    if (!$response)
        return null;
    $response = $response->obj;
    foreach ($response as $row) {
        if ($row->id == $inboundId) {
            $iid = $row->id;
            $remark = $row->remark;
            $streamSettings = $row->streamSettings;
            $settings = $row->settings;
            break;
        }
    }
    if (!intval($iid))
        return;
    $headers = getNewHeaders($netType, $request_header, $response_header, $header_type);
    $headers = empty($headers) ? "{}" : $headers;

    if ($protocol == 'trojan') {
        if ($security == 'none') {
            $tcpSettings = '{
        	  "network": "tcp",
        	  "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
        	  "tcpSettings": {
                "header": ' . $headers . '
              }
        	}';
            $wsSettings = '{
              "network": "ws",
              "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
              "wsSettings": {
                "path": "/",
                "headers": ' . $headers . '
              }
            }';

        }
        elseif ($security == 'xtls' && $serverType != "sanaei" && $serverType != "alireza") {

            $tcpSettings = '{
        	  "network": "tcp",
        	  "security": "' . $security . '",
        	  "' . $xtlsTitle . '": ' . $tlsSettings . ',
        	  "tcpSettings": {
                "header": ' . $headers . '
              }
        	}';
            $wsSettings = '{
              "network": "ws",
              "security": "' . $security . '",
        	  "' . $xtlsTitle . '": ' . $tlsSettings . ',
              "wsSettings": {
                "path": "/",
                "headers": ' . $headers . '
              }
            }';
        }
        else {
            $tcpSettings = '{
        	  "network": "tcp",
        	  "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
        	  "tcpSettings": {
                "header": ' . $headers . '
              }
        	}';
            $wsSettings = '{
              "network": "ws",
              "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
              "wsSettings": {
                "path": "/",
                "headers": ' . $headers . '
              }
            }';
        }


        $streamSettings = ($netType == 'tcp') ? $tcpSettings : $wsSettings;
        if ($netType == 'grpc') {
            $keyFileInfo = json_decode($tlsSettings, true);
            $certificateFile = "/root/cert.crt";
            $keyFile = '/root/private.key';

            if (isset($keyFileInfo['certificates'])) {
                $certificateFile = $keyFileInfo['certificates'][0]['certificateFile'];
                $keyFile = $keyFileInfo['certificates'][0]['keyFile'];
            }
            if ($security == 'tls') {
                $streamSettings = '{
  "network": "grpc",
  "security": "tls",
  "tlsSettings": {
    "serverName": "' .
                    (!empty($sni) && ($serverType == "sanaei" || $serverType == "alireza") ? $sni : parse_url($panel_url, PHP_URL_HOST))
                    . '",
    "certificates": [
      {
        "certificateFile": "' . $certificateFile . '",
        "keyFile": "' . $keyFile . '"
      }
    ],
    "alpn": []'
                    . '
  },
  "grpcSettings": {
    "serviceName": ""
  }
}';
            }
            else {
                $streamSettings = '{
  "network": "grpc",
  "security": "none",
  "grpcSettings": {
    "serviceName": "' . parse_url($panel_url, PHP_URL_HOST) . '"
  }
}';
            }
        }


        $dataArr = array('up' => $row->up, 'down' => $row->down, 'total' => $row->total, 'remark' => $remark, 'enable' => 'true',
            'expiryTime' => $row->expiryTime, 'listen' => '', 'port' => $row->port, 'protocol' => $protocol, 'settings' => $settings, 'streamSettings' => $streamSettings,
            'sniffing' => $row->sniffing);
    }
    else {
        $tcpSettings = ''; $wsSettings = '';
        if ($netType != "grpc") {
            if ($rahgozar == true) {
                $wsSettings = '{
                      "network": "ws",
                      "security": "none",
                      "wsSettings": {
                        "path": "/wss' . $row->port . '",
                        "headers": {}
                      }
                    }';
            }
            else {
                if ($security == 'tls') {
                    $tcpSettings = '{
            	  "network": "tcp",
            	  "security": "' . $security . '",
            	  "tlsSettings": ' . $tlsSettings . ',
            	  "tcpSettings": {
                    "header": ' . $headers . '
                  }
            	}';
                    $wsSettings = '{
                  "network": "ws",
                  "security": "' . $security . '",
            	  "tlsSettings": ' . $tlsSettings . ',
                  "wsSettings": {
                    "path": "/",
                    "headers": ' . $headers . '
                  }
                }';
                }
                elseif ($security == 'xtls' && $serverType != "sanaei" && $serverType != "alireza") {
                    $tcpSettings = '{
            	  "network": "tcp",
            	  "security": "' . $security . '",
            	  "' . $xtlsTitle . '": ' . $tlsSettings . ',
            	  "tcpSettings": {
                    "header": ' . $headers . '
                  }
            	}';
                    $wsSettings = '{
                  "network": "ws",
                  "security": "' . $security . '",
            	  "' . $xtlsTitle . '": ' . $tlsSettings . ',
                  "wsSettings": {
                    "path": "/",
                    "headers": ' . $headers . '
                  }
                }';
                }
                else {
                    $tcpSettings = '{
            	  "network": "tcp",
            	  "security": "none",
            	  "tcpSettings": {
            		"header": ' . $headers . '
            	  }
            	}';
                    $wsSettings = '{
                  "network": "ws",
                  "security": "none",
                  "wsSettings": {
                    "path": "/",
                    "headers": {}
                  }
                }';
                }
            }
            $streamSettings = ($netType == 'tcp') ? $tcpSettings : $wsSettings;
        }

        $dataArr = array('up' => $row->up, 'down' => $row->down, 'total' => $row->total, 'remark' => $remark, 'enable' => 'true',
            'expiryTime' => $row->expiryTime, 'listen' => '', 'port' => $row->port, 'protocol' => $protocol, 'settings' => $settings,
            'streamSettings' => $streamSettings,
            'sniffing' => $row->sniffing);
    }

    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];

    $loginUrl = $panel_url . '/login';

    $postFields = array(
        "username" => $serverName,
        "password" => $serverPass
    );

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $loginUrl);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
    curl_setopt($curl, CURLOPT_TIMEOUT, 3);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postFields));
    curl_setopt($curl, CURLOPT_HEADER, 1);
    $response = curl_exec($curl);

    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $header_size);
    $body = substr($response, $header_size);
    preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $header, $matches);
    $cookies = array();
    foreach ($matches[1] as $item) {
        parse_str($item, $cookie);
        $cookies = array_merge($cookies, $cookie);
    }

    $loginResponse = json_decode($body, true);
    if (!$loginResponse['success']) {
        curl_close($curl);
        return $loginResponse;
    }

    if ($serverType == "sanaei")
        $url = "$panel_url/panel/inbound/update/$iid";
    else
        $url = "$panel_url/xui/inbound/update/$iid";
    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_CONNECTTIMEOUT => 15,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => $dataArr,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_HEADER => false,
        CURLOPT_HTTPHEADER => array(
            'User-Agent:  Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0',
            'Accept:  application/json, text/plain, */*',
            'Accept-Language:  en-US,en;q=0.5',
            'Accept-Encoding:  gzip, deflate',
            'X-Requested-With:  XMLHttpRequest',
            'Cookie: ' . array_keys($cookies)[0] . "=" . $cookies[array_keys($cookies)[0]]
        )
    ));

    $response = curl_exec($curl);
    curl_close($curl);
    return $response = json_decode($response);
}

// --- Function editInbound ---
function editInbound($server_id, $uniqid, $uuid, $protocol, $netType = 'tcp', $security = 'none', $rahgozar = false)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = $server_info['panel_url'];
    $security = $server_info['security'];
    $tlsSettings = $server_info['tlsSettings'];
    $header_type = $server_info['header_type'];
    $request_header = $server_info['request_header'];
    $response_header = $server_info['response_header'];
    $serverType = $server_info['type'];
    $xtlsTitle = ($serverType == "sanaei" || $serverType == "alireza") ? "XTLSSettings" : "xtlsSettings";
    $sni = $server_info['sni'];
    if (!empty($sni) && ($serverType == "sanaei" || $serverType == "alireza")) {
        $tlsSettings = json_decode($tlsSettings, true);
        $tlsSettings['serverName'] = $sni;
        $tlsSettings = json_encode($tlsSettings);
    }

    $response = getJson($server_id);
    if (!$response)
        return null;
    $response = $response->obj;
    foreach ($response as $row) {
        $clients = json_decode($row->settings)->clients;
        if ($clients[0]->id == $uuid || $clients[0]->password == $uuid) {
            $iid = $row->id;
            $remark = $row->remark;
            $streamSettings = $row->streamSettings;
            $settings = $row->settings;
            break;
        }
    }
    if (!intval($iid))
        return;

    $headers = getNewHeaders($netType, $request_header, $response_header, $header_type);
    $headers = empty($headers) ? "{}" : $headers;

    if ($protocol == 'trojan') {
        if ($security == 'none') {
            $tcpSettings = '{
        	  "network": "tcp",
        	  "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
        	  "tcpSettings": {
                "header": ' . $headers . '
              }
        	}';
            $wsSettings = '{
              "network": "ws",
              "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
              "wsSettings": {
                "path": "/",
                "headers": ' . $headers . '
              }
            }';

            if ($serverType == "sanaei" || $serverType == "alireza") {
                $settings = '{
        	  "clients": [
        		{
        		  "id": "' . $uniqid . '",
                  "enable": true,
        		  "email": "' . $remark . '",
                  "limitIp": 0,
                  "totalGB": 0,
                  "expiryTime": 0,
                  "subId": "' . RandomString(16) . '"
        		}
        	  ],
        	  "decryption": "none",
        	  "fallbacks": []
        	}';
            }
            else {
                $settings = '{
        	  "clients": [
        		{
        		  "id": "' . $uniqid . '",
        		  "flow": "",
        		  "email": "' . $remark . '"
        		}
        	  ],
        	  "decryption": "none",
        	  "fallbacks": []
        	}';
            }
        }
        elseif ($security == 'xtls' && $serverType != "sanaei" && $serverType != "alireza") {

            $tcpSettings = '{
        	  "network": "tcp",
        	  "security": "' . $security . '",
        	  "' . $xtlsTitle . '": ' . $tlsSettings . ',
        	  "tcpSettings": {
                "header": ' . $headers . '
              }
        	}';
            $wsSettings = '{
              "network": "ws",
              "security": "' . $security . '",
        	  "' . $xtlsTitle . '": ' . $tlsSettings . ',
              "wsSettings": {
                "path": "/",
                "headers": ' . $headers . '
              }
            }';

            $settings = '{
              "clients": [
                {
                  "id": "' . $uniqid . '",
    			  "flow": "xtls-rprx-direct".
    			  "email": "' . $remark . '"
                }
              ],
              "decryption": "none",
        	  "fallbacks": []
            }';
        }
        else {
            $tcpSettings = '{
        	  "network": "tcp",
        	  "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
        	  "tcpSettings": {
                "header": ' . $headers . '
              }
        	}';
            $wsSettings = '{
              "network": "ws",
              "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
              "wsSettings": {
                "path": "/",
                "headers": ' . $headers . '
              }
            }';
            if ($serverType == "sanaei" || $serverType == "alireza") {
                $settings = '{
		  "clients": [
			{
			  "password": "' . $uniqid . '",
              "enable": true,
			  "email": "' . $remark . '",
              "limitIp": 0,
              "totalGB": 0,
              "expiryTime": 0,
              "subId": "' . RandomString(16) . '"
			}
		  ],
		  "fallbacks": []
		}';
            }
            else {
                $settings = '{
		  "clients": [
			{
			  "password": "' . $uniqid . '",
			  "flow": "",
			  "email": "' . $remark . '"
			}
		  ],
		  "fallbacks": []
		}';
            }
        }


        $streamSettings = ($netType == 'tcp') ? $tcpSettings : $wsSettings;
        if ($netType == 'grpc') {
            $keyFileInfo = json_decode($tlsSettings, true);
            $certificateFile = "/root/cert.crt";
            $keyFile = '/root/private.key';

            if (isset($keyFileInfo['certificates'])) {
                $certificateFile = $keyFileInfo['certificates'][0]['certificateFile'];
                $keyFile = $keyFileInfo['certificates'][0]['keyFile'];
            }

            if ($security == 'tls') {
                $streamSettings = '{
  "network": "grpc",
  "security": "tls",
  "tlsSettings": {
    "serverName": "' .
                    (!empty($sni) && ($serverType == "sanaei" || $serverType == "alireza") ? $sni : parse_url($panel_url, PHP_URL_HOST))
                    . '",
    "certificates": [
      {
        "certificateFile": "' . $certificateFile . '",
        "keyFile": "' . $keyFile . '"
      }
    ],
    "alpn": []'
                    . '
  },
  "grpcSettings": {
    "serviceName": ""
  }
}';
            }
            else {
                $streamSettings = '{
  "network": "grpc",
  "security": "none",
  "grpcSettings": {
    "serviceName": "' . parse_url($panel_url, PHP_URL_HOST) . '"
  }
}';
            }
        }


        $dataArr = array('up' => $row->up, 'down' => $row->down, 'total' => $row->total, 'remark' => $remark, 'enable' => 'true',
            'expiryTime' => $row->expiryTime, 'listen' => '', 'port' => $row->port, 'protocol' => $protocol, 'settings' => $settings, 'streamSettings' => $streamSettings,
            'sniffing' => $row->sniffing);
    }
    else {
        $tcpSettings = ''; $wsSettings = '';
        if ($netType != "grpc") {
            if ($rahgozar == true) {
                $wsSettings = '{
                      "network": "ws",
                      "security": "none",
                      "wsSettings": {
                        "path": "/wss' . $row->port . '",
                        "headers": {}
                      }
                    }';
                if ($serverType == "sanaei" || $serverType == "alireza") {
                    $settings = '{
            	  "clients": [
            		{
            		  "id": "' . $uniqid . '",
                      "enable": true,
            		  "email": "' . $remark . '",
                      "limitIp": 0,
                      "totalGB": 0,
                      "expiryTime": 0
                      "subId": "' . RandomString(16) . '"
            		}
            	  ],
            	  "decryption": "none",
            	  "fallbacks": []
            	}';
                }
                else {
                    $settings = '{
        	  "clients": [
        		{
        		  "id": "' . $uniqid . '",
        		  "flow": "",
        		  "email": "' . $remark . '"
        		}
        	  ],
        	  "decryption": "none",
        	  "fallbacks": []
        	}';
                }
            }
            else {
                if ($security == 'tls') {
                    $tcpSettings = '{
            	  "network": "tcp",
            	  "security": "' . $security . '",
            	  "tlsSettings": ' . $tlsSettings . ',
            	  "tcpSettings": {
                    "header": ' . $headers . '
                  }
            	}';
                    $wsSettings = '{
                  "network": "ws",
                  "security": "' . $security . '",
            	  "tlsSettings": ' . $tlsSettings . ',
                  "wsSettings": {
                    "path": "/",
                    "headers": ' . $headers . '
                  }
                }';
                    if ($serverType == "sanaei" || $serverType == "alireza") {
                        $settings = '{
                  "clients": [
                    {
                      "id": "' . $uniqid . '",
                      "enable": true,
                      "email": "' . $remark . '",
                      "limitIp": 0,
                      "totalGB": 0,
                      "expiryTime": 0,
                      "subId": "' . RandomString(16) . '"
                    }
                  ],
                  "decryption": "none",
            	  "fallbacks": []
                }';
                    }
                    else {
                        $settings = '{
                  "clients": [
                    {
                      "id": "' . $uniqid . '",
                      "alterId": 0
                    }
                  ],
                  "decryption": "none",
            	  "fallbacks": []
                }';
                    }
                }
                elseif ($security == 'xtls' && $serverType != "sanaei" && $serverType != "alireza") {
                    $tcpSettings = '{
            	  "network": "tcp",
            	  "security": "' . $security . '",
            	  "xtlsSettings": ' . $tlsSettings . ',
            	  "tcpSettings": {
                    "header": ' . $headers . '
                  }
            	}';
                    $wsSettings = '{
                  "network": "ws",
                  "security": "' . $security . '",
            	  "xtlsSettings": ' . $tlsSettings . ',
                  "wsSettings": {
                    "path": "/",
                    "headers": ' . $headers . '
                  }
                }';
                    if ($serverType == "sanaei" || $serverType == "alireza") {
                        $settings = '{
                  "clients": [
                    {
                      "id": "' . $uniqid . '",
                      "enable": true,
                      "email": "' . $remark . '",
                      "limitIp": 0,
                      "totalGB": 0,
                      "expiryTime": 0,
                      "subId": "' . RandomString(16) . '"
                    }
                  ],
                  "decryption": "none",
            	  "fallbacks": []
                }';
                    }
                    else {
                        $settings = '{
                  "clients": [
                    {
                      "id": "' . $uniqid . '",
        			  "flow": "",
        			  "email": "' . $remark . '"
                    }
                  ],
                  "decryption": "none",
            	  "fallbacks": []
                }';
                    }
                }
                else {
                    $tcpSettings = '{
            	  "network": "tcp",
            	  "security": "none",
            	  "tcpSettings": {
            		"header": ' . $headers . '
            	  }
            	}';
                    $wsSettings = '{
                  "network": "ws",
                  "security": "none",
                  "wsSettings": {
                    "path": "/",
                    "headers": {}
                  }
                }';
                    if ($serverType == "sanaei" || $serverType == "alireza") {
                        $settings = '{
            	  "clients": [
            		{
            		  "id": "' . $uniqid . '",
                      "enable": true,
            		  "email": "' . $remark . '",
                      "limitIp": 0,
                      "totalGB": 0,
                      "expiryTime": 0,
                      "subId": "' . RandomString(16) . '"
            		}
            	  ],
            	  "decryption": "none",
            	  "fallbacks": []
            	}';
                    }
                    else {
                        $settings = '{
            	  "clients": [
            		{
            		  "id": "' . $uniqid . '",
            		  "flow": "",
            		  "email": "' . $remark . '"
            		}
            	  ],
            	  "decryption": "none",
            	  "fallbacks": []
            	}';
                    }
                }
            }
            $streamSettings = ($netType == 'tcp') ? $tcpSettings : $wsSettings;
        }


        $dataArr = array('up' => $row->up, 'down' => $row->down, 'total' => $row->total, 'remark' => $remark, 'enable' => 'true',
            'expiryTime' => $row->expiryTime, 'listen' => '', 'port' => $row->port, 'protocol' => $protocol, 'settings' => $settings,
            'streamSettings' => $streamSettings,
            'sniffing' => $row->sniffing);
    }



    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];

    $loginUrl = $panel_url . '/login';

    $postFields = array(
        "username" => $serverName,
        "password" => $serverPass
    );

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $loginUrl);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
    curl_setopt($curl, CURLOPT_TIMEOUT, 3);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postFields));
    curl_setopt($curl, CURLOPT_HEADER, 1);
    $response = curl_exec($curl);

    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $header_size);
    $body = substr($response, $header_size);
    preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $header, $matches);
    $cookies = array();
    foreach ($matches[1] as $item) {
        parse_str($item, $cookie);
        $cookies = array_merge($cookies, $cookie);
    }

    $loginResponse = json_decode($body, true);
    if (!$loginResponse['success']) {
        curl_close($curl);
        return $loginResponse;
    }

    if ($serverType == "sanaei")
        $url = "$panel_url/panel/inbound/update/$iid";
    else
        $url = "$panel_url/xui/inbound/update/$iid";

    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_CONNECTTIMEOUT => 15,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => $dataArr,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_HEADER => false,
        CURLOPT_HTTPHEADER => array(
            'User-Agent:  Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0',
            'Accept:  application/json, text/plain, */*',
            'Accept-Language:  en-US,en;q=0.5',
            'Accept-Encoding:  gzip, deflate',
            'X-Requested-With:  XMLHttpRequest',
            'Cookie: ' . array_keys($cookies)[0] . "=" . $cookies[array_keys($cookies)[0]]
        )
    ));

    $response = curl_exec($curl);
    curl_close($curl);
    return $response = json_decode($response);
}

// --- Function getJson ---
function getJson($server_id)
{
    global $connection;

    // 1. دریافت اطلاعات سرور
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    if (!$server_info) {
        return (object)['success' => false, 'msg' => 'Server not found in DB'];
    }

    $panel_url = rtrim($server_info['panel_url'], '/');
    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];

    // استفاده از فایل برای ذخیره کوکی (پایدارتر از روش قبلی)
    $cookie_file = getCookieFilePath($server_id);

    // 2. لاگین
    $loginUrl = $panel_url . '/login';
    $postFields = ["username" => $serverName, "password" => $serverPass];

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $loginUrl,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($postFields),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_COOKIEJAR => $cookie_file, // ذخیره کوکی
        CURLOPT_COOKIEFILE => $cookie_file, // خواندن کوکی
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
    ]);

    $loginResponse = curl_exec($ch);
    $loginCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    // اگر لاگین موفق نبود
    if ($loginCode != 200) {
        return (object)['success' => false, 'msg' => "Login Failed (HTTP $loginCode)"];
    }

    $serverType = $server_info['type'] ?? 'sanaei';
    $base_path = ($serverType == 'sanaei') ? '/panel' : '/xui';
    $listUrl = "$panel_url" . $base_path . "/api/inbounds/list";

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $listUrl,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_COOKIEFILE => $cookie_file, // استفاده از کوکی لاگین
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_HTTPHEADER => [
            "Accept: application/json",
            "Content-Type: application/json"
        ]
    ]);

    $listResponse = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $finalResult = json_decode($listResponse);

    // اگر موفق بود
    if (is_object($finalResult) && isset($finalResult->success) && $finalResult->success) {
        return $finalResult;
    }

    // فال‌بک: اگر آدرس جدید کار نکرد، آدرس قدیمی را تست کن
    if ($http_code == 404 || empty($listResponse)) {
        $fallbackUrl = "$panel_url/panel/inbound/list";
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $fallbackUrl,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => "{}",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_COOKIEFILE => $cookie_file,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_SSL_VERIFYPEER => false
        ]);
        $fallbackResponse = curl_exec($ch);
        curl_close($ch);
        return json_decode($fallbackResponse) ?: (object)['success' => false, 'msg' => 'Failed to fetch list'];
    }

    return (object)['success' => false, 'msg' => 'Invalid JSON from Panel'];
}

// --- Function getNewCert ---
function getNewCert($server_id)
{
    global $connection;
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = rtrim($server_info['panel_url'], '/');
    $cookie_file = getCookieFilePath($server_id, true);

    // 1. لاگین اجباری (برای اطمینان از دریافت کلیدها)
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $panel_url . '/login',
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query([
            "username" => $server_info['username'],
            "password" => $server_info['password']
        ]),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_COOKIEJAR => $cookie_file,
        CURLOPT_COOKIEFILE => $cookie_file,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => 10
    ]);
    curl_exec($ch);
    curl_close($ch);

    // 2. دریافت سرتیفیکیت جدید
    $serverType = $server_info['type'];
    if ($serverType == "sanaei" || $serverType == "alireza") {
        $base_path = ($serverType == 'sanaei') ? '/panel' : '/xui';
        $url = "$panel_url" . $base_path . "/api/inbounds/getNewXrayCert";
    }
    else {
        $url = "$panel_url/server/getNewXrayCert";
    }

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_COOKIEFILE => $cookie_file,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_TIMEOUT => 10
    ]);
    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response);
}

// --- Function addUser ---
function addUser($server_id, $client_id, $protocol, $port, $expiryTime, $remark, $volume, $netType, $security = 'none', $rahgozar = false, $planId = null)
{
    global $connection;

    // 1. دریافت اطلاعات سرور
    $stmt = $connection->prepare("SELECT * FROM server_config WHERE id=?");
    $stmt->bind_param("i", $server_id);
    $stmt->execute();
    $server_info = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    $panel_url = rtrim($server_info['panel_url'], '/');
    $serverType = $server_info['type'];

    // تنظیمات هدر و امنیت پیش‌فرض
    $tlsSettings = $server_info['tlsSettings'];
    $header_type = $server_info['header_type'];
    $request_header = $server_info['request_header'];
    $response_header = $server_info['response_header'];
    $sni = $server_info['sni'];
    $reality = $server_info['reality'];

    // تنظیم SNI اگر وجود داشت
    if (!empty($sni) && ($serverType == "sanaei" || $serverType == "alireza")) {
        $tlsSettingsArr = json_decode($tlsSettings, true);
        if (is_array($tlsSettingsArr)) {
            $tlsSettingsArr['serverName'] = $sni;
            $tlsSettings = json_encode($tlsSettingsArr);
        }
    }

    // محاسبه حجم و تاریخ
    $volume = ($volume == 0) ? 0 : floor($volume * 1073741824);
    $expiryTime = $expiryTime > 0 ? (int)$expiryTime : 0;

    // ساخت هدرها
    $headers = getNewHeaders($netType, $request_header, $response_header, $header_type);

    // 2. لاگین به پنل (حیاتی)
    $cookie_file = getCookieFilePath($server_id);
    if (file_exists($cookie_file))
        @unlink($cookie_file); // حذف کوکی قدیمی برای لاگین تازه

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $panel_url . '/login',
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query([
            "username" => $server_info['username'],
            "password" => $server_info['password']
        ]),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_COOKIEJAR => $cookie_file,
        CURLOPT_COOKIEFILE => $cookie_file,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => 15
    ]);
    $loginData = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    // بررسی اولیه لاگین
    if ($httpCode != 200) {
        return (object)['success' => false, 'msg' => "Login Failed (HTTP $httpCode)"];
    }
    //---------------------------------------Trojan------------------------------------//
    if ($protocol == 'trojan') {
        // protocol trojan
        if ($security == 'none') {

            $tcpSettings = '{
        	  "network": "tcp",
        	  "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
        	  "tcpSettings": {
                "header": ' . $headers . '
              }
        	}';
            $wsSettings = '{
              "network": "ws",
              "security": "' . $security . '", 
        	  "tlsSettings": ' . $tlsSettings . ',
              "wsSettings": {
                "path": "/",
                "headers": ' . $headers . '
              }
            }';

            if ($serverType == "sanaei" || $serverType == "alireza") {
                $settings = '{
        	  "clients": [
        		{
        		  "id": "' . $client_id . '",
                  "enable": true,
                  "email": "' . $remark . '",
                  "limitIp": 0,
                  "totalGB": 0,
                  "expiryTime": 0,
                  "subId": "' . RandomString(16) . '"
        		}
        	  ],
        	  "decryption": "none",
        	  "fallbacks": []
        	}';
            }
            else {
                $settings = '{
        	  "clients": [
        		{
        		  "id": "' . $client_id . '",
        		  "flow": "",
        		  "email": "' . $remark . '"
        		}
        	  ],
        	  "decryption": "none",
        	  "fallbacks": []
        	}';
            }
        }
        elseif ($security == 'xtls' && $serverType != "sanaei" && $serverType != "alireza") {
            $tcpSettings = '{
                	  "network": "tcp",
                	  "security": "' . $security . '",
                	  "xtlsSettings": ' . $tlsSettings . ',
                	  "tcpSettings": {
                        "header": ' . $headers . '
                      }
                	}';

            $wsSettings = '{
                  "network": "ws",
                  "security": "' . $security . '",
            	  "xtlsSettings": ' . $tlsSettings . ',
                  "wsSettings": {
                    "path": "/",
                    "headers": ' . $headers . '
                  }
                }';
            $settings = '{
                  "clients": [
                    {
                      "id": "' . $client_id . '",
                      "alterId": 0
                    }
                  ],
                  "decryption": "none",
            	  "fallbacks": []
                }';
        }

        else {
            $tcpSettings = '{
        	  "network": "tcp",
        	  "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
        	  "tcpSettings": {
                "header": ' . $headers . '
              }
        	}';
            $wsSettings = '{
              "network": "ws",
              "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
              "wsSettings": {
                "path": "/",
                "headers": ' . $headers . '
              }
            }';
            if ($serverType == "sanaei" || $serverType == "alireza") {
                $settings = '{
		  "clients": [
			{
			  "password": "' . $client_id . '",
              "enable": true,
              "email": "' . $remark . '",
              "limitIp": 0,
              "totalGB": 0,
              "expiryTime": 0,
              "subId": "' . RandomString(16) . '"
			}
		  ],
		  "fallbacks": []
		}';
            }
            else {
                $settings = '{
		  "clients": [
			{
			  "password": "' . $client_id . '",
			  "flow": "",
			  "email": "' . $remark . '"
			}
		  ],
		  "fallbacks": []
		}';
            }
        }



        $streamSettings = ($netType == 'tcp') ? $tcpSettings : $wsSettings;
        if ($netType == 'grpc') {
            $keyFileInfo = json_decode($tlsSettings, true);
            $certificateFile = "/root/cert.crt";
            $keyFile = '/root/private.key';

            if (isset($keyFileInfo['certificates'])) {
                $certificateFile = $keyFileInfo['certificates'][0]['certificateFile'];
                $keyFile = $keyFileInfo['certificates'][0]['keyFile'];
            }

            if ($security == 'tls') {
                $streamSettings = '{
  "network": "grpc",
  "security": "tls",
  "tlsSettings": {
    "serverName": "' .
                    (!empty($sni) && ($serverType == "sanaei" || $serverType == "alireza") ? $sni : parse_url($panel_url, PHP_URL_HOST))
                    . '",
    "certificates": [
      {
        "certificateFile": "' . $certificateFile . '",
        "keyFile": "' . $keyFile . '"
      }
    ],
    "alpn": []'
                    . '
  },
  "grpcSettings": {
    "serviceName": ""
  }
}';
            }
            else {
                $streamSettings = '{
  "network": "grpc",
  "security": "none",
  "grpcSettings": {
    "serviceName": "' . parse_url($panel_url, PHP_URL_HOST) . '"
  }
}';
            }
        }




        // trojan
        $dataArr = array('up' => '0', 'down' => '0', 'total' => $volume, 'remark' => $remark, 'enable' => 'true', 'expiryTime' => $expiryTime, 'listen' => '', 'port' => $port, 'protocol' => $protocol, 'settings' => $settings, 'streamSettings' => $streamSettings,
            'sniffing' => '{
      "enabled": true,
      "destOverride": [
        "http",
        "tls"
      ]
    }');
    }
    else {
        $tcpSettings = ''; $wsSettings = '';
        //-------------------------------------- vmess vless -------------------------------//
        if ($rahgozar == true) {
            $wsSettings = '{
                  "network": "ws",
                  "security": "none",
                  "wsSettings": {
                    "path": "/wss' . $port . '",
                    "headers": {}
                  }
                }';
            if ($serverType == "sanaei" || $serverType == "alireza") {
                $settings = '{
        	  "clients": [
        		{
        		  "id": "' . $client_id . '",
                  "enable": true,
        		  "email": "' . $remark . '",
                  "limitIp": 0,
                  "totalGB": 0,
                  "expiryTime": 0,
                  "subId": "' . RandomString(16) . '"
        		}
        	  ],
        	  "decryption": "none",
        	  "fallbacks": []
        	}';
            }
            else {
                $settings = '{
        	  "clients": [
        		{
        		  "id": "' . $client_id . '",
        		  "flow": "",
        		  "email": "' . $remark . '"
        		}
        	  ],
        	  "decryption": "none",
        	  "fallbacks": []
        	}';
            }
        }
        else {
            if ($security == 'tls') {
                $tcpSettings = '{
        	  "network": "tcp",
        	  "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
        	  "tcpSettings": {
                "header": ' . $headers . '
              }
        	}';
                $wsSettings = '{
              "network": "ws",
              "security": "' . $security . '",
        	  "tlsSettings": ' . $tlsSettings . ',
              "wsSettings": {
                "path": "/",
                "headers": ' . $headers . '
              }
            }';
                if ($serverType == "sanaei" || $serverType == "alireza") {
                    $settings = '{
              "clients": [
                {
                  "id": "' . $client_id . '",
                  "enable": true,
                  "email": "' . $remark . '",
                  "limitIp": 0,
                  "totalGB": 0,
                  "expiryTime": 0,
                  "subId": "' . RandomString(16) . '"
                }
              ],
              "disableInsecureEncryption": false
            }';
                }
                else {
                    $settings = '{
              "clients": [
                {
                  "id": "' . $client_id . '",
                  "alterId": 0
                }
              ],
              "disableInsecureEncryption": false
            }';
                }
            }
            elseif ($security == 'xtls' && $serverType != "sanaei" && $serverType != "alireza") {
                $tcpSettings = '{
        	  "network": "tcp",
        	  "security": "' . $security . '",
        	  "xtlsSettings": ' . $tlsSettings . ',
        	  "tcpSettings": {
                "header": ' . $headers . '
              }
        	}';
                $wsSettings = '{
              "network": "ws",
              "security": "' . $security . '",
        	  "xtlsSettings": ' . $tlsSettings . ',
              "wsSettings": {
                "path": "/",
                "headers": ' . $headers . '
              }
            }';
                $settings = '{
              "clients": [
                {
                  "id": "' . $client_id . '",
                  "alterId": 0
                }
              ],
              "disableInsecureEncryption": false
            }';
            }
            else {
                $tcpSettings = '{
        	  "network": "tcp",
        	  "security": "none",
        	  "tcpSettings": {
        		"header": ' . $headers . '
        	  }
        	}';
                $wsSettings = '{
              "network": "ws",
              "security": "none",
              "wsSettings": {
                "path": "/",
                "headers": ' . $headers . '
              }
            }';
                if ($serverType == "sanaei" || $serverType == "alireza") {
                    $settings = '{
        	  "clients": [
        		{
        		  "id": "' . $client_id . '",
        		  "enable": true,
        		  "email": "' . $remark . '",
                  "limitIp": 0,
                  "totalGB": 0,
                  "expiryTime": 0,
                  "subId": "' . RandomString(16) . '"
        		}
        	  ],
        	  "decryption": "none",
        	  "fallbacks": []
        	}';
                }
                else {
                    $settings = '{
        	  "clients": [
        		{
        		  "id": "' . $client_id . '",
        		  "flow": "",
        		  "email": "' . $remark . '"
        		}
        	  ],
        	  "decryption": "none",
        	  "fallbacks": []
        	}';
                }
            }
        }


        if ($protocol == 'vless') {
            if ($serverType == "sanaei" || $serverType == "alireza") {
                if ($security == "reality") {
                    $stmt = $connection->prepare("SELECT * FROM `server_plans` WHERE `id`=?");
                    $stmt->bind_param("i", $planId);
                    $stmt->execute();
                    $file_detail = $stmt->get_result()->fetch_assoc();
                    $stmt->close();

                    $dest = "yahoo.com:443";
                    $serverNames = '["yahoo.com", "www.yahoo.com"]';
                    $spiderX = "";
                    $flow = "";

                    if ($planId) {
                        $stmt = $connection->prepare("SELECT * FROM `server_plans` WHERE `id`=?");
                        $stmt->bind_param("i", $planId);
                        $stmt->execute();
                        $file_detail = $stmt->get_result()->fetch_assoc();
                        $stmt->close();

                        if (!empty($file_detail['dest']))
                            $dest = $file_detail['dest'];
                        if (!empty($file_detail['serverNames']))
                            $serverNames = $file_detail['serverNames'];
                        if (!empty($file_detail['spiderX']))
                            $spiderX = $file_detail['spiderX'];
                        if (isset($file_detail['flow']) && $file_detail['flow'] != "None")
                            $flow = $file_detail['flow'];
                    }

                    // ب) دریافت کلیدهای Reality (مستقیم با همان کوکی)
                    $base_path = ($serverType == 'sanaei') ? '/panel' : '/xui';
                    $certUrl = "$panel_url" . $base_path . "/api/inbounds/getNewXrayCert";
                    $ch_cert = curl_init();
                    curl_setopt_array($ch_cert, [
                        CURLOPT_URL => $certUrl,
                        CURLOPT_RETURNTRANSFER => true,
                        CURLOPT_COOKIEFILE => $cookie_file, // استفاده از کوکی لاگین شده
                        CURLOPT_SSL_VERIFYHOST => false,
                        CURLOPT_SSL_VERIFYPEER => false,
                        CURLOPT_TIMEOUT => 10
                    ]);
                    $certResRaw = curl_exec($ch_cert);
                    curl_close($ch_cert);
                    $certResponse = json_decode($certResRaw);

                    // بررسی صحت کلیدها
                    if (!is_object($certResponse) || !isset($certResponse->obj)) {
                        return (object)['success' => false, 'msg' => 'Failed to get Reality Keys. Check Panel Logs.'];
                    }

                    $publicKey = $certResponse->obj->publicKey;
                    $privateKey = $certResponse->obj->privateKey;
                    $shortId = RandomString(8, "small");

                    // استخراج ServerName
                    $tlsArr = json_decode($tlsSettings, true);
                    $serverName = isset($tlsArr['serverName']) ? $tlsArr['serverName'] : "yahoo.com";

                    if ($netType == "grpc") {
                        $tcpSettings = '{
                          "network": "grpc",
                          "security": "reality",
                          "realitySettings": {
                            "show": false,
                            "xver": 0,
                            "dest": "' . $dest . '",
                            "serverNames":' . $serverNames . ',
                            "privateKey": "' . $privateKey . '",
                            "minClient": "",
                            "maxClient": "",
                            "maxTimediff": 0,
                            "shortIds": [
                              "' . $shortId . '"
                            ],
                            "settings": {
                              "publicKey": "' . $publicKey . '",
                              "fingerprint": "firefox",
                              "serverName": "' . $serverName . '",
                              "spiderX": "' . $spiderX . '"
                            }
                          },
                          "grpcSettings": {
                            "serviceName": "",
                    		"multiMode": false
                          }
                        }';
                    }
                    else {
                        $tcpSettings = '{
                          "network": "tcp",
                          "security": "reality",
                          "realitySettings": {
                            "show": false,
                            "xver": 0,
                            "dest": "' . $dest . '",
                            "serverNames":' . $serverNames . ',
                            "privateKey": "' . $privateKey . '",
                            "minClient": "",
                            "maxClient": "",
                            "maxTimediff": 0,
                            "shortIds": [
                              "' . $shortId . '"
                            ],
                            "settings": {
                              "publicKey": "' . $publicKey . '",
                              "fingerprint": "firefox",
                              "serverName": "' . $serverName . '",
                              "spiderX": "' . $spiderX . '"
                            }
                          },
                          "tcpSettings": {
                            "acceptProxyProtocol": false,
                    		"header": ' . $headers . '
                          }
                        }';
                    }

                    // اصلاح تنظیمات کلاینت برای Reality (فلو برای Grpc باید خالی باشد)
                    $finalFlow = ($netType == "grpc") ? "" : $flow;

                    $settings = '{
        			  "clients": [
        				{
        				  "id": "' . $client_id . '",
        				  "enable": true,
                          "email": "' . $remark . '",
                          "flow": "' . $flow . '",
                          "limitIp": 0,
                          "totalGB": 0,
                          "expiryTime": 0,
                          "subId": "' . RandomString(16) . '"
        				}
        			  ],
        			  "decryption": "none",
        			  "fallbacks": []
        			}';
                    $netType = "tcp";
                }
                else {
                    $settings = '{
        			  "clients": [
        				{
        				  "id": "' . $client_id . '",
        				  "enable": true,
                          "email": "' . $remark . '",
                          "limitIp": 0,
                          "totalGB": 0,
                          "expiryTime": 0,
                          "subId": "' . RandomString(16) . '"
        				}
        			  ],
        			  "decryption": "none",
        			  "fallbacks": []
        			}';
                }
            }
            else {
                $settings = '{
			  "clients": [
				{
				  "id": "' . $client_id . '",
				  "flow": "",
				  "email": "' . $remark . '"
				}
			  ],
			  "decryption": "none",
			  "fallbacks": []
			}';

                // اگر grpc باشد، متغیر netType را برای پایین دست تغییر ندهیم بهتر است،
                // اما طبق کد قبلی شما:
                if ($netType != "grpc")
                    $netType = "tcp";
            }
        }

        $streamSettings = ($netType == 'tcp') ? $tcpSettings : $wsSettings;
        if ($netType == 'grpc' && $reality != "true") {
            $keyFileInfo = json_decode($tlsSettings, true);
            $certificateFile = "/root/cert.crt";
            $keyFile = '/root/private.key';

            if (isset($keyFileInfo['certificates'])) {
                $certificateFile = $keyFileInfo['certificates'][0]['certificateFile'];
                $keyFile = $keyFileInfo['certificates'][0]['keyFile'];
            }

            if ($security == 'tls') {
                $streamSettings = '{
  "network": "grpc",
  "security": "tls",
  "tlsSettings": {
    "serverName": "' . parse_url($panel_url, PHP_URL_HOST) . '",
    "certificates": [
      {
        "certificateFile": "' . $certificateFile . '",
        "keyFile": "' . $keyFile . '"
      }
    ],
    "alpn": []
  },
  "grpcSettings": {
    "serviceName": ""
  }
}';
            }
            else {
                $streamSettings = '{
  "network": "grpc",
  "security": "none",
  "grpcSettings": {
    "serviceName": "' . parse_url($panel_url, PHP_URL_HOST) . '"
  }
}';
            }
        }

        if (($serverType == "sanaei" || $serverType == "alireza") && $reality == "true") {
            $sniffing = '{
              "enabled": true,
              "destOverride": [
                "http",
                "tls",
                "quic"
              ]
            }';
        }
        else {
            $sniffing = '{
        	  "enabled": true,
        	  "destOverride": [
        		"http",
        		"tls"
        	  ]
        	}';
        }
        // vmess - vless
        $dataArr = array('up' => '0', 'down' => '0', 'total' => $volume, 'remark' => $remark, 'enable' => 'true', 'expiryTime' => $expiryTime, 'listen' => '', 'port' => $port, 'protocol' => $protocol, 'settings' => $settings, 'streamSettings' => $streamSettings
            , 'sniffing' => $sniffing);
    }

    $phost = str_ireplace('https://', '', str_ireplace('http://', '', $panel_url));
    $serverName = $server_info['username'];
    $serverPass = $server_info['password'];

    $loginUrl = $panel_url . '/login';

    $postFields = array(
        "username" => $serverName,
        "password" => $serverPass
    );


    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $loginUrl);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
    curl_setopt($curl, CURLOPT_TIMEOUT, 3);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postFields));
    curl_setopt($curl, CURLOPT_HEADER, 1);
    $response = curl_exec($curl);
    sendMessage(curl_error($curl));

    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $header_size);
    $body = substr($response, $header_size);
    preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $header, $matches);
    $cookies = array();
    foreach ($matches[1] as $item) {
        parse_str($item, $cookie);
        $cookies = array_merge($cookies, $cookie);
    }

    $loginResponse = json_decode($body, true);

    if (!$loginResponse['success']) {
        curl_close($curl);
        return $loginResponse;
    }

    if ($serverType == "sanaei")
        $url = "$panel_url/panel/inbound/add";
    else
        $url = "$panel_url/xui/inbound/add";

    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_CONNECTTIMEOUT => 15,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => $dataArr,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_HEADER => false,
        CURLOPT_HTTPHEADER => array(
            'User-Agent:  Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0',
            'Accept:  application/json, text/plain, */*',
            'Accept-Language:  en-US,en;q=0.5',
            'Accept-Encoding:  gzip, deflate',
            'X-Requested-With:  XMLHttpRequest',
            'Cookie: ' . array_keys($cookies)[0] . "=" . $cookies[array_keys($cookies)[0]]
        )
    ));
    $response = curl_exec($curl);
    curl_close($curl);
    return json_decode($response);
}
