import '../../contracts/cancellation.dart';
import '../../contracts/library.dart';
import '../../contracts/playback.dart';
import '../../contracts/server.dart';


class AuthedRequestContext {
  final String baseUrl;
  final String token;
  final String userId;

  const AuthedRequestContext({
    required this.baseUrl,
    required this.token,
    required this.userId,
  });
}


class EmbyAuthResult {
  final String accessToken;
  final String userId;
  final String userName;

  const EmbyAuthResult({
    required this.accessToken,
    required this.userId,
    required this.userName,
  });
}


abstract class EmbyGateway {
  Future<ProbePublicInfoRes> probePublicInfo(String baseUrl);

  Future<EmbyAuthResult> authenticateByName({
    required String baseUrl,
    required String username,
    required String password,
  });

  Future<void> changePassword({
    required AuthedRequestContext ctx,
    required String currentPassword,
    required String newPassword,
  });

  Future<EmbyRawLibraries> getUserViews(AuthedRequestContext ctx);

  Future<LibraryLatestRes> getLatestItems(
    AuthedRequestContext ctx,
    String parentId, {
    int? limit,
    CancellationToken? cancelToken,
  });

  Future<LibraryResumeRes> getResumeItems(
    AuthedRequestContext ctx, {
    int? limit,
  });

  Future<List<EmbyRawItem>> getLibraryItems({
    required AuthedRequestContext ctx,
    String? parentId,
    String? includeItemTypes,
    List<String>? genreIds,
    String? searchTerm,
    String? anyProviderIdEquals,
    List<String>? personIds,
    String? fields,
    String? enableImageTypes,
    bool? groupProgramsBySeries,
    int? imageTypeLimit,
    int? startIndex,
    int? limit,
    bool? recursive,
    String? sortBy,
    SortOrder? sortOrder,
    String? filters,
    CancellationToken? cancelToken,
  });

  Future<List<EmbyRawItem>> getFavoriteItems({
    required AuthedRequestContext ctx,
    required String includeItemTypes,
    required String sortBy,
    SortOrder? sortOrder,
  });

  Future<ItemCountsRes> getItemCounts(AuthedRequestContext ctx);

  Future<EmbyRawItem> getItemDetail(AuthedRequestContext ctx, String itemId);

  Future<List<EmbyRawItem>> getSeriesNextUp(
    AuthedRequestContext ctx,
    String seriesId, {
    int? limit,
  });

  Future<List<EmbyRawSeason>> getSeriesSeasons(
    AuthedRequestContext ctx,
    String seriesId, {
    CancellationToken? cancelToken,
  });

  Future<List<EmbyRawItem>> getSeriesEpisodes(
    AuthedRequestContext ctx,
    String seriesId,
    String seasonId, {
    CancellationToken? cancelToken,
  });

  Future<List<EmbyRawItem>> getSimilarItems(
    AuthedRequestContext ctx,
    String itemId, {
    int? limit,
  });

  Future<List<EmbyRawItem>> getAdditionalParts(
    AuthedRequestContext ctx,
    String itemId,
  );

  Future<List<EmbyRawItem>> getSpecialFeatures(
    AuthedRequestContext ctx,
    String itemId,
  );

  Future<bool> setFavoriteStatus({
    required AuthedRequestContext ctx,
    required String itemId,
    required bool isFavorite,
  });

  Future<bool> setPlayedStatus({
    required AuthedRequestContext ctx,
    required String itemId,
    required bool played,
  });

  Future<bool> hideFromResume({
    required AuthedRequestContext ctx,
    required String itemId,
    required bool hide,
  });

  Future<void> reportPlaybackStarted({
    required AuthedRequestContext ctx,
    required PlaybackReportPayload payload,
  });

  Future<void> reportPlaybackProgress({
    required AuthedRequestContext ctx,
    required PlaybackReportPayload payload,
  });

  Future<void> reportPlaybackStopped({
    required AuthedRequestContext ctx,
    required PlaybackReportPayload payload,
  });


  Future<Map<String, dynamic>> fetchPlaybackInfo({
    required AuthedRequestContext ctx,
    required String itemId,
    String? mediaSourceId,
    int startTimeTicks = 0,
    bool isPlayback = false,
    required Map<String, dynamic> deviceProfile,
  });
}
