/**
 * ZULIP API Type Definitions
 *
 * These types are based on the ZULIP REST API documentation.
 * @see https://zulip.com/api/
 */

// ============================================================================
// Authentication Types
// ============================================================================

export interface ZulipAuthConfig {
  /** Zulip server URL (e.g., https://yourorg.zulipchat.com) */
  baseUrl: string;
  /** Bot email address */
  email: string;
  /** API key */
  apiKey: string;
}

// ============================================================================
// Message Types
// ============================================================================

export interface ZulipMessage {
  id: number;
  sender_id: number;
  sender_email: string;
  sender_full_name: string;
  sender_realm_str: string;
  content: string;
  content_type: string;
  display_recipient: string | ZulipDisplayRecipient[];
  recipient_id: number;
  stream_id?: number;
  subject: string;
  timestamp: number;
  type: 'stream' | 'private';
  avatar_url: string;
  client: string;
  flags: string[];
  is_me_message: boolean;
  reactions: ZulipReaction[];
  submessages: unknown[];
}

export interface ZulipDisplayRecipient {
  id: number;
  email: string;
  full_name: string;
  is_mirror_dummy: boolean;
}

export interface ZulipReaction {
  emoji_code: string;
  emoji_name: string;
  reaction_type: string;
  user: {
    email: string;
    full_name: string;
    user_id: number;
  };
  user_id: number;
}

export interface ZulipSendMessageRequest {
  /** Message type: 'stream' or 'private' */
  type: 'stream' | 'private';
  /** Stream name (for stream messages) or user IDs (for private messages) */
  to: string | number[];
  /** Topic (required for stream messages) */
  topic?: string;
  /** Message content (Markdown) */
  content: string;
  /** Queue ID for message acknowledgment */
  queue_id?: string;
  /** Local ID for message deduplication */
  local_id?: string;
}

export interface ZulipSendMessageResponse {
  id: number;
  result: string;
  msg: string;
}

export interface ZulipGetMessagesRequest {
  /** Anchor message ID or 'newest'/'oldest'/'first_unread' */
  anchor?: number | 'newest' | 'oldest' | 'first_unread';
  /** Include anchor message */
  include_anchor?: boolean;
  /** Number of messages before anchor */
  num_before?: number;
  /** Number of messages after anchor */
  num_after?: number;
  /** Narrow query (filter) */
  narrow?: ZulipNarrow[];
  /** Apply markdown */
  apply_markdown?: boolean;
  /** Use first unread anchor */
  use_first_unread_anchor?: boolean;
}

export type ZulipNarrow = {
  operator: string;
  operand: string | number;
  negated?: boolean;
};

export interface ZulipGetMessagesResponse {
  result: string;
  msg: string;
  messages: ZulipMessage[];
  found_anchor: boolean;
  found_oldest: boolean;
  found_newest: boolean;
  history_limited: boolean;
  anchor: number;
}

export interface ZulipUpdateMessageRequest {
  message_id: number;
  content?: string;
  topic?: string;
  propagate_mode?: 'change_one' | 'change_later' | 'change_all';
  send_notification_to_old_thread?: boolean;
  send_notification_to_new_thread?: boolean;
}

// ============================================================================
// Stream Types
// ============================================================================

export interface ZulipStream {
  stream_id: number;
  name: string;
  description: string;
  rendered_description: string;
  date_created: number;
  invite_only: boolean;
  is_web_public: boolean;
  is_announcement_only: boolean;
  history_public_to_subscribers: boolean;
  first_message_id: number | null;
  stream_post_policy: number;
  message_retention_days: number | null;
  can_remove_subscribers_group: number;
}

export interface ZulipStreamSubscription extends ZulipStream {
  audible_notifications: boolean | null;
  color: string;
  desktop_notifications: boolean | null;
  email_address: string;
  email_notifications: boolean | null;
  in_home_view: boolean;
  is_muted: boolean;
  pin_to_top: boolean;
  push_notifications: boolean | null;
  stream_weekly_traffic: number | null;
  wildcard_mentions_notify: boolean | null;
}

export interface ZulipGetStreamsResponse {
  result: string;
  msg: string;
  streams: ZulipStream[];
}

export interface ZulipGetSubscriptionsResponse {
  result: string;
  msg: string;
  subscriptions: ZulipStreamSubscription[];
}

export interface ZulipSubscribeRequest {
  subscriptions: Array<{
    name: string;
    description?: string;
  }>;
  principals?: number[];
  invite_only?: boolean;
  history_public_to_subscribers?: boolean;
  announce?: boolean;
}

export interface ZulipSubscribeResponse {
  result: string;
  msg: string;
  subscribed: Record<string, string[]>;
  already_subscribed: Record<string, string[]>;
  unauthorized: string[];
}

// ============================================================================
// User Types
// ============================================================================

export interface ZulipUser {
  user_id: number;
  email: string;
  full_name: string;
  avatar_url: string;
  avatar_version: number;
  is_admin: boolean;
  is_owner: boolean;
  is_billing_admin: boolean;
  is_guest: boolean;
  is_bot: boolean;
  is_active: boolean;
  timezone: string;
  date_joined: string;
  role: number;
  bot_type?: number;
  bot_owner_id?: number;
  profile_data?: Record<string, unknown>;
}

export interface ZulipGetUsersResponse {
  result: string;
  msg: string;
  members: ZulipUser[];
}

export interface ZulipGetUserPresenceResponse {
  result: string;
  msg: string;
  presence: Record<string, {
    status: 'active' | 'idle' | 'offline';
    timestamp: number;
    pushable: boolean;
  }>;
}

// ============================================================================
// Event Types
// ============================================================================

export interface ZulipRegisterQueueResponse {
  result: string;
  msg: string;
  queue_id: string;
  last_event_id: number;
  zulip_feature_level: number;
  zulip_version: string;
  zulip_merge_base: string;
}

export interface ZulipEvent {
  type: string;
  id: number;
  [key: string]: unknown;
}

export interface ZulipGetEventsResponse {
  result: string;
  msg: string;
  events: ZulipEvent[];
  queue_id?: string;
}

// ============================================================================
// API Response Types
// ============================================================================

export interface ZulipApiResponse {
  result: 'success' | 'error';
  msg: string;
}

export interface ZulipApiError extends ZulipApiResponse {
  result: 'error';
  code?: string;
  stream?: string;
}
