<?php
namespace Tests\Unit\Services;

use App\Models\Client;
use App\Models\Ville;
use App\Models\Besoin;
use App\Services\BesoinService;
use App\Services\ReferenceGeneratorService;
use App\Services\StatusLogService;
use App\Services\NotificationService;
use App\Enums\StatutBesoin;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class BesoinServiceTest extends TestCase
{
    use RefreshDatabase;

    private BesoinService $service;

    protected function setUp(): void
    {
        parent::setUp();
        $this->service = new BesoinService(
            new ReferenceGeneratorService(),
            new StatusLogService(),
            new NotificationService()
        );
    }

    public function test_creation_besoin_genere_reference(): void
    {
        $ville = Ville::factory()->active()->create();
        $user = \App\Models\User::factory()->create(['role' => 'client']);
        $client = Client::factory()->create(['user_id' => $user->id, 'ville_id' => $ville->id]);

        $besoin = $this->service->creerBesoin($client, [
            'type_service' => 'menage_residente',
            'type_situation' => 'residente',
            'frequence' => 'hebdomadaire',
            'taches_details' => 'Test',
            'salaire_propose' => 50000,
            'quartier_id' => \App\Models\Quartier::factory()->create(['ville_id' => $ville->id])->id,
            'ville_id' => $ville->id,
            'telephone_contact' => '+237 699 000 000',
        ]);

        $this->assertMatchesRegularExpression('/^BSN-\d{4}-\d{4}$/', $besoin->reference);
    }

    public function test_statut_initial_est_recu(): void
    {
        $ville = Ville::factory()->active()->create();
        $user = \App\Models\User::factory()->create(['role' => 'client']);
        $client = Client::factory()->create(['user_id' => $user->id, 'ville_id' => $ville->id]);

        $besoin = $this->service->creerBesoin($client, [
            'type_service' => 'menage_residente',
            'type_situation' => 'residente',
            'frequence' => 'hebdomadaire',
            'taches_details' => 'Test',
            'salaire_propose' => 50000,
            'quartier_id' => \App\Models\Quartier::factory()->create(['ville_id' => $ville->id])->id,
            'ville_id' => $ville->id,
            'telephone_contact' => '+237 699 000 000',
        ]);

        $this->assertEquals(StatutBesoin::RECU->value, $besoin->statut->value);
    }

    public function test_annulation_possible_depuis_statut_recu(): void
    {
        $ville = Ville::factory()->active()->create();
        $user = \App\Models\User::factory()->create(['role' => 'client']);
        $client = Client::factory()->create(['user_id' => $user->id, 'ville_id' => $ville->id]);
        $besoin = Besoin::factory()->recu()->create(['client_id' => $client->id, 'ville_id' => $ville->id]);

        $this->assertTrue($besoin->peutEtreAnnuleParClient());
    }

    public function test_annulation_possible_depuis_statut_en_etude(): void
    {
        $ville = Ville::factory()->active()->create();
        $user = \App\Models\User::factory()->create(['role' => 'client']);
        $client = Client::factory()->create(['user_id' => $user->id, 'ville_id' => $ville->id]);
        $besoin = Besoin::factory()->enEtude()->create(['client_id' => $client->id, 'ville_id' => $ville->id]);

        $this->assertTrue($besoin->peutEtreAnnuleParClient());
    }

    public function test_annulation_impossible_depuis_statut_mission_en_cours(): void
    {
        $ville = Ville::factory()->active()->create();
        $user = \App\Models\User::factory()->create(['role' => 'client']);
        $client = Client::factory()->create(['user_id' => $user->id, 'ville_id' => $ville->id]);
        $besoin = Besoin::factory()->enMission()->create(['client_id' => $client->id, 'ville_id' => $ville->id]);

        $this->assertFalse($besoin->peutEtreAnnuleParClient());
    }

    public function test_transition_invalide_leve_exception(): void
    {
        $ville = Ville::factory()->active()->create();
        $user = \App\Models\User::factory()->create(['role' => 'client']);
        $client = Client::factory()->create(['user_id' => $user->id, 'ville_id' => $ville->id]);
        $besoin = Besoin::factory()->enMission()->create(['client_id' => $client->id, 'ville_id' => $ville->id]);

        $this->expectException(\App\Exceptions\TransitionStatutInvalideException::class);
        
        $this->service->annulerBesoin($client, $besoin->reference);
    }
}
