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

part 'cacheable_file.g.dart';

@JsonSerializable(explicitToJson: true)
class CacheableFile {
  late String path;
  late bool isDirectory;
  late String name;
  String? mimeType;
  int? size;
  String? eTag;
  DateTime? createdAt;
  DateTime? modifiedAt;

  /// Nextcloud's instance-local file id (`oc:fileid`). Used to address the
  /// preview API by id, which is more reliable than the path-based variant
  /// on some server configurations.
  int? fileId;

  /// Server's answer to "can I render a thumbnail for this file?"
  /// (`nc:has-preview`). Lets the file viewer skip the placeholder text
  /// when a preview is going to load anyway.
  bool? hasPreview;

  /// True when this entry is an incoming share — i.e. shared with the current
  /// user by someone else (`nc:mount-type == 'shared'`). Used to badge the
  /// file/folder in the list. Nullable so older cached entries decode fine.
  bool? isSharedWithMe;

  CacheableFile({
    required this.path,
    required this.isDirectory,
    required this.name,
    this.mimeType,
    this.size,
    this.eTag,
    this.createdAt,
    this.modifiedAt,
    this.fileId,
    this.hasPreview,
    this.isSharedWithMe,
  });

  CacheableFile.fromDavFile(WebDavFile file) {
    path = file.path.path;
    isDirectory = file.isDirectory;
    name = file.isDirectory ? file.name : file.path.path.split('/').last;
    mimeType = file.mimeType;
    size = file.size;
    eTag = file.etag;
    createdAt = file.createdDate;
    modifiedAt = file.lastModified;
    fileId = int.tryParse(file.fileId ?? '');
    hasPreview = file.hasPreview;
    // Incoming share: the item is mounted into the user's files by someone
    // else. Outgoing shares ([isSharedByMe]) can't be derived from WebDAV with
    // the pinned package, so they are filled in by ListFiles via one OCS call
    // per folder.
    isSharedWithMe = file.props.ncmounttype == 'shared';
  }

  factory CacheableFile.fromJson(Map<String, dynamic> json) =>
      _$CacheableFileFromJson(json);
  Map<String, dynamic> toJson() => _$CacheableFileToJson(this);
}
