<?php

namespace Tests\Feature\Facades;

use App\Facades\File\FileFacade;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class FileTest extends TestCase
{
    use WithFaker;

    /**
     * A basic feature test example.
     */
    public function test_image_is_saved(): void
    {
        Storage::fake('public');

        $inputFile = UploadedFile::fake()->image($this->faker->image);
        $path = FileFacade::save($inputFile, 'testDir');

        Storage::disk('public')->assertExists($path);
    }

    public function test_image_is_saved_with_specified_name(): void
    {
        Storage::fake('public');

        $imageName = 'photo.png';
        $inputFile = UploadedFile::fake()->image($imageName);
        $actualPath = FileFacade::save($inputFile, 'testDir', $imageName);
        $expectedPath = 'testDir/photo.png';

        Storage::disk('public')->assertExists($actualPath);
        $this->assertEquals($expectedPath, $actualPath);
    }

    public function test_file_is_saved(): void
    {
        Storage::fake('public');

        $fileName = 'fake' . '.' . $this->faker->fileExtension();
        $inputFile = UploadedFile::fake()->create($fileName);
        $path = FileFacade::save($inputFile, 'testDir');

        Storage::disk('public')->assertExists($path);
    }

    public function test_file_is_saved_with_specified_name(): void
    {
        Storage::fake('public');

        $fileName = 'fake' . '.' . $this->faker->fileExtension();
        $inputFile = UploadedFile::fake()->create($fileName);
        $actualPath = FileFacade::save($inputFile, 'testDir', $fileName);
        $expectedPath = 'testDir/' . $fileName;

        Storage::disk('public')->assertExists($actualPath);
        $this->assertEquals($expectedPath, $actualPath);
    }

    public function test_file_is_saved_with_specified_disk(): void
    {
        Storage::fake('public');
        Storage::fake('p2');

        $fileName = 'fake' . '.' . $this->faker->fileExtension();
        $inputFile = UploadedFile::fake()->create($fileName);
        $path = FileFacade::save($inputFile, 'testDir', disk: 'p2');

        Storage::disk('p2')->assertExists($path);
        Storage::disk('public')->assertMissing($path);
    }

    public function test_delete_throws_exception_with_empty_file_path(): void
    {
        $this->assertThrows(
            fn() => FileFacade::delete(''),
            \InvalidArgumentException::class
        );
    }

    public function test_file_is_deleted(): void
    {
        Storage::fake('public');

        $fileName = 'fake' . '.' . $this->faker->fileExtension();
        $inputFile = UploadedFile::fake()->create($fileName);

        $path = Storage::disk('public')->putFile('testDir', $inputFile);

        Storage::disk('public')->assertExists($path);
        FileFacade::delete($path);
        Storage::disk('public')->assertMissing($path);
    }

    public function test_file_with_absolute_path_is_deleted(): void
    {
        Storage::fake('public');

        $fileName = 'fake' . '.' . $this->faker->fileExtension();
        $inputFile = UploadedFile::fake()->create($fileName);

        $path = Storage::disk('public')->putFile('testDir', $inputFile);
        $absolutePath = Storage::disk('public')->url($path);

        Storage::disk('public')->assertExists($path);
        FileFacade::delete($absolutePath, url_is_absolute: true);
        Storage::disk('public')->assertMissing($path);
    }
}
