<?php
namespace Tests\Feature\Candidat;

use App\Models\Candidat;
use App\Models\PieceJointe;
use App\Models\User;
use App\Models\Ville;
use App\Enums\StatutCompteUser;
use App\Enums\TypeDocument;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class PieceJointeTest extends TestCase
{
    use RefreshDatabase;

    private User $candidatUser;
    private Candidat $candidat;

    protected function setUp(): void
    {
        parent::setUp();
        Storage::fake('local');
        $ville = Ville::factory()->active()->create();
        $this->candidatUser = User::factory()->candidat()->create(['statut' => StatutCompteUser::ACTIF]);
        $this->candidat = Candidat::factory()->create([
            'user_id'  => $this->candidatUser->id,
            'ville_id' => $ville->id,
        ]);
    }

    public function test_candidat_peut_uploader_une_piece_jointe(): void
    {
        $fichier = UploadedFile::fake()->create('cni.pdf', 1024, 'application/pdf');

        $response = $this->actingAs($this->candidatUser)
            ->postJson('/api/candidat/pieces-jointes', [
                'type_document' => TypeDocument::CNI_PASSEPORT->value,
                'fichier'       => $fichier,
            ]);

        $response->assertStatus(201)
            ->assertJsonStructure(['piece_jointe' => ['id', 'type_document', 'statut_validation']]);

        $this->assertDatabaseHas('pieces_jointes', [
            'candidat_id'   => $this->candidat->id,
            'type_document' => TypeDocument::CNI_PASSEPORT->value,
        ]);
    }

    public function test_upload_remplace_lancienne_piece_du_meme_type(): void
    {
        $fichier1 = UploadedFile::fake()->create('cni1.pdf', 512, 'application/pdf');
        $fichier2 = UploadedFile::fake()->create('cni2.pdf', 512, 'application/pdf');

        $this->actingAs($this->candidatUser)
            ->postJson('/api/candidat/pieces-jointes', [
                'type_document' => TypeDocument::CNI_PASSEPORT->value,
                'fichier'       => $fichier1,
            ]);

        $this->actingAs($this->candidatUser)
            ->postJson('/api/candidat/pieces-jointes', [
                'type_document' => TypeDocument::CNI_PASSEPORT->value,
                'fichier'       => $fichier2,
            ]);

        $this->assertEquals(
            1,
            PieceJointe::where('candidat_id', $this->candidat->id)
                ->where('type_document', TypeDocument::CNI_PASSEPORT->value)
                ->count()
        );
    }

    public function test_upload_fichier_invalide_retourne_erreur(): void
    {
        $fichier = UploadedFile::fake()->create('script.exe', 512, 'application/octet-stream');

        $response = $this->actingAs($this->candidatUser)
            ->postJson('/api/candidat/pieces-jointes', [
                'type_document' => TypeDocument::CNI_PASSEPORT->value,
                'fichier'       => $fichier,
            ]);

        $response->assertStatus(422);
    }

    public function test_candidat_peut_lister_ses_pieces_jointes(): void
    {
        PieceJointe::factory()->count(3)->create(['candidat_id' => $this->candidat->id]);

        $response = $this->actingAs($this->candidatUser)
            ->getJson('/api/candidat/pieces-jointes');

        $response->assertStatus(200)
            ->assertJsonCount(3, 'pieces_jointes');
    }

    public function test_candidat_peut_supprimer_une_piece_en_attente(): void
    {
        $piece = PieceJointe::factory()->create([
            'candidat_id'       => $this->candidat->id,
            'statut_validation' => 'en_attente',
        ]);

        $response = $this->actingAs($this->candidatUser)
            ->deleteJson("/api/candidat/pieces-jointes/{$piece->id}");

        $response->assertStatus(200);
        $this->assertDatabaseMissing('pieces_jointes', ['id' => $piece->id]);
    }

    public function test_candidat_ne_peut_pas_supprimer_piece_validee(): void
    {
        $piece = PieceJointe::factory()->valide()->create([
            'candidat_id' => $this->candidat->id,
        ]);

        $response = $this->actingAs($this->candidatUser)
            ->deleteJson("/api/candidat/pieces-jointes/{$piece->id}");

        $response->assertStatus(422);
    }

    public function test_chemin_stockage_jamais_expose_dans_api(): void
    {
        PieceJointe::factory()->create(['candidat_id' => $this->candidat->id]);

        $response = $this->actingAs($this->candidatUser)
            ->getJson('/api/candidat/pieces-jointes');

        $response->assertStatus(200);
        // Vérifie que chemin_stockage n'apparaît JAMAIS dans la réponse
        $this->assertStringNotContainsString('chemin_stockage', $response->content());
    }

    public function test_piece_dun_autre_candidat_non_accessible(): void
    {
        $autreVille = Ville::factory()->active()->create();
        $autreUser = User::factory()->candidat()->create(['statut' => StatutCompteUser::ACTIF]);
        $autreCandidat = Candidat::factory()->create(['user_id' => $autreUser->id, 'ville_id' => $autreVille->id]);
        $piece = PieceJointe::factory()->create(['candidat_id' => $autreCandidat->id]);

        $response = $this->actingAs($this->candidatUser)
            ->deleteJson("/api/candidat/pieces-jointes/{$piece->id}");

        $response->assertStatus(404);
    }
}
