import 'package:pshared/models/organization/bound.dart';
import 'package:pshared/models/permissions/bound.dart';
import 'package:pshared/models/permissions/bound/storable.dart';
import 'package:pshared/models/storable.dart';
import 'package:pshared/models/invitation/status.dart';


class InvitationContent {
  final String email;
  final String name;
  final String lastName;
  final String comment;

  const InvitationContent({
    required this.email,
    required this.name,
    required this.lastName,
    required this.comment,
  });

  InvitationContent copyWith({
    String? email,
    String? name,
    String? lastName,
    String? comment,
  }) => InvitationContent(
    email: email ?? this.email,
    name: name ?? this.name,
    lastName: lastName ?? this.lastName,
    comment: comment ?? this.comment,
  );

  String get fullName {
    final trimmedName = name.trim();
    final trimmedLastName = lastName.trim();
    if (trimmedName.isEmpty && trimmedLastName.isEmpty) return '';
    if (trimmedName.isEmpty) return trimmedLastName;
    if (trimmedLastName.isEmpty) return trimmedName;
    return '$trimmedName $trimmedLastName';
  }
}

class Invitation implements PermissionBoundStorable {
  final Storable storable;
  final PermissionBound permissionBound;
  final String roleRef;
  final String inviterRef;
  final InvitationStatus status;
  final DateTime expiresAt;
  final InvitationContent content;
  final bool isArchived;

  Invitation({
    required this.storable,
    required this.permissionBound,
    required this.roleRef,
    required this.inviterRef,
    required this.status,
    required this.expiresAt,
    required this.content,
    this.isArchived = false,
  });

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

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

  String get inviteeDisplayName => content.fullName.isNotEmpty ? content.fullName : content.email;
  bool get isExpired => expiresAt.isBefore(DateTime.now().toUtc());
  bool get isPending => status == InvitationStatus.created || status == InvitationStatus.sent;

  Invitation copyWith({
    Storable? storable,
    PermissionBound? permissionBound,
    String? roleRef,
    String? inviterRef,
    InvitationStatus? status,
    DateTime? expiresAt,
    InvitationContent? content,
    bool? isArchived,
  }) => Invitation(
    storable: storable ?? this.storable,
    permissionBound: permissionBound ?? this.permissionBound,
    roleRef: roleRef ?? this.roleRef,
    inviterRef: inviterRef ?? this.inviterRef,
    status: status ?? this.status,
    expiresAt: expiresAt ?? this.expiresAt,
    content: content ?? this.content,
    isArchived: isArchived ?? this.isArchived,
  );
}

Invitation newInvitation({
  required String organizationRef,
  required String roleRef,
  required String inviterRef,
  required String email,
  String name = '',
  String lastName = '',
  String comment = '',
  InvitationStatus status = InvitationStatus.created,
  DateTime? expiresAt,
  bool isArchived = false,
  String? permissionRef,
}) => Invitation(
  storable: newStorable(),
  permissionBound: newPermissionBound(
    organizationBound: newOrganizationBound(organizationRef: organizationRef),
    permissionRef: permissionRef,
  ),
  roleRef: roleRef,
  inviterRef: inviterRef,
  status: status,
  expiresAt: expiresAt ?? DateTime.now().toUtc().add(const Duration(days: 7)),
  content: InvitationContent(email: email, name: name, lastName: lastName, comment: comment),
  isArchived: isArchived,
);
