import 'package:flutter_test/flutter_test.dart';
import 'package:smplayer/core/contracts/library.dart';
import 'package:smplayer/shared/mappers/media_image_url.dart';

const _baseUrl = 'https://emby.example.com';
const _token = 'test-token';

EmbyRawItem _makeItem({
  String id = 'item-1',
  String? type,
  String? primaryImageTag,
  Map<String, String>? imageTags,
  List<String>? backdropImageTags,
  Map<String, dynamic> extra = const {},
}) {
  return EmbyRawItem(
    Id: id,
    Name: 'Test',
    Type: type,
    PrimaryImageTag: primaryImageTag,
    ImageTags: imageTags,
    BackdropImageTags: backdropImageTags,
    extra: extra,
  );
}

void main() {
  group('EmbyImageUrl.landscapeCard fallback chain', () {
    test('returns Primary when PrimaryImageTag is present', () {
      final item = _makeItem(primaryImageTag: 'primary-tag-1');

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, isNotNull);
      expect(url, contains('/Images/Primary'));
      expect(url, contains('tag=primary-tag-1'));
    });

    test('returns Primary from ImageTags map when PrimaryImageTag is null', () {
      final item = _makeItem(imageTags: {'Primary': 'map-primary-tag'});

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, isNotNull);
      expect(url, contains('/Images/Primary'));
      expect(url, contains('tag=map-primary-tag'));
    });

    test('falls back to Thumb when Primary is missing', () {
      final item = _makeItem(imageTags: {'Thumb': 'thumb-tag-1'});

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, isNotNull);
      expect(url, contains('/Images/Thumb'));
      expect(url, contains('tag=thumb-tag-1'));
    });

    test('falls back to Backdrop when Primary and Thumb are missing', () {
      final item = _makeItem(backdropImageTags: ['backdrop-tag-1']);

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, isNotNull);
      expect(url, contains('/Images/Backdrop'));
      expect(url, contains('tag=backdrop-tag-1'));
    });

    test('falls back to parent Thumb from extra JSON', () {
      final item = _makeItem(
        extra: {
          'ParentThumbItemId': 'parent-1',
          'ParentThumbImageTag': 'parent-thumb-tag',
        },
      );

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, isNotNull);
      expect(url, contains('/Items/parent-1/Images/Thumb'));
      expect(url, contains('tag=parent-thumb-tag'));
    });

    test('falls back to parent Backdrop from extra JSON', () {
      final item = _makeItem(
        extra: {
          'ParentBackdropItemId': 'parent-2',
          'ParentBackdropImageTags': ['parent-backdrop-tag'],
        },
      );

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, isNotNull);
      expect(url, contains('/Items/parent-2/Images/Backdrop'));
      expect(url, contains('tag=parent-backdrop-tag'));
    });

    test('falls back to series Primary from extra JSON as last resort', () {
      final item = _makeItem(
        extra: {
          'SeriesId': 'series-1',
          'SeriesPrimaryImageTag': 'series-primary-tag',
        },
      );

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, isNotNull);
      expect(url, contains('/Items/series-1/Images/Primary'));
      expect(url, contains('tag=series-primary-tag'));
    });

    test('returns null when all image sources are absent', () {
      final item = _makeItem();

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, isNull);
    });

    test('respects priority: Primary beats Thumb beats Backdrop', () {
      final item = _makeItem(
        primaryImageTag: 'primary-tag',
        imageTags: {'Primary': 'primary-tag', 'Thumb': 'thumb-tag'},
        backdropImageTags: ['backdrop-tag'],
      );

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, contains('/Images/Primary'));
      expect(url, contains('tag=primary-tag'));
    });

    test('parent Thumb takes priority over parent Backdrop', () {
      final item = _makeItem(
        extra: {
          'ParentThumbItemId': 'parent-1',
          'ParentThumbImageTag': 'parent-thumb-tag',
          'ParentBackdropItemId': 'parent-2',
          'ParentBackdropImageTags': ['parent-backdrop-tag'],
          'SeriesId': 'series-1',
          'SeriesPrimaryImageTag': 'series-primary-tag',
        },
      );

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, contains('/Items/parent-1/Images/Thumb'));
    });

    test('forwards maxWidth and quality parameters', () {
      final item = _makeItem(primaryImageTag: 'tag');

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
        maxWidth: 500,
        quality: 80,
      );

      expect(url, contains('maxWidth=500'));
      expect(url, contains('quality=80'));
    });
  });

  group('EmbyImageUrl.landscapeCard movie-specific ordering', () {
    test('movie prefers Backdrop over Primary', () {
      final item = _makeItem(
        type: 'Movie',
        primaryImageTag: 'poster-tag',
        backdropImageTags: ['backdrop-tag'],
      );

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, contains('/Images/Backdrop'));
      expect(url, contains('tag=backdrop-tag'));
    });

    test('movie falls back to Thumb when Backdrop is missing', () {
      final item = _makeItem(
        type: 'Movie',
        primaryImageTag: 'poster-tag',
        imageTags: {'Primary': 'poster-tag', 'Thumb': 'thumb-tag'},
      );

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, contains('/Images/Thumb'));
      expect(url, contains('tag=thumb-tag'));
    });

    test('movie falls back to Primary (poster) as last resort', () {
      final item = _makeItem(type: 'Movie', primaryImageTag: 'poster-tag');

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, contains('/Images/Primary'));
      expect(url, contains('tag=poster-tag'));
    });

    test('movie returns tagless Primary URL when all tag sources absent', () {
      final item = _makeItem(type: 'Movie');

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, isNotNull);
      expect(url, contains('/Items/item-1/Images/Primary'));
      expect(url, isNot(contains('tag=')));
    });

    test('episode still prefers Primary over Backdrop', () {
      final item = _makeItem(
        type: 'Episode',
        primaryImageTag: 'screenshot-tag',
        backdropImageTags: ['backdrop-tag'],
      );

      final url = EmbyImageUrl.landscapeCard(
        baseUrl: _baseUrl,
        token: _token,
        item: item,
      );

      expect(url, contains('/Images/Primary'));
      expect(url, contains('tag=screenshot-tag'));
    });
  });
}
