<?php
declare(strict_types=1);

namespace App\Modules\Settings;

use App\Core\Http\SslCertificateResolver;

final class HostedSmsApiClient
{
    private const API_URL = 'https://api.hostedsms.pl/SimpleApi';

    public function __construct(private readonly int $timeoutSeconds = 15)
    {
    }

    /**
     * @return array{ok: bool, http_code: int, message: string, message_id: string}
     */
    public function sendSms(
        string $userEmail,
        string $password,
        string $sender,
        string $phone,
        string $message,
        bool $convertMessageToGsm7
    ): array {
        $payload = [
            'UserEmail' => trim($userEmail),
            'Password' => $password,
            'Sender' => trim($sender),
            'Phone' => trim($phone),
            'Message' => $message,
        ];

        if ($convertMessageToGsm7) {
            $payload['ConvertMessageToGSM7'] = 'true';
        }

        [$body, $httpCode, $curlError] = $this->postForm($payload);
        if ($curlError !== null) {
            return [
                'ok' => false,
                'http_code' => $httpCode,
                'message' => 'Blad polaczenia: ' . $curlError,
                'message_id' => '',
            ];
        }

        $decoded = json_decode(ltrim($body, "\xEF\xBB\xBF \t\n\r\0\x0B"), true);
        if (!is_array($decoded)) {
            return [
                'ok' => false,
                'http_code' => $httpCode,
                'message' => 'Niepoprawna odpowiedz JSON HostedSMS: ' . substr(trim(strip_tags($body)), 0, 180),
                'message_id' => '',
            ];
        }

        $messageId = trim((string) ($decoded['MessageId'] ?? ''));
        if ($httpCode >= 200 && $httpCode < 300 && $messageId !== '') {
            return [
                'ok' => true,
                'http_code' => $httpCode,
                'message' => 'MessageId: ' . $messageId,
                'message_id' => $messageId,
            ];
        }

        $errorMessage = trim((string) ($decoded['ErrorMessage'] ?? ''));
        if ($errorMessage === '') {
            $errorMessage = 'HTTP ' . $httpCode;
        }

        return [
            'ok' => false,
            'http_code' => $httpCode,
            'message' => $errorMessage,
            'message_id' => '',
        ];
    }

    /**
     * @param array<string, string> $payload
     * @return array{0: string, 1: int, 2: ?string}
     */
    private function postForm(array $payload): array
    {
        $ch = curl_init(self::API_URL);
        if ($ch === false) {
            return ['', 0, 'Nie udalo sie zainicjowac cURL.'];
        }

        $options = [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query($payload),
            CURLOPT_TIMEOUT => $this->timeoutSeconds,
            CURLOPT_CONNECTTIMEOUT => 10,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_SSL_VERIFYHOST => 2,
            CURLOPT_HTTPHEADER => [
                'Accept: application/json',
                'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
                'User-Agent: orderPRO/1.0',
            ],
        ];

        $caPath = SslCertificateResolver::resolve();
        if ($caPath !== null) {
            $options[CURLOPT_CAINFO] = $caPath;
        }

        curl_setopt_array($ch, $options);
        $rawBody = curl_exec($ch);
        $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlError = curl_error($ch);
        unset($ch);

        if ($rawBody === false) {
            return ['', $httpCode, $curlError !== '' ? $curlError : 'Brak odpowiedzi z API.'];
        }

        return [(string) $rawBody, $httpCode, null];
    }
}
