<?php

namespace Tests\Feature;

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

class OcrInvoiceTest extends TestCase
{
    use RefreshDatabase;

    public function test_extract_parses_clean_json_response(): void
    {
        $this->makeCtx(claudeKey: 'sk-fake');

        Http::fake(['api.anthropic.com/*' => Http::response([
            'content' => [['type' => 'text', 'text' => json_encode([
                'supplier_name' => 'Acme Parts SRL',
                'date' => '2026-05-15',
                'currency' => 'MDL',
                'items' => [
                    ['name' => 'Filtru ulei', 'qty' => 2, 'unit_price' => 75, 'total' => 150],
                    ['name' => 'Filtru aer', 'qty' => 1, 'unit_price' => 90, 'total' => 90],
                ],
                'total' => 240,
            ])]],
            'usage' => ['input_tokens' => 1500, 'output_tokens' => 120],
        ])]);

        $img = $this->fakeImage();
        $r = app(OcrInvoiceService::class)->extract($img);

        $this->assertTrue($r['ok']);
        $this->assertEquals('Acme Parts SRL', $r['data']['supplier_name']);
        $this->assertEquals('2026-05-15', $r['data']['date']);
        $this->assertCount(2, $r['data']['items']);
        $this->assertEquals(240.0, $r['data']['total']);
        @unlink($img);
    }

    public function test_extract_strips_markdown_fences(): void
    {
        $this->makeCtx(claudeKey: 'sk-fake');

        $payload = json_encode(['supplier_name' => 'X', 'items' => [
            ['name' => 'Y', 'qty' => 1, 'unit_price' => 50],
        ]]);
        Http::fake(['api.anthropic.com/*' => Http::response([
            'content' => [['type' => 'text', 'text' => "```json\n{$payload}\n```"]],
            'usage' => ['input_tokens' => 100, 'output_tokens' => 30],
        ])]);

        $img = $this->fakeImage();
        $r = app(OcrInvoiceService::class)->extract($img);

        $this->assertTrue($r['ok']);
        $this->assertEquals('X', $r['data']['supplier_name']);
        @unlink($img);
    }

    public function test_extract_handles_malformed_response(): void
    {
        $this->makeCtx(claudeKey: 'sk-fake');

        Http::fake(['api.anthropic.com/*' => Http::response([
            'content' => [['type' => 'text', 'text' => 'this is not json at all']],
            'usage' => ['input_tokens' => 50, 'output_tokens' => 10],
        ])]);

        $img = $this->fakeImage();
        $r = app(OcrInvoiceService::class)->extract($img);

        $this->assertFalse($r['ok']);
        $this->assertStringContainsString('ne-parsabil', $r['error']);
        @unlink($img);
    }

    public function test_missing_api_key_returns_friendly_error(): void
    {
        $this->makeCtx(claudeKey: null);

        $img = $this->fakeImage();
        $r = app(OcrInvoiceService::class)->extract($img);

        $this->assertFalse($r['ok']);
        $this->assertStringContainsString('Setări', $r['error']);
        Http::assertNothingSent();
        @unlink($img);
    }

    public function test_unsupported_mime_rejected(): void
    {
        $this->makeCtx(claudeKey: 'sk-fake');

        $path = tempnam(sys_get_temp_dir(), 'ocr');
        file_put_contents($path, "%PDF-not really");

        $r = app(OcrInvoiceService::class)->extract($path, 'application/pdf');
        $this->assertFalse($r['ok']);
        $this->assertStringContainsString('Tip fișier', $r['error']);
        @unlink($path);
    }

    public function test_normalize_computes_item_total_when_missing(): void
    {
        $this->makeCtx(claudeKey: 'sk-fake');
        Http::fake(['api.anthropic.com/*' => Http::response([
            'content' => [['type' => 'text', 'text' => json_encode([
                'items' => [['name' => 'A', 'qty' => 3, 'unit_price' => 25]],
            ])]],
            'usage' => ['input_tokens' => 1, 'output_tokens' => 1],
        ])]);

        $img = $this->fakeImage();
        $r = app(OcrInvoiceService::class)->extract($img);
        $this->assertEquals(75.0, $r['data']['items'][0]['total']);
        $this->assertEquals(75.0, $r['data']['total']);
        @unlink($img);
    }

    private function makeCtx(?string $claudeKey): Company
    {
        $plan = Plan::firstOrCreate(['slug' => 'test'], ['name' => 'T', 'price' => 0, 'features' => []]);
        $company = Company::create([
            'plan_id' => $plan->id, 'slug' => 'ocr-' . uniqid(),
            'name' => 'OCR Co', 'status' => 'active',
            'settings' => ['ai' => ['claude_key' => $claudeKey]],
        ]);
        app(TenantManager::class)->setCurrent($company);
        return $company;
    }

    private function fakeImage(): string
    {
        // Minimal 1x1 PNG so mime_content_type returns image/png.
        $bytes = base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==');
        $path = tempnam(sys_get_temp_dir(), 'ocr') . '.png';
        file_put_contents($path, $bytes);
        return $path;
    }
}
