<?php

use App\Ai\Agents\MealImageAnalyzer;
use App\Enums\IngredientUnit;
use App\Enums\MealPostType;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Laravel\Sanctum\Sanctum;

uses(RefreshDatabase::class);

function fakeMealAnalysisImage(): UploadedFile
{
    $path = tempnam(sys_get_temp_dir(), 'meal-analysis-');

    file_put_contents($path, base64_decode(
        'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAFgwJ/lmHqWQAAAABJRU5ErkJggg=='
    ));

    return new UploadedFile($path, 'meal.png', 'image/png', null, true);
}

it('analyzes a meal image into a draft', function () {
    Sanctum::actingAs(User::factory()->create());

    MealImageAnalyzer::fake([
        [
            'title' => ' Bowl saumon avocat ',
            'caption' => 'Un bowl avec du saumon, du riz et de l’avocat.',
            'type' => MealPostType::LUNCH->value,
            'calories' => 612,
            'proteins' => 39.4,
            'carbs' => 58.2,
            'fats' => 25.1,
            'ingredients' => [
                [
                    'position' => 12,
                    'ingredient' => ' Riz ',
                    'quantity' => 150,
                    'unit' => IngredientUnit::GRAM->value,
                ],
                [
                    'position' => 13,
                    'ingredient' => 'Saumon',
                    'quantity' => 120,
                    'unit' => IngredientUnit::GRAM->value,
                ],
            ],
        ],
    ]);

    $response = $this
        ->withHeader('Accept', 'application/json')
        ->post('/api/meal-posts/analyze-image', [
            'image' => fakeMealAnalysisImage(),
        ]);

    $response
        ->assertOk()
        ->assertJsonPath('data.title', 'Bowl saumon avocat')
        ->assertJsonPath('data.type', MealPostType::LUNCH->value)
        ->assertJsonPath('data.calories', 612)
        ->assertJsonPath('data.proteins', 39.4)
        ->assertJsonPath('data.ingredients.0.position', 1)
        ->assertJsonPath('data.ingredients.0.ingredient', 'Riz')
        ->assertJsonPath('data.ingredients.1.ingredient', 'Saumon');

    MealImageAnalyzer::assertPrompted(
        fn ($prompt): bool => str_contains($prompt->prompt, "Analyse l'image")
            && $prompt->attachments->count() === 1
    );
});

it('requires authentication to analyze a meal image', function () {
    $this
        ->withHeader('Accept', 'application/json')
        ->post('/api/meal-posts/analyze-image', [
            'image' => fakeMealAnalysisImage(),
        ])
        ->assertUnauthorized();
});

it('validates the analyzed image', function () {
    Sanctum::actingAs(User::factory()->create());

    $this
        ->postJson('/api/meal-posts/analyze-image')
        ->assertUnprocessable()
        ->assertJsonValidationErrors(['image']);
});
