import 'package:pshared/models/describable.dart';
import 'package:pshared/models/organization/bound.dart';
import 'package:pshared/models/permissions/bound/describable.dart';
import 'package:pshared/models/permissions/bound.dart';
import 'package:pshared/models/recipient/status.dart';
import 'package:pshared/models/recipient/type.dart';
import 'package:pshared/models/storable.dart';


class Recipient implements PermissionBoundStorableDescribable {
  final Storable storable;
  final PermissionBound permissionBound;
  final Describable describable;
  final String email;
  final String? avatarUrl;
  final RecipientStatus status;
  final RecipientType type;
  final bool isArchived;

  const Recipient({
    required this.storable,
    required this.permissionBound,
    required this.describable,
    required this.email,
    required this.status,
    required this.type,
    this.avatarUrl,
    this.isArchived = false,
  });

  @override
  String get id => storable.id;
  @override
  DateTime get createdAt => storable.createdAt;
  @override
  DateTime get updatedAt => storable.updatedAt;

  @override
  String get organizationRef => permissionBound.organizationRef;
  @override
  String get permissionRef => permissionBound.permissionRef;

  @override
  String get name => describable.name;
  @override
  String? get description => describable.description;

  Recipient copyWith({
    Describable? describable,
    String? email,
    String? Function()? avatarUrl,
    RecipientStatus? status,
    RecipientType? type,
    bool? isArchived,
  }) => Recipient(
    storable: storable,
    permissionBound: permissionBound,
    describable: describableCopyWithOther(this.describable, describable),
    email: email ?? this.email,
    avatarUrl: avatarUrl != null ? avatarUrl() : this.avatarUrl,
    status: status ?? this.status,
    type: type ?? this.type,
    isArchived: isArchived ?? this.isArchived,
  );

  // TODO: move search to backend
  bool matchesQuery(String q) {
    final searchable = [
      name,
      email,
    ];

    return searchable.any((field) => field.toLowerCase().contains(q.toLowerCase()));
  }

}

Recipient newRecipient({
  required String organizationRef,
  required String email,
  required String name, 
  required RecipientStatus status,
  required RecipientType type,
  String? description,
  String? avatarUrl,
  bool isArchived = false,
}) => Recipient(
  storable: newStorable(),
  permissionBound: newPermissionBound(organizationBound: newOrganizationBound(organizationRef: organizationRef)),
  describable: newDescribable(name: name, description: description),
  email: email,
  status: status,
  type: type,
  avatarUrl: avatarUrl,
  isArchived: isArchived,
);