<?php
/**
 * Sanaei X-UI Panel API Class
 * برای اتصال به پنل X-UI و مدیریت اکانت‌ها
 */

class XUI_API {
    private $panel_url;
    private $username;
    private $password;
    private $session_cookie;
    private $debug_mode;
    
    public function __construct($panel_url, $username, $password, $debug = false) {
        $this->panel_url = rtrim($panel_url, '/');
        $this->username = $username;
        $this->password = $password;
        $this->debug_mode = $debug;
        $this->session_cookie = null;
    }
    
    /**
     * لاگین به پنل و دریافت کوکی session
     */
    public function login() {
        $url = $this->panel_url . '/login';
        
        $data = [
            'username' => $this->username,
            'password' => $this->password
        ];
        
        $response = $this->makeRequest('POST', $url, $data, false);
        
        if ($response && isset($response['success']) && $response['success']) {
            $this->log("✅ Login successful");
            return true;
        }
        
        $this->log("❌ Login failed: " . json_encode($response));
        return false;
    }
    
    /**
     * دریافت لیست همه Inbound ها
     */
    public function getInbounds() {
        if (!$this->ensureLogin()) {
            return null;
        }
        
        $url = $this->panel_url . '/panel/api/inbounds/list';
        $response = $this->makeRequest('GET', $url);
        
        if ($response && isset($response['success']) && $response['success']) {
            return $response['obj'];
        }
        
        return null;
    }
    
    /**
     * پیدا کردن Inbound با پروتکل VLESS
     */
    public function findVlessInbound() {
        $inbounds = $this->getInbounds();
        
        if (!$inbounds) {
            return null;
        }
        
        foreach ($inbounds as $inbound) {
            if (strtolower($inbound['protocol']) === 'vless') {
                return $inbound;
            }
        }
        
        return null;
    }
    
    /**
     * اضافه کردن Client جدید به Inbound
     */
    public function addClient($inbound_id, $email, $total_gb, $expire_days, $limit_ip = 0) {
        if (!$this->ensureLogin()) {
            return null;
        }
        
        // تبدیل گیگ به بایت
        $total_bytes = $total_gb * 1024 * 1024 * 1024;
        
        // محاسبه زمان انقضا (میلی‌ثانیه)
        $expire_time = ($expire_days > 0) ? (time() + ($expire_days * 86400)) * 1000 : 0;
        
        // تولید UUID جدید
        $uuid = $this->generateUUID();
        
        $client_data = [
            'id' => $uuid,
            'alterId' => 0,
            'email' => $email,
            'limitIp' => (int)$limit_ip,
            'totalGB' => (int)$total_bytes,
            'expiryTime' => (int)$expire_time,
            'enable' => true,
            'tgId' => '',
            'subId' => $this->generateSubId(),
            'reset' => 0
        ];
        
        $settings = [
            'clients' => [$client_data]
        ];
        
        $data = [
            'id' => (int)$inbound_id,
            'settings' => json_encode($settings)
        ];
        
        $url = $this->panel_url . '/panel/api/inbounds/addClient';
        $response = $this->makeRequest('POST', $url, $data);
        
        if ($response && isset($response['success']) && $response['success']) {
            $this->log("✅ Client created: " . $email);
            return [
                'success' => true,
                'uuid' => $uuid,
                'email' => $email,
                'subId' => $client_data['subId']
            ];
        }
        
        $this->log("❌ Failed to create client: " . json_encode($response));
        return null;
    }
    
    /**
     * دریافت لینک اشتراک کاربر
     */
    public function getClientLink($inbound_id, $email) {
        if (!$this->ensureLogin()) {
            return null;
        }
        
        $inbound = $this->getInboundById($inbound_id);
        
        if (!$inbound) {
            return null;
        }
        
        $settings = json_decode($inbound['settings'], true);
        $client = null;
        
        foreach ($settings['clients'] as $c) {
            if ($c['email'] === $email) {
                $client = $c;
                break;
            }
        }
        
        if (!$client) {
            return null;
        }
        
        // ساخت لینک VLESS
        $stream_settings = json_decode($inbound['streamSettings'], true);
        $network = $stream_settings['network'] ?? 'tcp';
        
        $link = $this->buildVlessLink(
            $client['id'],
            $inbound['listen'] ?? 'YOUR_SERVER_IP',
            $inbound['port'],
            $email,
            $network,
            $stream_settings
        );
        
        return $link;
    }
    
    /**
     * دریافت Inbound با ID مشخص
     */
    private function getInboundById($inbound_id) {
        $inbounds = $this->getInbounds();
        
        if (!$inbounds) {
            return null;
        }
        
        foreach ($inbounds as $inbound) {
            if ($inbound['id'] == $inbound_id) {
                return $inbound;
            }
        }
        
        return null;
    }
    
    /**
     * ساخت لینک VLESS
     */
    private function buildVlessLink($uuid, $address, $port, $remark, $network, $stream_settings) {
        $params = [
            'type' => $network,
            'security' => $stream_settings['security'] ?? 'none',
            'encryption' => 'none'
        ];
        
        if ($network === 'ws') {
            $params['path'] = $stream_settings['wsSettings']['path'] ?? '/';
            $params['host'] = $stream_settings['wsSettings']['headers']['Host'] ?? '';
        } elseif ($network === 'grpc') {
            $params['serviceName'] = $stream_settings['grpcSettings']['serviceName'] ?? '';
        }
        
        if (isset($stream_settings['tlsSettings']['serverName'])) {
            $params['sni'] = $stream_settings['tlsSettings']['serverName'];
        }
        
        $query = http_build_query($params);
        $link = "vless://{$uuid}@{$address}:{$port}?{$query}#{$remark}";
        
        return $link;
    }
    
    /**
     * دریافت اطلاعات کاربر
     */
    public function getClientInfo($email) {
        if (!$this->ensureLogin()) {
            return null;
        }
        
        $url = $this->panel_url . '/panel/api/inbounds/getClientTraffics/' . urlencode($email);
        $response = $this->makeRequest('GET', $url);
        
        if ($response && isset($response['success']) && $response['success']) {
            return $response['obj'];
        }
        
        return null;
    }
    
    /**
     * حذف کاربر
     */
    public function deleteClient($inbound_id, $email) {
        if (!$this->ensureLogin()) {
            return false;
        }
        
        $url = $this->panel_url . '/panel/api/inbounds/' . $inbound_id . '/delClient/' . urlencode($email);
        $response = $this->makeRequest('POST', $url);
        
        if ($response && isset($response['success']) && $response['success']) {
            $this->log("✅ Client deleted: " . $email);
            return true;
        }
        
        return false;
    }
    
    /**
     * تمدید اکانت (افزایش حجم و زمان)
     */
    public function renewClient($inbound_id, $email, $add_gb, $add_days) {
        if (!$this->ensureLogin()) {
            return false;
        }
        
        // دریافت اطلاعات فعلی
        $inbound = $this->getInboundById($inbound_id);
        if (!$inbound) {
            return false;
        }
        
        $settings = json_decode($inbound['settings'], true);
        $client = null;
        $client_index = null;
        
        foreach ($settings['clients'] as $index => $c) {
            if ($c['email'] === $email) {
                $client = $c;
                $client_index = $index;
                break;
            }
        }
        
        if (!$client) {
            return false;
        }
        
        // افزایش حجم
        $add_bytes = $add_gb * 1024 * 1024 * 1024;
        $client['totalGB'] += $add_bytes;
        
        // افزایش زمان
        if ($add_days > 0) {
            $add_time = $add_days * 86400 * 1000;
            $client['expiryTime'] = ($client['expiryTime'] > 0) ? ($client['expiryTime'] + $add_time) : ((time() + ($add_days * 86400)) * 1000);
        }
        
        $data = [
            'id' => (int)$inbound_id,
            'settings' => json_encode(['clients' => [$client]])
        ];
        
        $url = $this->panel_url . '/panel/api/inbounds/updateClient/' . $client['id'];
        $response = $this->makeRequest('POST', $url, $data);
        
        if ($response && isset($response['success']) && $response['success']) {
            $this->log("✅ Client renewed: " . $email);
            return true;
        }
        
        return false;
    }
    
    /**
     * ریست کردن ترافیک کاربر
     */
    public function resetClientTraffic($inbound_id, $email) {
        if (!$this->ensureLogin()) {
            return false;
        }
        
        $url = $this->panel_url . '/panel/api/inbounds/resetClientTraffic/' . $inbound_id . '/' . urlencode($email);
        $response = $this->makeRequest('POST', $url);
        
        if ($response && isset($response['success']) && $response['success']) {
            return true;
        }
        
        return false;
    }
    
    /**
     * تضمین ورود به سیستم
     */
    private function ensureLogin() {
        if ($this->session_cookie === null) {
            return $this->login();
        }
        return true;
    }
    
    /**
     * ارسال درخواست HTTP
     */
    private function makeRequest($method, $url, $data = null, $use_cookie = true) {
        $ch = curl_init();
        
        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_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        
        $headers = [
            'Accept: application/json',
            'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        ];
        
        if ($use_cookie && $this->session_cookie) {
            curl_setopt($ch, CURLOPT_COOKIE, $this->session_cookie);
        }
        
        // ذخیره کوکی‌ها
        $cookie_file = sys_get_temp_dir() . '/xui_session_' . md5($this->panel_url . $this->username) . '.txt';
        curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
        
        if ($method === 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            if ($data) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
            }
        }
        
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        
        // برای ذخیره کوکی‌ها
        curl_setopt($ch, CURLOPT_HEADER, true);
        
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        
        $header = substr($response, 0, $header_size);
        $body = substr($response, $header_size);
        
        // استخراج کوکی‌ها
        if (preg_match_all('/Set-Cookie:\s*([^;]+)/i', $header, $matches)) {
            $cookies = implode('; ', $matches[1]);
            $this->session_cookie = $cookies;
        }
        
        if (curl_errno($ch)) {
            $this->log("CURL Error: " . curl_error($ch));
            curl_close($ch);
            return null;
        }
        
        curl_close($ch);
        
        $this->log("Response code: " . $http_code);
        $this->log("Response body: " . $body);
        
        return json_decode($body, true);
    }
    
    /**
     * تولید UUID جدید
     */
    private function generateUUID() {
        return 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)
        );
    }
    
    /**
     * تولید Sub ID تصادفی
     */
    private function generateSubId() {
        return bin2hex(random_bytes(8));
    }
    
    /**
     * لاگ برای دیباگ
     */
    private function log($message) {
        if ($this->debug_mode) {
            $log_file = __DIR__ . '/xui_api_debug.log';
            $timestamp = date('Y-m-d H:i:s');
            file_put_contents($log_file, "[{$timestamp}] {$message}\n", FILE_APPEND);
        }
    }
}
