import 'dart:convert';
import 'dart:io';

class HashEntry {
  const HashEntry({
    required this.cardId,
    required this.hash,
    this.filename,
  });

  final String cardId;
  final String hash;
  final String? filename;

  /// Flutter asset path for the gallery image.
  String? get assetPath =>
      filename == null ? null : 'test_assets/$filename';
}

class HashLibrary {
  const HashLibrary({
    required this.version,
    required this.algorithm,
    required this.hashBits,
    required this.items,
  });

  final String version;
  final String algorithm;
  final int hashBits;
  final List<HashEntry> items;

  static HashLibrary fromJson(Map<String, dynamic> json) {
    final rawItems = (json['items'] as List<dynamic>? ?? const []);
    return HashLibrary(
      version: json['version'] as String? ?? 'assets-v1',
      algorithm: json['algorithm'] as String? ?? 'rgb-phash-v1',
      hashBits: json['hash_bits'] as int? ?? 105,
      items: rawItems
          .map((e) {
            final m = e as Map<String, dynamic>;
            return HashEntry(
              cardId: m['card_id'] as String,
              hash: m['hash'] as String,
              filename: m['filename'] as String?,
            );
          })
          .toList(growable: false),
    );
  }

  Map<String, dynamic> toJson() => {
        'version': version,
        'algorithm': algorithm,
        'hash_bits': hashBits,
        'card_count': items.length,
        'items': items
            .map(
              (e) => {
                'card_id': e.cardId,
                'hash': e.hash,
                if (e.filename != null) 'filename': e.filename,
              },
            )
            .toList(growable: false),
      };

  /// Load from filesystem (CLI scripts / tests).
  static Future<HashLibrary> loadFile(String path) async {
    final text = await File(path).readAsString();
    return fromJson(jsonDecode(text) as Map<String, dynamic>);
  }

  Future<void> saveFile(String path) async {
    final file = File(path);
    await file.parent.create(recursive: true);
    const encoder = JsonEncoder.withIndent('  ');
    await file.writeAsString('${encoder.convert(toJson())}\n');
  }
}
