import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
import { MsgType } from 'matrix-js-sdk';

export const MATRIX_BLUR_HASH_PROPERTY_NAME = 'xyz.amorgan.blurhash';
export const MATRIX_SPOILER_PROPERTY_NAME = 'page.codeberg.everypizza.msc4193.spoiler';
export const MATRIX_SPOILER_REASON_PROPERTY_NAME =
  'page.codeberg.everypizza.msc4193.spoiler.reason';

// MSC3245 voice message marker (presence ⇒ render as a voice note) and the
// MSC1767 extensible-audio block carrying duration + waveform. Both Vojo-native
// and Telegram-bridged voice notes carry these keys. See
// docs/plans/voice_messages.md §2.1.
export const MATRIX_VOICE_PROPERTY_NAME = 'org.matrix.msc3245.voice';
// Legacy unstable prefix some older clients used before msc3245.voice.
export const MATRIX_VOICE_LEGACY_PROPERTY_NAME = 'org.matrix.msc2516.voice';
export const MATRIX_AUDIO_PROPERTY_NAME = 'org.matrix.msc1767.audio';

// Single source of truth for "is this m.audio a voice note?" — used by both the
// renderer (RenderMessageContent → VoiceContent) and the layout (Message.tsx
// bubble-collapse) so the two never disagree. See docs/plans/voice_messages.md §5.
export const isVoiceMessageContent = (content: Record<string, unknown> | undefined): boolean =>
  !!content?.[MATRIX_VOICE_PROPERTY_NAME] || !!content?.[MATRIX_VOICE_LEGACY_PROPERTY_NAME];

export type IImageInfo = {
  w?: number;
  h?: number;
  mimetype?: string;
  size?: number;
  [MATRIX_BLUR_HASH_PROPERTY_NAME]?: string;
};

export type IVideoInfo = {
  w?: number;
  h?: number;
  mimetype?: string;
  size?: number;
  duration?: number;
};

export type IAudioInfo = {
  mimetype?: string;
  size?: number;
  duration?: number;
};

// MSC1767 `org.matrix.msc1767.audio`: duration (ms) + waveform (integers 0..1024).
export type IMSC1767Audio = {
  duration?: number;
  waveform?: number[];
};

export type IFileInfo = {
  mimetype?: string;
  size?: number;
};

export type IEncryptedFile = EncryptedAttachmentInfo & {
  url: string;
};

export type IThumbnailContent = {
  thumbnail_info?: IImageInfo;
  thumbnail_file?: IEncryptedFile;
  thumbnail_url?: string;
};

export type IImageContent = {
  msgtype: MsgType.Image;
  body?: string;
  filename?: string;
  url?: string;
  info?: IImageInfo & IThumbnailContent;
  file?: IEncryptedFile;
  [MATRIX_SPOILER_PROPERTY_NAME]?: boolean;
  [MATRIX_SPOILER_REASON_PROPERTY_NAME]?: string;
};

export type IVideoContent = {
  msgtype: MsgType.Video;
  body?: string;
  filename?: string;
  url?: string;
  info?: IVideoInfo & IThumbnailContent;
  file?: IEncryptedFile;
  [MATRIX_SPOILER_PROPERTY_NAME]?: boolean;
  [MATRIX_SPOILER_REASON_PROPERTY_NAME]?: string;
};

export type IAudioContent = {
  msgtype: MsgType.Audio;
  body?: string;
  filename?: string;
  url?: string;
  info?: IAudioInfo;
  file?: IEncryptedFile;
  // Voice-note keys — present when this audio is a voice message.
  [MATRIX_VOICE_PROPERTY_NAME]?: Record<string, never>;
  [MATRIX_AUDIO_PROPERTY_NAME]?: IMSC1767Audio;
};

export type IFileContent = {
  msgtype: MsgType.File;
  body?: string;
  filename?: string;
  url?: string;
  info?: IFileInfo & IThumbnailContent;
  file?: IEncryptedFile;
};

export type ILocationContent = {
  msgtype: MsgType.Location;
  body?: string;
  geo_uri?: string;
  info?: IThumbnailContent;
};
