import 'package:jiffy/jiffy.dart';
import 'package:json_annotation/json_annotation.dart';

import '../../../../../view/pages/files/files.dart';
import '../../../../apiResponse.dart';
import 'cacheableFile.dart';

part 'listFilesResponse.g.dart';

@JsonSerializable(explicitToJson: true)
class ListFilesResponse extends ApiResponse {
    Set<CacheableFile> files;

    ListFilesResponse(this.files);

    factory ListFilesResponse.fromJson(Map<String, dynamic> json) => _$ListFilesResponseFromJson(json);
    Map<String, dynamic> toJson() => _$ListFilesResponseToJson(this);

    List<CacheableFile> sortBy({bool foldersToTop = true, SortOption sortOption = SortOption.name, bool reversed = false}) {
        var list = List<CacheableFile>.empty(growable: true);

        if(foldersToTop) {
            list.addAll(_sort(files.where((element) => element.isDirectory).toSet(), reversed: reversed, sortOption: sortOption));
            list.addAll(_sort(files.where((element) => !element.isDirectory).toSet(), reversed: reversed, sortOption: sortOption));
        } else {
            list.addAll(_sort(files, reversed: reversed, sortOption: sortOption));
        }

        return list;
    }

    List<CacheableFile> _sort(Set<CacheableFile> files, {SortOption sortOption = SortOption.name, bool reversed = false}) {
        for (var file in files) {
            final buffer = StringBuffer();

            switch(sortOption) {
                case SortOption.date:
                    buffer.write(Jiffy.parseFromMillisecondsSinceEpoch(file.modifiedAt?.millisecondsSinceEpoch ?? 0).format(pattern: 'yyyyMMddhhmmss'));
                    break;

                case SortOption.name:
                    buffer.write(file.name.toLowerCase());
                    break;

                case SortOption.size:
                    buffer.write(file.size);
                    break;
            }

            file.sort = buffer.toString();
        }


        var list = files.toList()..sort((a, b) => b.sort!.compareTo(a.sort!));
        return reversed ? list.reversed.toList() : list;
    }
}
