namespace Halo.Api.Endpoints;
// Was über die Leitung geht. Bewusst eigene Typen und nicht die der Domäne:
// sonst wandert jede Umbenennung im Datenmodell ungefragt in die Schnittstelle
// und bricht Clients, die niemand mehr aktualisiert.
public sealed record SystemInfo(string Version, bool NeedsSetup);
public sealed record SetupRequest(string UserName, string Password);
public sealed record LoginRequest(string UserName, string Password, string DeviceName, string DeviceId);
public sealed record AuthenticatedUser(Guid Id, string UserName, bool IsAdministrator);
public sealed record LoginResponse(string Token, AuthenticatedUser User);
public sealed record CodeRequest(string DeviceName, string DeviceId);
/// Was der Fernseher nach dem Anfordern bekommt.
///
///
/// Der Handle ist das Geheimnis und wird nicht angezeigt — der
/// Code ist das, was auf dem Bildschirm steht.
///
public sealed record CodeResponse(string Code, string Handle, DateTimeOffset ExpiresAt);
public sealed record CodeState(string State, LoginResponse? Login);
public sealed record CreateUserRequest(string UserName, string Password, bool IsAdministrator);
public sealed record LibraryResponse(Guid Id, string Name, string Kind, string Path);
public sealed record CreateLibraryRequest(string Name, string Kind, string Path);
// --- Stufe 2: Bibliothek -------------------------------------------------
public sealed record ScanProblem(string Path, string Reason);
public sealed record ScanStatus(
string State,
DateTimeOffset? StartedAt,
DateTimeOffset? FinishedAt,
int? FilesFound,
int? Added,
int? Updated,
int? Removed,
int? Unrecognised,
int? Probed,
IReadOnlyList? Problems,
string? Error,
MetadataProgress? Metadata);
/// Was das Nachschlagen bei der Metadatenquelle ergeben hat.
public sealed record MetadataProgress(
int MoviesMatched, int SeriesMatched, int EpisodesMatched, bool Skipped, string? Error);
/// Eine Spur in einer Datei.
public sealed record MediaStreamResponse(
int Index, string Kind, string? Codec, string? Language, string? Title,
bool IsDefault, bool IsForced, int? Channels, int? Width, int? Height);
/// Eine Datei hinter einem Titel — eine Fassung also.
///
///
/// Nur der Dateiname, nicht der Pfad. Der Pfad verriete jedem
/// Angemeldeten den Aufbau des Servers, und gebraucht wird er nirgends: die
/// App spricht Dateien über ihre Kennung an. Zum Unterscheiden zweier
/// Fassungen genügt der Name.
///
public sealed record MediaFileResponse(
Guid Id, string FileName, long SizeBytes, string? Container, double? DurationSeconds,
IReadOnlyList Streams);
public sealed record MovieResponse(
Guid Id, string Title, int? Year, string? Overview,
string? PosterImage, string? BackdropImage,
IReadOnlyList Files);
public sealed record SeriesResponse(
Guid Id, string Title, int? Year, string? Overview,
string? PosterImage, string? BackdropImage,
int EpisodeCount, IReadOnlyList Seasons);
public sealed record EpisodeResponse(
Guid Id, int Season, int Episode, string? Title, string? Overview, string? StillImage,
IReadOnlyList Files);
public sealed record Page(IReadOnlyList Items, int Total);
public sealed record MetadataSettingsResponse(bool HasApiKey, string Language);
public sealed record MetadataSettingsRequest(string? ApiKey, string? Language);
// --- Stufe 3: Ausliefern -------------------------------------------------
/// Was mit einer Datei geschehen wird, bevor sie hinausgeht.
///
///
/// Damit vorher feststeht, was man bekommt. Drei Gigabyte
/// herunterzuladen und erst danach zu merken, dass die Untertitel fehlen oder
/// die falsche Tonspur drin ist, war der Anlass für dieses ganze Projekt.
///
public sealed record DeliveryInfo(
string Method,
IReadOnlyList Reasons,
IReadOnlyList AudioToEncode,
IReadOnlyList SubtitlesDropped,
string PackageState,
double Progress,
string? Error);