import '../../core/contracts/library.dart';
import '../utils/url_utils.dart';

class EmbyImageUrl {
  static final RegExp _typedUlidPattern = RegExp(
    r'^[a-z][0-9A-HJKMNP-TV-Z]{26}$',
  );


  static String? primary({
    required String baseUrl,
    required String token,
    required EmbyRawItem item,
    int? maxWidth,
    int? maxHeight,
    int? quality,
    String format = 'webp',
  }) {
    final tag = item.PrimaryImageTag ?? item.ImageTags?['Primary'];
    if (tag == null) return null;
    return _build(
      baseUrl: baseUrl,
      itemId: item.Id,
      type: 'Primary',
      tag: tag,
      token: token,
      maxWidth: maxWidth,
      maxHeight: maxHeight,
      quality: quality,
      format: format,
    );
  }


  static String? library({
    required String baseUrl,
    required String token,
    required EmbyRawLibrary lib,
    int? maxHeight,
    int? quality,
  }) {
    final tag = lib.ImageTags?['Primary'];
    if (tag == null) return null;
    return _build(
      baseUrl: baseUrl,
      itemId: lib.Id,
      type: 'Primary',
      tag: tag,
      token: token,
      maxHeight: maxHeight,
      quality: quality,
    );
  }


  static String? backdrop({
    required String baseUrl,
    required String token,
    required EmbyRawItem item,
    int? maxWidth,
    int? quality,
  }) {
    final tags = item.BackdropImageTags ?? const [];
    if (tags.isEmpty) return null;
    return _build(
      baseUrl: baseUrl,
      itemId: item.Id,
      type: 'Backdrop',
      tag: tags.first,
      token: token,
      maxWidth: maxWidth,
      quality: quality,
    );
  }

  static String detailBanner({
    required String baseUrl,
    required String token,
    required EmbyRawItem item,
  }) {
    final artworkItemId = (item.SeriesId?.isNotEmpty ?? false)
        ? item.SeriesId!
        : item.Id;
    return backdrop(
          baseUrl: baseUrl,
          token: token,
          item: item,
          maxWidth: 1600,
          quality: 90,
        ) ??
        fanart(baseUrl: baseUrl, token: token, itemId: artworkItemId);
  }


  static String fanart({
    required String baseUrl,
    required String token,
    required String itemId,
  }) {
    return _buildDirectImage(
      baseUrl: baseUrl,
      itemId: itemId,
      imageKind: 'fanart',
      extension: 'jpg',
      token: token,
    );
  }

  static String? logo({
    required String baseUrl,
    required String token,
    required String itemId,
    String? tag,
  }) {
    if (tag != null) {
      return _build(
        baseUrl: baseUrl,
        itemId: itemId,
        type: 'Logo',
        tag: tag,
        token: token,
      );
    }
    final base = stripTrailingSlash(baseUrl);
    return '$base/Items/$itemId/Images/Logo?api_key=$token';
  }


  static String? thumb({
    required String baseUrl,
    required String token,
    required EmbyRawItem item,
    int? maxWidth,
    int? quality,
  }) {
    final tag = item.ImageTags?['Thumb'];
    if (tag != null) {
      return _build(
        baseUrl: baseUrl,
        itemId: item.Id,
        type: 'Thumb',
        tag: tag,
        token: token,
        maxWidth: maxWidth,
        quality: quality,
      );
    }
    return primary(
      baseUrl: baseUrl,
      token: token,
      item: item,
      quality: quality,
    );
  }


  static String primaryById({
    required String baseUrl,
    required String token,
    required String itemId,
    int? maxHeight,
    int? quality,
  }) {
    final base = stripTrailingSlash(baseUrl);
    final params = <String, String>{
      'api_key': token,
      if (maxHeight != null) 'maxHeight': '$maxHeight',
      'quality': '${quality ?? 90}',
      'format': 'webp',
    };
    final query = params.entries.map((e) => '${e.key}=${e.value}').join('&');
    return '$base/Items/$itemId/Images/Primary?$query';
  }


  static String? season({
    required String baseUrl,
    required String token,
    required EmbyRawSeason season,
    int? maxHeight,
    int? quality,
  }) {
    final tag = season.PrimaryImageTag ?? season.ImageTags?['Primary'];
    if (tag == null) return null;
    return _build(
      baseUrl: baseUrl,
      itemId: season.Id,
      type: 'Primary',
      tag: tag,
      token: token,
      maxHeight: maxHeight,
      quality: quality,
    );
  }


  static String? landscapeCard({
    required String baseUrl,
    required String token,
    required EmbyRawItem item,
    int? maxWidth,
    int? quality,
  }) {
    String? pick(String? itemId, String type, String? tag) =>
        (itemId == null || tag == null)
        ? null
        : _build(
            baseUrl: baseUrl,
            itemId: itemId,
            type: type,
            tag: tag,
            token: token,
            maxWidth: maxWidth,
            quality: quality,
          );
    String? self(String type, String? tag) => pick(item.Id, type, tag);

    final primary = item.PrimaryImageTag ?? item.ImageTags?['Primary'];
    final thumb = item.ImageTags?['Thumb'];
    final backdropTags = item.BackdropImageTags ?? const <String>[];
    final backdrop = backdropTags.isEmpty ? null : backdropTags.first;

    if (item.Type == 'Movie') {
      return self('Backdrop', backdrop) ??
          self('Thumb', thumb) ??
          self('Primary', primary) ??
          _build(
            baseUrl: baseUrl,
            itemId: item.Id,
            type: 'Primary',
            tag: null,
            token: token,
            maxWidth: maxWidth,
            quality: quality,
          );
    }

    final extra = item.extra;
    final parentBackdropTags = extra['ParentBackdropImageTags'];
    return self('Primary', primary) ??
        self('Thumb', thumb) ??
        self('Backdrop', backdrop) ??
        pick(
          extra['ParentThumbItemId'] as String?,
          'Thumb',
          extra['ParentThumbImageTag'] as String?,
        ) ??
        pick(
          extra['ParentBackdropItemId'] as String?,
          'Backdrop',
          parentBackdropTags is List && parentBackdropTags.isNotEmpty
              ? parentBackdropTags.first as String
              : null,
        ) ??
        pick(
          extra['SeriesId'] as String?,
          'Primary',
          extra['SeriesPrimaryImageTag'] as String?,
        );
  }


  static int targetPixelWidth(
    double logicalWidth,
    double devicePixelRatio, {
    double maxScale = 3.0,
  }) {
    final scale = devicePixelRatio.clamp(1.0, maxScale);
    return (logicalWidth * scale).ceil();
  }


  static String _build({
    required String baseUrl,
    required String itemId,
    required String type,
    required String? tag,
    required String token,
    int? maxWidth,
    int? maxHeight,
    int? quality,
    String format = 'webp',
  }) {
    final base = stripTrailingSlash(baseUrl);
    final params = <String, String>{
      if (tag != null) 'tag': tag,
      'api_key': token,
      if (maxWidth != null) 'maxWidth': '$maxWidth',
      if (maxHeight != null) 'maxHeight': '$maxHeight',
      'quality': '${quality ?? 90}',
      'format': format,
    };
    final query = params.entries.map((e) => '${e.key}=${e.value}').join('&');
    return '$base/Items/$itemId/Images/$type?$query';
  }

  static String _buildDirectImage({
    required String baseUrl,
    required String itemId,
    required String imageKind,
    required String extension,
    required String token,
  }) {
    final uri = Uri.parse(baseUrl);
    final origin =
        '${uri.scheme}://${uri.host}${uri.hasPort ? ':${uri.port}' : ''}';
    final id = Uri.encodeComponent(_directImageId(itemId));
    final key = Uri.encodeQueryComponent(token);
    return '$origin/img/i/$imageKind/$id.$extension?api_key=$key';
  }

  static String _directImageId(String itemId) {
    if (_typedUlidPattern.hasMatch(itemId)) {
      return itemId.substring(1);
    }
    return itemId;
  }
}
