<?php

namespace Tests\Unit\Services;

use App\Models\Voice;
use App\Services\AI\LaravelAiVoiceSynthesizer;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use RuntimeException;
use Tests\TestCase;

class LaravelAiVoiceSynthesizerTest extends TestCase
{
    public function test_it_previews_a_gemini_voice_and_stores_the_wav(): void
    {
        Storage::fake('public');
        config([
            'ai.providers.gemini.key' => 'test-key',
            'ai.providers.gemini.url' => 'https://generativelanguage.googleapis.com/v1beta/',
            'ai.providers.gemini.models.audio.default' => 'gemini-3.8-flash-tts',
        ]);
        Http::fake(['*/interactions' => Http::response([
            'steps' => [['type' => 'model_output', 'content' => [[
                'type' => 'audio',
                'data' => base64_encode('RIFF0000WAVEfake-wav-bytes'),
            ]]]],
        ])]);

        $voice = new Voice([
            'provider' => 'gemini',
            'provider_voice_id' => 'Achernar',
            'tone' => 'soft',
            'accent' => 'American',
        ]);
        $path = (new LaravelAiVoiceSynthesizer)->preview($voice, 'Hello there.');

        $this->assertStringStartsWith('voices/previews/', $path);
        $this->assertStringEndsWith('.wav', $path);
        Storage::disk('public')->assertExists($path);
        $this->assertSame('RIFF0000WAVEfake-wav-bytes', Storage::disk('public')->get($path));
        Http::assertSent(fn ($request): bool => $request['model'] === 'gemini-3.8-flash-tts'
            && $request['input'][0]['content'][0]['text'] === 'Hello there.'
            && $request['generation_config']['speech_config'][0]['voice'] === 'Achernar');
    }

    public function test_it_rejects_non_gemini_voice_ids(): void
    {
        Http::fake();

        $this->expectException(RuntimeException::class);
        $this->expectExceptionMessage('Only Gemini voices');

        (new LaravelAiVoiceSynthesizer)->preview(new Voice([
            'provider' => 'openai',
            'provider_voice_id' => 'alloy',
        ]));
    }

    public function test_it_rejects_a_response_without_wav_audio(): void
    {
        config(['ai.providers.gemini.key' => 'test-key']);
        Http::fake(['*/interactions' => Http::response(['steps' => []])]);

        $this->expectException(RuntimeException::class);
        $this->expectExceptionMessage('valid WAV');

        (new LaravelAiVoiceSynthesizer)->preview(new Voice([
            'provider' => 'gemini',
            'provider_voice_id' => 'Achernar',
        ]));
    }
}
