<?php

namespace Tests\Feature\MediaFolder;

use App\Models\Backoffice\MediaFolder;
use Tests\TestCase;
use Illuminate\Support\Facades\Storage;

class CreateFolderTest extends TestCase
{
    public function testItThrowsValidationErrorWhenCreatingFolderWithMissingOrInvalidName()
    {
        $response = $this->actingAsAdmin()->postJson('/admin/media/folders', [
            'base_folder' => 'default',
        ]);

        $response->assertStatus(422)
            ->assertJsonValidationErrors(['name'])
            ->assertJsonFragment([
                'name' => ['The name field is required.'],
            ]);

        $response = $this->actingAsAdmin()->postJson('/admin/media/folders', [
            'name' => 'invalid$folder',
            'base_folder' => 'default',
        ]);

        $response->assertStatus(422)
            ->assertJsonValidationErrors(['name'])
            ->assertJsonFragment([
                'name' => ['The name field format is invalid.'],
            ]);
    }

    public function testItThrowsExceptionWhenCreatingFolderWithInvalidBaseFolder()
    {
        Storage::fake('media');

        $response = $this->actingAsAdmin()->postJson('/admin/media/folders', [
            'name' => 'newfolder',
            'base_folder' => 'invalid_folder',
        ]);
        $data = $response->json();

        $response->assertStatus(500);
        $this->assertEquals("Base folder 'invalid_folder' not found in config/media.php", $data['message']);
    }

    public function testItThrowsExceptionWhenCreatingFolderWithExistingFolder()
    {
        Storage::fake('media');
        Storage::disk('media')->makeDirectory('parent/existing');

        $parent = MediaFolder::create([
            'base_folder' => 'media',
            'path' => 'parent',
            'name' => 'parent',
            'parent_id' => null,
        ]);

        $response = $this->actingAsAdmin()->postJson('/admin/media/folders', [
            'parent_id' => $parent->id,
            'name' => 'existing',
            'base_folder' => 'default',
        ]);

        $response->assertStatus(500)
            ->assertJson([
                'error' => "Folder 'parent/existing' already exists",
            ]);
    }

    public function testItCreatesFolderWithParentId()
    {
        Storage::fake('media');

        $parent = MediaFolder::create([
            'base_folder' => 'media',
            'path' => 'parent',
            'name' => 'parent',
            'parent_id' => null,
        ]);

        $response = $this->actingAsAdmin()->postJson('/admin/media/folders', [
            'parent_id' => $parent->id,
            'name' => 'newFolder',
            'base_folder' => 'default',
        ]);

        $response->assertStatus(201)
            ->assertJsonStructure(['id', 'baseFolder', 'path', 'name'])
            ->assertJson([
                'baseFolder' => 'media',
                'path' => 'parent/newFolder',
                'name' => 'newFolder',
            ]);

        $this->assertDatabaseHas('media_folders', [
            'base_folder' => 'media',
            'path' => 'parent/newFolder',
            'name' => 'newFolder',
            'parent_id' => $parent->id,
        ]);

        Storage::disk('media')->assertExists('parent/newFolder');
    }

    public function testItCreatesFolderWithoutParentId()
    {
        Storage::fake('media');

        $response = $this->actingAsAdmin()->postJson('/admin/media/folders', [
            'name' => 'rootFolder',
            'base_folder' => 'default',
        ]);

        $response->assertStatus(201)
            ->assertJsonStructure(['id', 'baseFolder', 'path', 'name'])
            ->assertJson([
                'baseFolder' => 'media',
                'path' => 'rootFolder',
                'name' => 'rootFolder',
            ]);

        $this->assertDatabaseHas('media_folders', [
            'base_folder' => 'media',
            'path' => 'rootFolder',
            'name' => 'rootFolder',
            'parent_id' => null,
        ]);

        Storage::disk('media')->assertExists('rootFolder');
    }

    public function testItCreatesFolderWithoutBaseFolder()
    {
        Storage::fake('media');

        $parent = MediaFolder::create([
            'base_folder' => 'media',
            'path' => 'parent',
            'name' => 'parent',
            'parent_id' => null,
        ]);

        $response = $this->actingAsAdmin()->postJson('/admin/media/folders', [
            'parent_id' => $parent->id,
            'name' => 'newFolder',
        ]);

        $response->assertStatus(201)
            ->assertJsonStructure(['id', 'baseFolder', 'path', 'name'])
            ->assertJson([
                'baseFolder' => 'media',
                'path' => 'parent/newFolder',
                'name' => 'newFolder',
            ]);

        $this->assertDatabaseHas('media_folders', [
            'base_folder' => 'media',
            'path' => 'parent/newFolder',
            'name' => 'newFolder',
            'parent_id' => $parent->id,
        ]);

        Storage::disk('media')->assertExists('parent/newFolder');
    }

    public function testItCreatesFolderInSubdirectory()
    {
        Storage::fake('media');

        $parent = MediaFolder::create([
            'base_folder' => 'media',
            'path' => 'parent',
            'name' => 'parent',
            'parent_id' => null,
        ]);

        $subFolder = MediaFolder::create([
            'base_folder' => 'media',
            'path' => 'parent/subFolder',
            'name' => 'subFolder',
            'parent_id' => $parent->id,
        ]);

        $response = $this->actingAsAdmin()->postJson('/admin/media/folders', [
            'parent_id' => $subFolder->id,
            'name' => 'newFolder',
            'base_folder' => 'default',
        ]);

        $response->assertStatus(201)
            ->assertJsonStructure(['id', 'baseFolder', 'path', 'name'])
            ->assertJson([
                'baseFolder' => 'media',
                'path' => 'parent/subFolder/newFolder',
                'name' => 'newFolder',
            ]);

        $this->assertDatabaseHas('media_folders', [
            'base_folder' => 'media',
            'path' => 'parent/subFolder/newFolder',
            'name' => 'newFolder',
            'parent_id' => $subFolder->id,
        ]);

        Storage::disk('media')->assertExists('parent/subFolder/newFolder');
    }
}
