<?php
namespace Tests\Feature\Admin;

use App\Models\User;
use App\Models\Mission;
use App\Models\Besoin;
use App\Models\Candidat;
use App\Models\Client;
use App\Models\Ville;
use App\Enums\RolePrincipal;
use App\Enums\StatutCompteUser;
use App\Enums\StatutCandidat;
use App\Enums\StatutBesoin;
use App\Enums\StatutMission;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;

class MissionTest extends TestCase
{
    use RefreshDatabase;

    private User $adminUser;
    private Client $client;
    private Candidat $candidat;
    private Ville $ville;

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

        $this->adminUser = User::factory()->create([
            'role' => RolePrincipal::SUPER_ADMIN,
            'statut' => StatutCompteUser::ACTIF,
            'email_verified_at' => now(),
        ]);

        $this->ville = Ville::factory()->active()->create();

        $this->client = Client::factory()->create([
            'ville_id' => $this->ville->id,
        ]);

        $this->candidat = Candidat::factory()->create([
            'statut' => StatutCandidat::DISPONIBLE->value,
            'ville_id' => $this->ville->id,
        ]);
    }

    public function test_admin_peut_lister_missions(): void
    {
        Mission::factory()->count(5)->create();

        $response = $this->actingAs($this->adminUser)
            ->getJson('/api/admin/missions');

        $response->assertStatus(200)
            ->assertJsonCount(5, 'data');
    }

    public function test_admin_peut_creer_mission(): void
    {
        $besoin = Besoin::factory()->avecClient($this->client)->create([
            'statut' => StatutBesoin::CONTRAT_SIGNE->value,
        ]);

        $response = $this->actingAs($this->adminUser)
            ->postJson('/api/admin/missions', [
                'besoin_id' => $besoin->id,
                'candidat_id' => $this->candidat->id,
                'date_debut' => now()->addDay()->format('Y-m-d'),
                'date_fin_prevue' => now()->addMonth()->format('Y-m-d'),
                'salaire_mensuel' => 150000,
                'tarif_agence' => 30000,
                'frequence_paiement' => 'mensuel',
            ]);

        $response->assertStatus(201)
            ->assertJsonStructure([
                'reference',
                'type_service',
                'statut',
                'candidat',
                'client',
            ]);

        $this->assertDatabaseHas('missions', [
            'candidat_id' => $this->candidat->id,
            'statut' => StatutMission::ACTIVE->value,
        ]);

        $this->assertDatabaseHas('candidats', [
            'id' => $this->candidat->id,
            'statut' => StatutCandidat::EN_MISSION->value,
        ]);
    }

    public function test_admin_peut_voir_detail_mission(): void
    {
        $besoin = Besoin::factory()->avecClient($this->client)->create();
        $mission = Mission::factory()->create([
            'besoin_id' => $besoin->id,
            'client_id' => $this->client->id,
            'candidat_id' => $this->candidat->id,
        ]);

        $response = $this->actingAs($this->adminUser)
            ->getJson('/api/admin/missions/' . $mission->reference);

        $response->assertStatus(200)
            ->assertJsonStructure([
                'reference',
                'type_service',
                'statut',
                'candidat',
                'client',
                'besoin',
            ]);
    }

    public function test_admin_peut_changer_statut_mission(): void
    {
        $besoin = Besoin::factory()->avecClient($this->client)->create();
        $mission = Mission::factory()->create([
            'statut' => StatutMission::ACTIVE->value,
            'besoin_id' => $besoin->id,
            'client_id' => $this->client->id,
            'candidat_id' => $this->candidat->id,
        ]);

        $response = $this->actingAs($this->adminUser)
            ->postJson('/api/admin/missions/' . $mission->reference . '/statut', [
                'statut' => StatutMission::SUSPENDUE->value,
                'motif' => 'Absence prolongée',
            ]);

        $response->assertStatus(200);
        $this->assertDatabaseHas('missions', [
            'reference' => $mission->reference,
            'statut' => StatutMission::SUSPENDUE->value,
        ]);
    }

    // Commented out - depends on fully implemented destroy logic
    // public function test_admin_ne_peut_pas_supprimer_mission_active(): void
    // {
    //     $besoin = Besoin::factory()->avecClient($this->client)->create();
    //     $mission = Mission::factory()->create([
    //         'statut' => StatutMission::ACTIVE->value,
    //         'besoin_id' => $besoin->id,
    //         'client_id' => $this->client->id,
    //         'candidat_id' => $this->candidat->id,
    //     ]);

    //     $response = $this->actingAs($this->adminUser)
    //         ->deleteJson('/api/admin/missions/' . $mission->reference);

    //     $response->assertStatus(422);
    // }

    public function test_admin_peut_supprimer_mission_terminee(): void
    {
        $besoin = Besoin::factory()->avecClient($this->client)->create();
        $mission = Mission::factory()->create([
            'statut' => StatutMission::TERMINEE->value,
            'besoin_id' => $besoin->id,
            'client_id' => $this->client->id,
            'candidat_id' => $this->candidat->id,
        ]);

        $response = $this->actingAs($this->adminUser)
            ->deleteJson('/api/admin/missions/' . $mission->reference);

        $response->assertStatus(200);
        $this->assertSoftDeleted('missions', [
            'reference' => $mission->reference,
        ]);
    }

    // Commented out - depends on descente_terrains table which doesn't exist in Phase 4
    // public function test_admin_peut_voir_descentes_mission(): void
    // {
    //     $besoin = Besoin::factory()->avecClient($this->client)->create();
    //     $mission = Mission::factory()->create([
    //         'besoin_id' => $besoin->id,
    //         'client_id' => $this->client->id,
    //         'candidat_id' => $this->candidat->id,
    //     ]);

    //     $response = $this->actingAs($this->adminUser)
    //         ->getJson('/api/admin/missions/' . $mission->reference . '/descentes');

    //     $response->assertStatus(200);
    // }

    public function test_admin_peut_voir_signalements_mission(): void
    {
        $besoin = Besoin::factory()->avecClient($this->client)->create();
        $mission = Mission::factory()->create([
            'besoin_id' => $besoin->id,
            'client_id' => $this->client->id,
            'candidat_id' => $this->candidat->id,
        ]);

        $response = $this->actingAs($this->adminUser)
            ->getJson('/api/admin/missions/' . $mission->reference . '/signalements');

        $response->assertStatus(200);
    }

    public function test_non_admin_ne_peut_pas_acceder_missions(): void
    {
        $candidatUser = User::factory()->create([
            'role' => RolePrincipal::CANDIDAT,
            'statut' => StatutCompteUser::ACTIF,
            'email_verified_at' => now(),
        ]);

        $response = $this->actingAs($candidatUser)
            ->getJson('/api/admin/missions');

        $response->assertStatus(403);
    }
}
