/**
 * Socket.IO event types aligned with imks real-time messaging handlers.
 */

export const ClientEvent = {
  ChannelJoin: 'channel:join',
  ChannelLeave: 'channel:leave',
  MessageSend: 'message:send',
  MessageEdit: 'message:edit',
  MessageDelete: 'message:delete',
  ReactionAdd: 'reaction:add',
  PinAdd: 'pin:add',
  PinRemove: 'pin:remove',
  PollVote: 'poll:vote',
  PollVoteRemove: 'poll:vote:remove',
  TypingStart: 'typing:start',
  TypingStop: 'typing:stop',
  PresenceUpdate: 'presence:update',
  DraftSave: 'draft:save',
  DraftGet: 'draft:get',
  DraftDelete: 'draft:delete',
  ReadStateMark: 'read_state:mark',
  ReadStateGet: 'read_state:get',
  NotificationList: 'notification:list',
  NotificationMarkRead: 'notification:mark_read',
  NotificationMarkAllRead: 'notification:mark_all_read',
  BookmarkAdd: 'bookmark:add',
  BookmarkRemove: 'bookmark:remove',
  BookmarkList: 'bookmark:list',
  ThreadCreate: 'thread:create',
  ThreadResolve: 'thread:resolve',
  ThreadJoin: 'thread:join',
  ThreadLeave: 'thread:leave',
  ThreadList: 'thread:list',
  ArticleCreate: 'article:create',
  ArticleUpdate: 'article:update',
  ArticleList: 'article:list',
  ArticleDelete: 'article:delete',
  ComponentInteract: 'component:interact',
  ComponentUpdate: 'component:update',
} as const;

export type ClientEvent = (typeof ClientEvent)[keyof typeof ClientEvent];

export const ServerEvent = {
  MessageNew: 'message:new',
  MessageUpdated: 'message:updated',
  MessageDeleted: 'message:deleted',
  Typing: 'typing',
  ReactionUpdated: 'reaction:updated',
  PresenceUpdate: 'presence:update',
  PinAdded: 'pin:added',
  PinRemoved: 'pin:removed',
  PollUpdated: 'poll:updated',
  DraftLoaded: 'draft:loaded',
  ReadStateUpdated: 'read_state:updated',
  ReadStateLoaded: 'read_state:loaded',
  NotificationLoaded: 'notification:loaded',
  NotificationUnreadCount: 'notification:unread_count',
  BookmarkLoaded: 'bookmark:loaded',
  ThreadCreated: 'thread:created',
  ThreadUpdated: 'thread:updated',
  ThreadParticipantJoined: 'thread:participant_joined',
  ThreadParticipantLeft: 'thread:participant_left',
  ThreadLoaded: 'thread:loaded',
  ArticleCreated: 'article:created',
  ArticleUpdated: 'article:updated',
  ArticleDeleted: 'article:deleted',
  ArticleLoaded: 'article:loaded',
  ComponentInteraction: 'component:interaction',
  ComponentUpdated: 'component:updated',
  EditHistory: 'message:edit_history',
} as const;

export type ServerEvent = (typeof ServerEvent)[keyof typeof ServerEvent];

export interface JoinChannelPayload {
  channel_id: string;
}

export interface LeaveChannelPayload {
  channel_id: string;
}

export interface SendMessagePayload {
  channel_id: string;
  body: string;
  thread_id?: string | null;
  reply_to_message_id?: string | null;
  nonce?: string;
  mentioned_user_ids?: string[];
  attachments?: AttachmentInput[];
  embeds?: EmbedInput[];
  sticker?: StickerInput;
  forward?: ForwardInput;
}

export interface EditMessagePayload {
  message_id: string;
  body: string;
}

export interface DeleteMessagePayload {
  message_id: string;
}

export interface ReactionPayload {
  message_id: string;
  content: string;
}

export interface PinPayload {
  channel_id: string;
  message_id: string;
}

export interface PollVotePayload {
  poll_id: string;
  option_id: string;
}

export interface TypingPayload {
  channel_id: string;
}

export interface PresencePayload {
  channel_id: string;
  online: boolean;
}

export interface DraftPayload {
  channel_id: string;
  body?: string;
  thread_id?: string | null;
  reply_to_message_id?: string | null;
  metadata?: unknown;
}

export interface ReadStateMarkPayload {
  channel_id: string;
  message_id: string;
}

export interface ReadStateGetPayload {
  channel_id: string;
}

export interface NotificationListPayload {
  before?: string;
  limit?: number;
}

export interface BookmarkAddPayload {
  message_id: string;
  channel_id: string;
  note?: string;
}

export interface BookmarkRemovePayload {
  message_id: string;
}

export interface BookmarkListPayload {
  before?: string;
  limit?: number;
}

export interface ThreadCreatePayload {
  channel_id: string;
  root_message_id: string;
}

export interface ThreadResolvePayload {
  thread_id: string;
  resolved: boolean;
}

export interface ThreadJoinLeavePayload {
  thread_id: string;
}

export interface ArticlePayload {
  channel_id: string;
  title: string;
  body: string;
  summary?: string;
  cover_url?: string;
  tags?: unknown;
}

export interface ArticleUpdatePayload {
  message_id: string;
  title?: string;
  body?: string;
  summary?: string;
  cover_url?: string;
  cover_color?: string;
  tags?: unknown;
}

export interface ArticleDeletePayload {
  message_id: string;
  channel_id: string;
}

export interface ComponentInteractPayload {
  component_id: string;
  custom_id: string;
  message_id: string;
  channel_id: string;
}

export interface ComponentUpdatePayload {
  component_id: string;
  label?: string;
  disabled?: boolean;
}

export interface AttachmentInput {
  filename: string;
  url: string;
  size: number;
  content_type?: string;
}

export interface EmbedInput {
  embed_type: string;
  title?: string;
  description?: string;
  url?: string;
  image_url?: string;
  fields?: { name: string; value: string; inline?: boolean }[];
}

export interface StickerInput {
  sticker_id: string;
  name: string;
  image_url: string;
  format_type?: string;
}

export interface ForwardInput {
  source_message_id: string;
  source_channel_id: string;
}

export interface MessageNewPayload {
  id: string;
  channel_id: string;
  author_id: string;
  thread_id?: string | null;
  reply_to_message_id?: string | null;
  message_type: string;
  body: string;
  metadata?: unknown;
  pinned: boolean;
  system: boolean;
  edited_at?: string | null;
  deleted_at?: string | null;
  created_at: string;
  updated_at: string;
}

export interface MessageUpdatedPayload extends MessageNewPayload {}

export interface MessageDeletedPayload {
  id: string;
  channel_id: string;
}

export interface TypingPayloadServer {
  user_id: string;
  channel_id: string;
  typing: boolean;
  username?: string;
}

export interface ReactionUpdatedPayload {
  message_id: string;
  channel_id: string;
  content: string;
  user_id: string;
  action: 'add' | 'remove';
}

export interface PresenceUpdatePayload {
  user_id: string;
  online: boolean;
}

export interface PinAddedPayload {
  channel_id: string;
  message_id: string;
  pinned_by: string;
}

export interface PinRemovedPayload {
  channel_id: string;
  message_id: string;
}

export interface ThreadUpdatedPayload {
  thread_id: string;
  resolved: boolean;
  resolved_by: string;
}

export interface ThreadParticipantPayload {
  thread_id: string;
  user_id: string;
}

export interface ArticleDeletedPayload {
  id: string;
  channel_id: string;
}

export interface ComponentInteractionPayload {
  component_id: string;
  custom_id: string;
  message_id: string;
  user_id: string;
  channel_id: string;
}

export interface EditHistoryPayload {
  message_id: string;
  edits: unknown[];
  edit_count: number;
  last_edited_at: string | null;
  last_edited_by: string | null;
}

export interface ClientEventMap {
  [ClientEvent.ChannelJoin]: [JoinChannelPayload];
  [ClientEvent.ChannelLeave]: [LeaveChannelPayload];
  [ClientEvent.MessageSend]: [SendMessagePayload];
  [ClientEvent.MessageEdit]: [EditMessagePayload];
  [ClientEvent.MessageDelete]: [DeleteMessagePayload];
  [ClientEvent.ReactionAdd]: [ReactionPayload];
  [ClientEvent.PinAdd]: [PinPayload];
  [ClientEvent.PinRemove]: [PinPayload];
  [ClientEvent.PollVote]: [PollVotePayload];
  [ClientEvent.PollVoteRemove]: [PollVotePayload];
  [ClientEvent.TypingStart]: [TypingPayload];
  [ClientEvent.TypingStop]: [TypingPayload];
  [ClientEvent.PresenceUpdate]: [PresencePayload];
  [ClientEvent.DraftSave]: [DraftPayload];
  [ClientEvent.DraftGet]: [DraftPayload];
  [ClientEvent.DraftDelete]: [DraftPayload];
  [ClientEvent.ReadStateMark]: [ReadStateMarkPayload];
  [ClientEvent.ReadStateGet]: [ReadStateGetPayload];
  [ClientEvent.NotificationList]: [NotificationListPayload?];
  [ClientEvent.NotificationMarkRead]: [{ notification_id: string }];
  [ClientEvent.NotificationMarkAllRead]: [];
  [ClientEvent.BookmarkAdd]: [BookmarkAddPayload];
  [ClientEvent.BookmarkRemove]: [BookmarkRemovePayload];
  [ClientEvent.BookmarkList]: [BookmarkListPayload?];
  [ClientEvent.ThreadCreate]: [ThreadCreatePayload];
  [ClientEvent.ThreadResolve]: [ThreadResolvePayload];
  [ClientEvent.ThreadJoin]: [ThreadJoinLeavePayload];
  [ClientEvent.ThreadLeave]: [ThreadJoinLeavePayload];
  [ClientEvent.ThreadList]: [{ channel_id: string }];
  [ClientEvent.ArticleCreate]: [ArticlePayload];
  [ClientEvent.ArticleUpdate]: [ArticleUpdatePayload];
  [ClientEvent.ArticleList]: [{ channel_id: string; limit?: number }];
  [ClientEvent.ArticleDelete]: [ArticleDeletePayload];
  [ClientEvent.ComponentInteract]: [ComponentInteractPayload];
  [ClientEvent.ComponentUpdate]: [ComponentUpdatePayload];
}

export interface ServerEventMap {
  [ServerEvent.MessageNew]: [MessageNewPayload];
  [ServerEvent.MessageUpdated]: [MessageUpdatedPayload];
  [ServerEvent.MessageDeleted]: [MessageDeletedPayload];
  [ServerEvent.Typing]: [TypingPayloadServer];
  [ServerEvent.ReactionUpdated]: [ReactionUpdatedPayload];
  [ServerEvent.PresenceUpdate]: [PresenceUpdatePayload];
  [ServerEvent.PinAdded]: [PinAddedPayload];
  [ServerEvent.PinRemoved]: [PinRemovedPayload];
  [ServerEvent.PollUpdated]: [unknown];
  [ServerEvent.DraftLoaded]: [unknown];
  [ServerEvent.ReadStateUpdated]: [unknown];
  [ServerEvent.ReadStateLoaded]: [unknown];
  [ServerEvent.NotificationLoaded]: [unknown];
  [ServerEvent.NotificationUnreadCount]: [{ count: number }];
  [ServerEvent.BookmarkLoaded]: [unknown];
  [ServerEvent.ThreadCreated]: [unknown];
  [ServerEvent.ThreadUpdated]: [ThreadUpdatedPayload];
  [ServerEvent.ThreadParticipantJoined]: [ThreadParticipantPayload];
  [ServerEvent.ThreadParticipantLeft]: [ThreadParticipantPayload];
  [ServerEvent.ThreadLoaded]: [unknown];
  [ServerEvent.ArticleCreated]: [unknown];
  [ServerEvent.ArticleUpdated]: [unknown];
  [ServerEvent.ArticleDeleted]: [ArticleDeletedPayload];
  [ServerEvent.ArticleLoaded]: [unknown];
  [ServerEvent.ComponentInteraction]: [ComponentInteractionPayload];
  [ServerEvent.ComponentUpdated]: [unknown];
  [ServerEvent.EditHistory]: [EditHistoryPayload];
}

export type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
