/**
 * Messages store actions using `createActionGroup` for concise definitions.
 *
 * Action type strings follow the `[Messages] Event Name` convention and are
 * generated automatically by NgRx from the `source` and event key.
 */
import {
  createActionGroup,
  emptyProps,
  props
} from '@ngrx/store';
import {
  Message,
  Reaction,
  LinkMetadata
} from '../../shared-kernel';

export const MessagesActions = createActionGroup({
  source: 'Messages',
  events: {
    /** Triggers loading messages for the given room from the local database. */
    'Load Messages': props<{ roomId: string }>(),
    'Load Messages Success': props<{ messages: Message[] }>(),
    'Load Messages Failure': props<{ error: string }>(),

    /**
     * Background-prefetches the initial page of messages for a room without
     * touching the active-room `loading` flag. Fired for every saved room
     * after `loadRoomsSuccess` so subsequent room navigations resolve from
     * the in-memory cache instead of paying an IPC round-trip.
     */
    'Prefetch Room Messages': props<{ roomId: string }>(),
    'Prefetch Room Messages Success': props<{ messages: Message[] }>(),

    /**
     * Fetches a page of messages strictly older than `beforeTimestamp` for a
     * given conversation (room + channel). Used by the chat scroll-up handler
     * to backfill history from the local database on demand.
     */
    'Load Older Messages': props<{
      roomId: string;
      channelId: string;
      beforeTimestamp: number;
      limit: number;
    }>(),
    'Load Older Messages Success': props<{
      conversationKey: string;
      messages: Message[];
      reachedEnd: boolean;
    }>(),
    'Load Older Messages Failure': props<{ error: string }>(),

    /** Sends a new chat message to the current room and broadcasts to peers. */
    'Send Message': props<{ content: string; replyToId?: string; channelId?: string }>(),
    'Send Message Success': props<{ message: Message }>(),
    'Send Message Failure': props<{ error: string }>(),

    /** Applies a message received from a remote peer to the local store. */
    'Receive Message': props<{ message: Message }>(),

    'Edit Message': props<{ messageId: string; content: string }>(),
    'Edit Message Success': props<{ messageId: string; content: string; editedAt: number }>(),
    'Edit Message Failure': props<{ error: string }>(),

    'Delete Message': props<{ messageId: string }>(),
    'Delete Message Success': props<{ messageId: string }>(),
    'Delete Message Failure': props<{ error: string }>(),
    /** Soft-deletes a message by an admin (can delete any message). */
    'Admin Delete Message': props<{ messageId: string }>(),

    'Add Reaction': props<{ messageId: string; emoji: string }>(),
    'Add Reaction Success': props<{ reaction: Reaction }>(),
    'Remove Reaction': props<{ messageId: string; emoji: string }>(),
    'Remove Reaction Success': props<{ messageId: string; emoji: string; oderId: string }>(),

    /** Merges a batch of messages received from a peer into the local store. */
    'Sync Messages': props<{ messages: Message[] }>(),
    /** Marks the start of a message sync cycle. */
    'Start Sync': emptyProps(),
    /** Marks the end of a message sync cycle. */
    'Sync Complete': emptyProps(),

    /** Attaches fetched link metadata to a message. */
    'Update Link Metadata': props<{ messageId: string; linkMetadata: LinkMetadata[] }>(),

    /** Removes a single link embed from a message by URL. */
    'Remove Link Embed': props<{ messageId: string; url: string }>(),

    /** Removes all messages from the store (e.g. when leaving a room). */
    'Clear Messages': emptyProps()
  }
});
