<?php

namespace Tests\Feature\Audit;

use App\Models\Central\Company;
use App\Models\Central\Plan;
use App\Services\Ai\AiAssistantService;
use App\Tenancy\TenantManager;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;

/**
 * The 3 AI providers share infrastructure but each has a different request
 * shape. After the model selector refactor, verify each provider still uses
 * the configured model + key in the actual HTTP call.
 */
class AiProvidersCrossCheckTest extends TestCase
{
    use RefreshDatabase;

    public function test_openai_singleshot_uses_configured_model_and_sends_messages(): void
    {
        $this->bootCompany('gpt', 'gpt-fake');

        Http::fake(['api.openai.com/*' => Http::response([
            'choices' => [['message' => ['content' => 'OpenAI response']]],
            'usage' => ['prompt_tokens' => 50, 'completion_tokens' => 12],
            'model' => 'gpt-4o-mini',
        ])]);

        [$reply, $meta] = app(AiAssistantService::class)->singleShot('system here', 'user prompt', 'gpt');

        $this->assertEquals('OpenAI response', $reply);
        $this->assertEquals('gpt', $meta['provider']);
        Http::assertSent(function ($req) {
            if (! str_contains($req->url(), 'openai.com')) return false;
            $body = json_decode($req->body(), true);
            return $body['model'] === 'gpt-4o-mini'
                && $body['messages'][0]['role'] === 'system'
                && str_contains($body['messages'][0]['content'], 'system here');
        });
    }

    public function test_gemini_singleshot_hits_url_with_configured_model(): void
    {
        $this->bootCompany('gemini', 'gem-fake');

        Http::fake(['generativelanguage.googleapis.com/*' => Http::response([
            'candidates' => [['content' => ['parts' => [['text' => 'Gemini response']]]]],
            'usageMetadata' => ['promptTokenCount' => 30],
        ])]);

        [$reply, $meta] = app(AiAssistantService::class)->singleShot('s', 'u', 'gemini');

        $this->assertEquals('Gemini response', $reply);
        Http::assertSent(fn ($req) => str_contains($req->url(), 'gemini-1.5-flash:generateContent'));
    }

    public function test_no_api_key_returns_friendly_message_without_http(): void
    {
        $this->bootCompany('claude', null);

        Http::fake();
        [$reply, $meta] = app(AiAssistantService::class)->singleShot('s', 'u', 'claude');

        $this->assertStringContainsString('API key', $reply);
        $this->assertEquals('no_api_key', $meta['error']);
        Http::assertNothingSent();
    }

    public function test_tenant_model_override_propagates_into_request(): void
    {
        $plan = Plan::firstOrCreate(['slug' => 'test'], ['name' => 'T', 'price' => 0, 'features' => []]);
        $company = Company::create([
            'plan_id' => $plan->id, 'slug' => 'override-' . uniqid(),
            'name' => 'O', 'status' => 'active',
            'settings' => [
                'ai' => [
                    'claude_key' => 'sk-fake',
                    'models' => ['claude' => 'claude-opus-4-7'],
                ],
            ],
        ]);
        app(TenantManager::class)->setCurrent($company);

        Http::fake(['api.anthropic.com/*' => Http::response([
            'content' => [['type' => 'text', 'text' => 'ok']],
            'usage' => ['input_tokens' => 1, 'output_tokens' => 1],
        ])]);

        app(AiAssistantService::class)->singleShot('s', 'u', 'claude');

        Http::assertSent(function ($req) {
            $body = json_decode($req->body(), true);
            return $body['model'] === 'claude-opus-4-7';
        });
    }

    private function bootCompany(string $provider, ?string $key): Company
    {
        $plan = Plan::firstOrCreate(['slug' => 'test'], ['name' => 'T', 'price' => 0, 'features' => []]);
        $company = Company::create([
            'plan_id' => $plan->id, 'slug' => 'ai-' . uniqid(),
            'name' => 'AI Co', 'status' => 'active',
            'settings' => ['ai' => [
                'default_provider' => $provider,
                "{$provider}_key" => $key,
            ]],
        ]);
        app(TenantManager::class)->setCurrent($company);
        return $company;
    }
}
