// Direct-messaging domain: the E2EE key bundle setup/reset, the conversation list, threads, and
// send/unread. Self-contained — types reference only each other, methods only touch core's req.
// (The WebCrypto layer that encrypts/decrypts message bodies lives in e2ee.ts, not here.)
import { req } from "./core";

export interface MessageUser {
  id: number;
  name: string;
  avatar_url: string | null;
}

export interface Message {
  id: number;
  kind: "user" | "system";
  sender_id: number | null;
  recipient_id: number;
  body: string | null; // plaintext, system messages only
  ciphertext: string | null; // base64, E2EE user messages only
  iv: string | null;
  read_at: string | null;
  created_at: string | null;
}

export interface Conversation {
  partner: MessageUser;
  last_message: Message;
  unread: number;
}

// My own E2EE key bundle. When configured, the wrapped blob + params let a device unlock.
export interface MyKeyBundle {
  configured: boolean;
  public_key?: string;
  wrapped_private_key?: string;
  salt?: string;
  wrap_iv?: string;
  key_check?: string;
}

export interface KeySetup {
  public_key: string;
  wrapped_private_key: string;
  salt: string;
  wrap_iv: string;
  key_check: string;
}

export const messagingApi = {
  messageMyKey: (): Promise<MyKeyBundle> => req("/api/messages/keys/me"),
  setupMessageKey: (k: KeySetup): Promise<{ configured: boolean }> =>
    req("/api/messages/keys", { method: "POST", body: JSON.stringify(k) }),
  // Forgotten-passphrase reset: drops the server key (and the now-undecryptable history) so a new
  // passphrase can be set. Password accounts must pass their current password; errors shown inline.
  resetMessageKey: (currentPassword?: string): Promise<{ configured: boolean }> =>
    req(
      "/api/messages/keys/reset",
      { method: "POST", body: JSON.stringify({ current_password: currentPassword ?? null }) },
      { quiet: true },
    ),
  messagePublicKey: (userId: number): Promise<{ user_id: number; public_key: string }> =>
    req(`/api/messages/keys/${userId}`),
  messageUsers: (): Promise<MessageUser[]> => req("/api/messages/users"),
  conversations: (): Promise<{ items: Conversation[] }> => req("/api/messages/conversations"),
  thread: (partnerId: number): Promise<{ partner: MessageUser; items: Message[] }> =>
    req(`/api/messages/conversations/${partnerId}`),
  sendMessage: (recipientId: number, ciphertext: string, iv: string): Promise<Message> =>
    req("/api/messages", {
      method: "POST",
      body: JSON.stringify({ recipient_id: recipientId, ciphertext, iv }),
    }),
  messageUnreadCount: (): Promise<{ count: number }> => req("/api/messages/unread_count"),
};
