using TrajetKmTracker.Api.Models.Entities;
namespace TrajetKmTracker.Api.Repositories;
///
/// Accès aux données des trajets et gestion des positions au sein d'une journée.
///
/// La est une valeur décimale (REAL) permettant l'insertion
/// sans réordonnancement systématique : ajout en fin de journée → max(Position) + 1.0,
/// insertion entre deux positions P₁ et P₂ → (P₁ + P₂) / 2. Lorsque l'écart devient
/// trop faible (< ), la journée est renumérotée par pas de
/// 1.0 en transaction en préservant l'ordre relatif (Property 15, Exigences 11.7/11.8).
///
///
/// Ce repository fournit uniquement les primitives d'accès et de calcul de position ;
/// la logique métier (validation, calcul de distance, mise en cache) relève de TrajetService.
///
///
public interface ITrajetRepository
{
///
/// Seuil de précision en deçà duquel une renumérotation de la journée est déclenchée.
/// Conforme à la conception : écart < 0.001.
///
const decimal SeuilRenumerotation = 0.001m;
/// Retourne le trajet par identifiant, ou null s'il n'existe pas.
Task GetByIdAsync(int id, CancellationToken cancellationToken = default);
/// Retourne les trajets d'une journée triés par croissante.
Task> GetByDateAsync(DateOnly date, CancellationToken cancellationToken = default);
///
/// Résout le véhicule applicable à la date du trajet et copie sa PuissanceFiscale
/// sur le trajet (dénormalisation, Exigence 10.14). Ne modifie ni VehiculeId ni
/// PuissanceFiscale si aucun véhicule n'est applicable à cette date.
/// Coordonné avec .
///
Task AppliquerVehiculeADateAsync(Trajet trajet, CancellationToken cancellationToken = default);
///
/// Calcule la position d'un trajet ajouté en fin de journée : max(Position) + 1.0
/// pour la date, ou 1.0 si la journée est vide.
///
Task CalculerPositionFinDeJourneeAsync(DateOnly date, CancellationToken cancellationToken = default);
///
/// Calcule la position d'un trajet inséré entre les positions
/// (P₁) et (P₂) : (P₁ + P₂) / 2.
///
/// Si P₁ n'est pas strictement inférieure à P₂.
decimal CalculerPositionEntre(decimal positionPrecedente, decimal positionSuivante);
///
/// Indique si l'écart entre deux positions adjacentes est devenu trop faible
/// (< ) pour insérer une nouvelle valeur intermédiaire.
///
bool NecessiteRenumerotation(decimal positionPrecedente, decimal positionSuivante);
/// Ajoute un trajet (sans persister). L'appelant gère la transaction et l'appel à .
Task AddAsync(Trajet trajet, CancellationToken cancellationToken = default);
/// Marque un trajet existant comme modifié (sans persister).
void Update(Trajet trajet);
/// Supprime un trajet (sans persister).
void Delete(Trajet trajet);
/// Persiste les changements en attente.
Task SauvegarderAsync(CancellationToken cancellationToken = default);
///
/// Applique un réordonnancement manuel : met à jour uniquement la
/// des trajets fournis (par identifiant) sans altérer leurs autres champs, en transaction.
/// Les identifiants inconnus sont ignorés.
///
Task ReordonnerAsync(
IReadOnlyList<(int Id, decimal Position)> positions,
CancellationToken cancellationToken = default);
///
/// Renumérote les trajets d'une journée par pas de 1.0 (1.0, 2.0, 3.0, …) en préservant
/// l'ordre relatif courant (tri par Position puis Id), en transaction. Retourne la liste
/// renumérotée triée par Position croissante (Property 15).
///
Task> RenumeroterJourneeAsync(DateOnly date, CancellationToken cancellationToken = default);
}