<?php
/**
 * کلاینت API «خدمات شبکه‌های اجتماعی» (apiaddress.com)
 * ------------------------------------------------------------
 * فقط دقیقا همان Endpointهایی که در مستندات ارائه‌شده توسط کاربر آمده پیاده‌سازی
 * شده‌اند (services / add / status / refill / refill_status / cancel / balance).
 * هیچ Endpoint یا پارامتر فرضی/حدسی اضافه نشده. طبق تاکید مستندات، Dripfeed
 * پشتیبانی نمی‌شود؛ بنابراین هیچ‌کدام از پارامترهای dripfeed/runs/interval در
 * هیچ‌جای این کلاینت ارسال نمی‌شود.
 *
 * ⚠️ ابهام مستندات (قبل از حدس زدن مشخص شده تا بعدا بررسی/تایید شود):
 * پاسخ Endpoint «status» در نمونه‌های ارائه‌شده دو شکل متفاوت دارد:
 *   ۱) وقتی یک orders=ID تکی درخواست می‌شود: به‌نظر می‌رسد پاسخ می‌تواند مستقیم
 *      همان آبجکت وضعیت باشد (فیلدهای charge/start_count/status/remains در سطح اول).
 *   ۲) وقتی چند orders با کاما درخواست می‌شود: پاسخ یک آبجکت/دیکشنری است که
 *      کلیدش شناسه‌ی سفارش و مقدارش همان آبجکت وضعیت (یا {"error":...}) است.
 * چون در این پروژه هر بار فقط وضعیت یک سفارش را می‌خواهیم (smmClient->status
 * با یک orderId تکی صدا زده می‌شود)، متد status() هر دو شکل را پشتیبانی
 * می‌کند: اگر پاسخ کلید 'status' در سطح اول داشت همان را برمی‌گرداند، وگرنه
 * دنبال کلید $orderId داخل آرایه‌ی پاسخ می‌گردد.
 */

require_once __DIR__ . '/request.php';

class SmmApiClient
{
    private $baseUrl;
    private $apiKey;

    public function __construct($baseUrl, $apiKey)
    {
        $this->baseUrl = rtrim((string) $baseUrl, '/');
        $this->apiKey = (string) $apiKey;
    }

    public function isConfigured()
    {
        return $this->baseUrl !== '' && $this->apiKey !== '';
    }

    #-----------------[ فراخوانی خام Endpoint پایه (GET) ]-------------------#
    private function call(array $params)
    {
        if (!$this->isConfigured()) {
            return ['ok' => false, 'error_type' => 'not_configured', 'data' => null];
        }
        $params = array_merge(['key' => $this->apiKey], $params);
        $url = $this->baseUrl . '?' . http_build_query($params);

        $req = new CurlRequest($url);
        $req->setTimeout(15000);
        $res = $req->get();

        if (!empty($res['error'])) {
            return ['ok' => false, 'error_type' => 'connection_error', 'error_detail' => $res['error'], 'data' => null];
        }
        $body = $res['body'] ?? null;
        if ($body === null || $body === '') {
            return ['ok' => false, 'error_type' => 'empty_response', 'data' => null];
        }
        $data = json_decode($body, true);
        if (json_last_error() !== JSON_ERROR_NONE || $data === null) {
            return ['ok' => false, 'error_type' => 'invalid_json', 'data' => null, 'raw' => substr($body, 0, 500)];
        }
        if (is_array($data) && isset($data['error']) && !isset($data['balance']) && !isset($data['order'])) {
            return ['ok' => false, 'error_type' => 'api_error', 'error_detail' => $data['error'], 'data' => $data];
        }
        return ['ok' => true, 'data' => $data, 'http_status' => $res['status'] ?? null];
    }

    #-----------------[ GET/POST https://apiaddress.com/v2?...&action=services ]-------------------#
    public function services()
    {
        return $this->call(['action' => 'services']);
    }

    #-----------------[ GET/POST ...&action=add&service=&link=&quantity= ]-------------------#
    public function addOrder($serviceId, $link, $quantity)
    {
        return $this->call([
            'action' => 'add',
            'service' => $serviceId,
            'link' => $link,
            'quantity' => $quantity,
        ]);
    }

    #-----------------[ GET/POST ...&action=status&orders=ID (تکی، طبق نیاز این پروژه) ]-------------------#
    public function status($orderId)
    {
        $res = $this->call(['action' => 'status', 'orders' => $orderId]);
        if (!$res['ok']) return $res;

        $data = $res['data'];
        // حالت ۱: پاسخ مستقیم آبجکت وضعیت است.
        if (isset($data['status'])) {
            $res['status_data'] = $data;
            return $res;
        }
        // حالت ۲: پاسخ دیکشنری‌ست با کلید شناسه‌ی سفارش.
        if (isset($data[$orderId]) && is_array($data[$orderId])) {
            if (isset($data[$orderId]['error'])) {
                return ['ok' => false, 'error_type' => 'api_error', 'error_detail' => $data[$orderId]['error'], 'data' => $data];
            }
            $res['status_data'] = $data[$orderId];
            return $res;
        }
        return ['ok' => false, 'error_type' => 'invalid_response', 'data' => $data];
    }

    #-----------------[ GET/POST ...&action=refill&order=ID ]-------------------#
    public function refill($orderId)
    {
        return $this->call(['action' => 'refill', 'order' => $orderId]);
    }

    #-----------------[ GET/POST ...&action=refill_status&refill=ID ]-------------------#
    public function refillStatus($refillId)
    {
        return $this->call(['action' => 'refill_status', 'refill' => $refillId]);
    }

    #-----------------[ GET/POST ...&action=cancel&orders=ID ]-------------------#
    public function cancel($orderId)
    {
        return $this->call(['action' => 'cancel', 'orders' => $orderId]);
    }

    #-----------------[ GET/POST ...&action=balance ]-------------------#
    public function balance()
    {
        return $this->call(['action' => 'balance']);
    }
}
