<?php

namespace Tests\Feature;

use App\Domain\Media\AttachmentStorageService;
use App\Models\Attachment;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class LocalAttachmentServeTest extends TestCase
{
    use RefreshDatabase;

    protected string $attachmentsRoot;

    protected function setUp(): void
    {
        parent::setUp();

        $this->attachmentsRoot = storage_path('framework/testing/attachments-'.uniqid());
        File::ensureDirectoryExists($this->attachmentsRoot);

        config([
            'filesystems.disks.attachments' => [
                'driver' => 'local',
                'root' => $this->attachmentsRoot,
                'url' => rtrim((string) config('app.url'), '/').'/attachments-local',
                'visibility' => 'public',
                'throw' => true,
            ],
            'larablog.attachments_disk' => 'attachments',
        ]);
    }

    protected function tearDown(): void
    {
        if (isset($this->attachmentsRoot) && is_dir($this->attachmentsRoot)) {
            File::deleteDirectory($this->attachmentsRoot);
        }

        parent::tearDown();
    }

    public function test_local_driver_attachment_url_is_servable(): void
    {
        Storage::disk('attachments')->put('demo/hello.txt', 'hello');
        $attachment = Attachment::query()->create([
            'disk' => 'attachments',
            'path' => 'demo/hello.txt',
            'filename' => 'hello.txt',
            'mime' => 'text/plain',
            'size' => 5,
            'visibility' => Attachment::VISIBILITY_PUBLIC,
            'synced_at' => now(),
            'downloads' => 0,
        ]);

        $url = app(AttachmentStorageService::class)->publicUrl($attachment);
        $this->assertStringContainsString('/attachments-local/', $url);

        $path = parse_url($url, PHP_URL_PATH);
        $response = $this->get($path);
        $response->assertOk();
        $this->assertStringContainsString('hello', $response->streamedContent());

        $this->get('/attachment.php?id='.$attachment->id)->assertRedirect();
    }

    public function test_deleting_attachment_removes_disk_object(): void
    {
        Storage::disk('attachments')->put('orphan.bin', 'x');
        $attachment = Attachment::query()->create([
            'disk' => 'attachments',
            'path' => 'orphan.bin',
            'filename' => 'orphan.bin',
            'size' => 1,
            'visibility' => Attachment::VISIBILITY_PUBLIC,
            'synced_at' => now(),
        ]);

        $this->assertTrue(is_file($this->attachmentsRoot.'/orphan.bin'));
        $attachment->delete();
        $this->assertFalse(is_file($this->attachmentsRoot.'/orphan.bin'));
    }
}
