<?php
namespace App\Services;

use App\Models\Besoin;
use App\Models\Client;
use App\Enums\StatutBesoin;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\ModelNotFoundException;

class BesoinService
{
    public function __construct(
        private readonly ReferenceGeneratorService $referenceGenerator,
        private readonly StatusLogService $statusLogService,
        private readonly NotificationService $notificationService
    ) {}

    public function creerBesoin(Client $client, array $data): Besoin
    {
        $data['client_id'] = $client->id;
        $data['reference'] = $this->referenceGenerator->besoin();
        $data['statut'] = StatutBesoin::RECU->value;

        $besoin = Besoin::create($data);
        
        $this->statusLogService->log($besoin, StatutBesoin::RECU->value, 'Création du besoin');
        
        $this->notificationService->notifierBesoinRecu($client->user, $besoin);

        return $besoin;
    }

    public function listerBesoinsClient(Client $client, ?string $statut = null): LengthAwarePaginator
    {
        $query = Besoin::query()
            ->duClient($client->id)
            ->with(['ville', 'quartier'])
            ->orderBy('created_at', 'DESC');

        if ($statut) {
            $query->avecStatut($statut);
        }

        return $query->paginate(15);
    }

    public function getBesoinDuClient(Client $client, string $reference): Besoin
    {
        return Besoin::where('reference', $reference)
            ->duClient($client->id)
            ->with(['ville', 'quartier', 'mission'])
            ->firstOrFail();
    }

    public function annulerBesoin(Client $client, string $reference): Besoin
    {
        $besoin = $this->getBesoinDuClient($client, $reference);

        if (!$besoin->peutEtreAnnuleParClient()) {
            throw new \App\Exceptions\TransitionStatutInvalideException(
                "Ce besoin ne peut pas être annulé car son statut est : {$besoin->statut->value}"
            );
        }

        $ancienStatut = $besoin->statut;
        $besoin->update(['statut' => StatutBesoin::ANNULEE->value]);
        
        $this->statusLogService->log($besoin, StatutBesoin::ANNULEE->value, 'Annulation par le client');

        return $besoin->fresh();
    }
}
