<?php
namespace EasyChat\Library\Voice;

use CURLFile;
use EasyChat\Library\EasyTokensClientHeaders;
use EasyChat\Library\Http\ExternalHttpClient;

 
class EasyTokensAudioClient {
    private $http;

    public function __construct($registry, ?ExternalHttpClient $http = null) {
        $this->http = $http ?: new ExternalHttpClient($registry);
    }

    public function transcribe(string $path, string $mime, string $display_name, string $api_key, string $idempotency_key): array {
        if (!is_file($path) || filesize($path) <= 0) {
            return ['success' => false, 'error' => 'audio_file_missing', 'retryable' => false];
        }
        $api_key = $this->firstKey($api_key);
        if ($api_key === '') {
            return ['success' => false, 'error' => 'api_key_missing', 'retryable' => false];
        }

        $headers = EasyTokensClientHeaders::append([
            'Authorization: Bearer ' . $api_key,
            'Accept: application/json',
            'Idempotency-Key: ' . substr(hash('sha256', $idempotency_key), 0, 64),
        ]);
        $response = $this->http->request('POST', 'https://api.easytokens.ru/v1/audio/transcriptions', [
            'headers' => $headers,
            'post_fields' => [
                'file' => new CURLFile($path, $mime, basename($display_name) ?: basename($path)),
                'model' => 'gpt-4o-transcribe',
                'response_format' => 'verbose_json',
                'temperature' => '0',
            ],
            'connect_timeout' => 10,
            'timeout' => 240,
            'follow_location' => false,
            'trust_profile' => 'easytokens',
            'proxy_profile' => 'ai_easytokens',
            'allow_tls_fallback' => true,
        ]);

        $http_code = (int)($response['http_code'] ?? 0);
        if (empty($response['transport_ok']) || $http_code < 200 || $http_code >= 300) {
            return [
                'success' => false,
                'error' => $this->httpError($http_code, (string)($response['raw'] ?? '')),
                'http_code' => $http_code,
                'retryable' => $http_code === 0 || $http_code === 408 || $http_code === 429 || $http_code >= 500,
            ];
        }

        $payload = json_decode((string)($response['raw'] ?? ''), true);
        if (!is_array($payload)) {
            return ['success' => false, 'error' => 'transcription_bad_response', 'retryable' => true];
        }
        $text = trim((string)($payload['text'] ?? ''));
        if (function_exists('mb_substr')) {
            $text = mb_substr($text, 0, 100000, 'UTF-8');
        } else {
            $text = substr($text, 0, 100000);
        }
        return [
            'success' => true,
            'text' => $text,
            'language' => substr(preg_replace('/[^a-zA-Z_-]/', '', (string)($payload['language'] ?? '')), 0, 16),
            'duration' => max(0, (int)ceil((float)($payload['duration'] ?? $payload['usage']['seconds'] ?? 0))),
        ];
    }

    private function firstKey(string $value): string {
        foreach ((array)preg_split('/\r\n|\r|\n/', $value) as $line) {
            $line = trim((string)$line);
            if ($line !== '') return $line;
        }
        return '';
    }

    private function httpError(int $http_code, string $body): string {
        $payload = json_decode($body, true);
        $detail = is_array($payload) ? (string)($payload['detail'] ?? $payload['error']['code'] ?? '') : '';
        $detail = strtolower(preg_replace('/[^a-z0-9_ -]/i', '', $detail));
        if ($http_code === 401 || $http_code === 403) return 'transcription_auth_failed';
        if ($http_code === 402) return 'transcription_balance_required';
        if ($http_code === 413) return 'audio_size_exceeded';
        if ($http_code === 429) return 'transcription_rate_limited';
        if ($http_code >= 500 || $http_code === 0) return 'transcription_temporarily_unavailable';
        return $detail !== '' ? 'transcription_rejected' : 'transcription_failed';
    }
}
