<?php
/**
 * کلاینت ساخت لینک کوتاه ۶۳۶ برای سایت یا اسکریپت خودت.
 *
 * این فایل به لاراول وابسته نیست. فقط PHP با افزونهٔ curl لازم است.
 *
 *   $api = new SixThreeSixShortLink('https://636.ir', getenv('SIX36_API_TOKEN') ?: '');
 *   $link = $api->create('https://example.com/page', 'عنوان');
 *   echo $link['short_url'];
 *
 * کلید را از داشبورد → API لینک بگیر. کلید را در گیت یا صفحهٔ وب نگذار.
 */
declare(strict_types=1);

final class SixThreeSixShortLink
{
    private string $base;
    private string $token;

    public function __construct(string $baseUrl, string $apiToken)
    {
        $base = rtrim(trim($baseUrl), '/');
        if ($base === '' || ! preg_match('#^https?://#i', $base)) {
            throw new SixThreeSixShortLinkException('آدرس پایهٔ سایت نامعتبر است.');
        }
        if ($apiToken === '') {
            throw new SixThreeSixShortLinkException('کلید API خالی است.');
        }

        $this->base = $base;
        $this->token = $apiToken;
    }

    /**
     * یک لینک کوتاه برای حساب صاحب کلید می‌سازد.
     *
     * @return array{code:string,short_url:string,title:?string}
     */
    public function create(string $url, ?string $title = null, ?string $code = null, ?string $brand = null): array
    {
        $url = trim($url);
        if ($url === '' || ! preg_match('#^https?://#i', $url)) {
            throw new SixThreeSixShortLinkException('آدرس مقصد باید با http یا https شروع شود.');
        }

        $payload = ['url' => $url];
        if ($title !== null && trim($title) !== '') {
            $payload['title'] = mb_substr(trim($title), 0, 120);
        }
        if ($code !== null && trim($code) !== '') {
            $payload['code'] = trim($code);
        }
        if ($brand !== null && trim($brand) !== '') {
            $payload['brand'] = trim($brand);
        }

        $res = $this->httpPost($this->base.'/api/links', $payload);
        $json = json_decode($res['body'], true);
        if (! is_array($json)) {
            throw new SixThreeSixShortLinkException('پاسخ API نامعتبر است. HTTP '.$res['code']);
        }

        if ($res['code'] < 200 || $res['code'] >= 300 || empty($json['short_url'])) {
            $message = (string) ($json['message'] ?? '');
            if ($message === '' && isset($json['errors']) && is_array($json['errors'])) {
                $first = reset($json['errors']);
                $message = is_array($first) ? (string) reset($first) : (string) $first;
            }
            if ($message === '') {
                $message = 'HTTP '.$res['code'];
            }
            throw new SixThreeSixShortLinkException('ساخت لینک ناموفق: '.$message);
        }

        return [
            'code' => (string) ($json['code'] ?? ''),
            'short_url' => (string) $json['short_url'],
            'title' => array_key_exists('title', $json) ? (isset($json['title']) ? (string) $json['title'] : null) : null,
        ];
    }

    /** @param array<string, string> $fields */
    private function httpPost(string $url, array $fields): array
    {
        if (! function_exists('curl_init')) {
            throw new SixThreeSixShortLinkException('افزونهٔ curl روی سرور فعال نیست.');
        }

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'Accept: application/json',
                'Authorization: Bearer '.$this->token,
            ],
            CURLOPT_POSTFIELDS => json_encode($fields, JSON_UNESCAPED_UNICODE),
            CURLOPT_TIMEOUT => 20,
            CURLOPT_CONNECTTIMEOUT => 8,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        ]);
        $body = curl_exec($ch);
        $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        if ($body === false) {
            throw new SixThreeSixShortLinkException('تماس با ۶۳۶ ناموفق بود: '.$error);
        }

        return ['code' => $code, 'body' => (string) $body];
    }
}

final class SixThreeSixShortLinkException extends RuntimeException
{
}
