/**
 * Notification Entity
 *
 * Represents a notification sent to a user
 */

export enum NotificationType {
  BOOKING_CREATED = 'booking_created',
  BOOKING_UPDATED = 'booking_updated',
  BOOKING_CANCELLED = 'booking_cancelled',
  BOOKING_CONFIRMED = 'booking_confirmed',
  RATE_QUOTE_EXPIRING = 'rate_quote_expiring',
  DOCUMENT_UPLOADED = 'document_uploaded',
  SYSTEM_ANNOUNCEMENT = 'system_announcement',
  USER_INVITED = 'user_invited',
  ORGANIZATION_UPDATE = 'organization_update',
  // CSV Booking notifications
  CSV_BOOKING_ACCEPTED = 'csv_booking_accepted',
  CSV_BOOKING_REJECTED = 'csv_booking_rejected',
  CSV_BOOKING_REQUEST_SENT = 'csv_booking_request_sent',
}

export enum NotificationPriority {
  LOW = 'low',
  MEDIUM = 'medium',
  HIGH = 'high',
  URGENT = 'urgent',
}

interface NotificationProps {
  id: string;
  userId: string;
  organizationId: string;
  type: NotificationType;
  priority: NotificationPriority;
  title: string;
  message: string;
  metadata?: Record<string, any>;
  read: boolean;
  readAt?: Date;
  actionUrl?: string;
  createdAt: Date;
}

export class Notification {
  private constructor(private readonly props: NotificationProps) {}

  static create(
    props: Omit<NotificationProps, 'id' | 'read' | 'createdAt'> & { id: string }
  ): Notification {
    return new Notification({
      ...props,
      read: false,
      createdAt: new Date(),
    });
  }

  static fromPersistence(props: NotificationProps): Notification {
    return new Notification(props);
  }

  get id(): string {
    return this.props.id;
  }

  get userId(): string {
    return this.props.userId;
  }

  get organizationId(): string {
    return this.props.organizationId;
  }

  get type(): NotificationType {
    return this.props.type;
  }

  get priority(): NotificationPriority {
    return this.props.priority;
  }

  get title(): string {
    return this.props.title;
  }

  get message(): string {
    return this.props.message;
  }

  get metadata(): Record<string, any> | undefined {
    return this.props.metadata;
  }

  get read(): boolean {
    return this.props.read;
  }

  get readAt(): Date | undefined {
    return this.props.readAt;
  }

  get actionUrl(): string | undefined {
    return this.props.actionUrl;
  }

  get createdAt(): Date {
    return this.props.createdAt;
  }

  /**
   * Mark notification as read
   */
  markAsRead(): Notification {
    return new Notification({
      ...this.props,
      read: true,
      readAt: new Date(),
    });
  }

  /**
   * Check if notification is unread
   */
  isUnread(): boolean {
    return !this.props.read;
  }

  /**
   * Check if notification is high priority
   */
  isHighPriority(): boolean {
    return (
      this.props.priority === NotificationPriority.HIGH ||
      this.props.priority === NotificationPriority.URGENT
    );
  }

  /**
   * Convert to plain object
   */
  toObject(): NotificationProps {
    return { ...this.props };
  }
}
