using OmsorgCore.Domain.Entities;

namespace OmsorgCore.Application.Services;

public interface ITimeEntryService
{
    Task<(IReadOnlyList<TimeEntry> Items, int TotalCount)> GetPagedAsync(
        Guid? statusId,
        Guid? employeeId,
        Guid? orderId,
        int page,
        int pageSize,
        CancellationToken cancellationToken = default);
    Task<TimeEntry?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);

    /// <summary>
    /// Legt die Zeiterfassung an. Ist der aktuelle Nutzer nur mit Own-Scope berechtigt, wird
    /// <paramref name="timeEntry"/>.EmployeeId ignoriert und serverseitig auf die eigene, per JWT
    /// verknüpfte Mitarbeiter-Id gesetzt (analog AbsenceService.CreateAsync). StatusId wird immer
    /// serverseitig auf den initialen Status ("Entwurf") gesetzt. Gibt null zurück, wenn Own-Scope
    /// greift, aber kein Mitarbeiter verknüpft ist (fail-closed).
    /// </summary>
    Task<TimeEntry?> CreateAsync(TimeEntry timeEntry, CancellationToken cancellationToken = default);

    /// <summary>
    /// Bearbeitet Auftrag/Datum/Zeiten/Zuschlagsstunden - nur solange der aktuelle Status
    /// <see cref="ValueListItem.IsEditableByOwner"/> ist. Own-Scope-Aufrufer dürfen nur eigene
    /// Einträge bearbeiten (wie bei GetByIdAsync).
    /// </summary>
    Task<UpdateTimeEntryResult> UpdateAsync(Guid id, TimeEntry updates, CancellationToken cancellationToken = default);

    /// <summary>
    /// Löst die einzige Selbst-Einreichungs-Kante (RequiresApproval=false) ab dem aktuellen Status
    /// aus (Entwurf/Rückfrage -&gt; Eingereicht). Kein Body nötig.
    /// </summary>
    Task<SubmitTimeEntryResult> SubmitAsync(Guid id, CancellationToken cancellationToken = default);

    /// <summary>
    /// Büro-Entscheidung entlang der Statuspipeline (z. B. -&gt;Prüfung/-&gt;Rückfrage/-&gt;Freigegeben/-&gt;Abgerechnet).
    /// Validiert die Ziel-Transition über CanTransitionAsync und lehnt Kanten mit RequiresApproval=false ab
    /// (die gehören zu SubmitAsync, nicht hierher).
    /// </summary>
    Task<DecideTimeEntryResult> DecideAsync(Guid id, Guid statusId, string? adminNote, CancellationToken cancellationToken = default);

    Task<bool> DeleteAsync(Guid id, CancellationToken cancellationToken = default);
    Task<IReadOnlyList<TimeEntry>> GetDeletedAsync(string? search, CancellationToken cancellationToken = default);
    Task<bool> RestoreAsync(Guid id, CancellationToken cancellationToken = default);
}
