import 'package:aves/model/covers.dart';
import 'package:aves/model/filters/container/album_group.dart';
import 'package:aves/model/filters/covered/covered.dart';
import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/vaults/vaults.dart';
import 'package:aves/services/common/services.dart';
import 'package:aves/theme/colors.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/widgets/common/identity/aves_icons.dart';
import 'package:aves_model/aves_model.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';

class StoredAlbumFilter extends CollectionFilter with CoveredFilter, AlbumBaseFilter {
  static const type = 'album';

  final String album;
  final String? displayName;
  late final EntryPredicate _test;

  // ✅ Canonical key = basename (ultimo segmento del path)
  // Serve per:
  // - unire locale+remoto nello stesso album
  // - deduplicare filtri (pinned/hidden/covers) in modo coerente
  late final String _canonicalKey;

  // do not include contextual `displayName` to `props`
  @override
  List<Object?> get props => [_canonicalKey, reversed];

  StoredAlbumFilter(this.album, this.displayName, {super.reversed = false}) {
    _canonicalKey = _albumKey(album);

    // ✅ Match by basename: locale e remoto con stesso nome cartella finiscono nello stesso album
    _test = (entry) {
      final dir = entry.directory;
      if (dir == null || dir.isEmpty) return false;
      return _albumKey(dir) == _canonicalKey;
    };
  }

  /// Extract album key from a directory path (local or remote).
  /// - "/storage/.../DCIM/Trip" -> "Trip"
  /// - "/photos/Fabio/original/Trip" -> "Trip"
  String _albumKey(String path) {
    final normalized = path.replaceAll('\\', '/');
    final parts = pContext.split(normalized).where((s) => s.isNotEmpty).toList();
    return parts.isEmpty ? normalized : parts.last;
  }

  factory StoredAlbumFilter.fromMap(Map<String, dynamic> json) {
    return StoredAlbumFilter(
      json['album'],
      json['uniqueName'],
      reversed: json['reversed'] ?? false,
    );
  }

  @override
  Map<String, dynamic> toMap() => {
        'type': type,
        'album': album,
        'uniqueName': displayName,
        'reversed': reversed,
      };

  @override
  EntryPredicate get positiveTest => _test;

  @override
  bool get exclusiveProp => true;

  @override
  String get universalLabel => displayName ?? _canonicalKey;

  // ✅ Tooltip: niente path completo del server, resta leggibile
  @override
  String getTooltip(BuildContext context) => isVault ? super.getTooltip(context) : (displayName ?? _canonicalKey);

  @override
  Widget? iconBuilder(BuildContext context, double size, {bool allowGenericIcon = true}) {
    return IconUtils.getAlbumIcon(
          context: context,
          albumPath: album,
          size: size,
        ) ??
        (allowGenericIcon ? Icon(AIcons.album, size: size) : null);
  }

  @override
  Future<Color> color(BuildContext context) {
    // custom color has precedence over others, even custom app color
    final customColor = covers.of(this)?.$3;
    if (customColor != null) return SynchronousFuture(customColor);

    final colors = context.read<AvesColorsData>();
    // do not use async/await and rely on `SynchronousFuture`
    // to prevent rebuilding of the `FutureBuilder` listening on this future
    final albumType = covers.effectiveAlbumType(album);
    switch (albumType) {
      case AlbumType.regular:
      case AlbumType.vault:
        break;
      case AlbumType.app:
        final appColor = colors.appColor(album);
        if (appColor != null) return appColor;
      case AlbumType.camera:
        return SynchronousFuture(colors.albumCamera);
      case AlbumType.download:
        return SynchronousFuture(colors.albumDownload);
      case AlbumType.screenRecordings:
        return SynchronousFuture(colors.albumScreenRecordings);
      case AlbumType.screenshots:
        return SynchronousFuture(colors.albumScreenshots);
      case AlbumType.videoCaptures:
        return SynchronousFuture(colors.albumVideoCaptures);
    }
    return super.color(context);
  }

  @override
  String get category => type;

  // key is expected by test driver
  // ✅ anche questa deve essere canonica, altrimenti duplicati/instabilità in UI
  @override
  String get key => '$type-$reversed-$_canonicalKey';

  StorageVolume? get storageVolume => androidFileUtils.getStorageVolume(album);

  bool get canRename {
    if (isVault) return true;

    // do not allow renaming volume root
    final dir = androidFileUtils.relativeDirectoryFromPath(album);
    return dir != null && dir.relativeDir.isNotEmpty;
  }

  bool get isVault => vaults.isVault(album);
}
