import { markdownToMatrixHtml } from "../format.js";
import { getMatrixRuntime } from "../../runtime.js";
import {
  MsgType,
  RelationType,
  type MatrixFormattedContent,
  type MatrixMediaMsgType,
  type MatrixRelation,
  type MatrixReplyRelation,
  type MatrixTextContent,
  type MatrixThreadRelation,
} from "./types.js";

const getCore = () => getMatrixRuntime();

export function buildTextContent(
  body: string,
  relation?: MatrixRelation,
): MatrixTextContent {
  const content: MatrixTextContent = relation
    ? {
        msgtype: MsgType.Text,
        body,
        "m.relates_to": relation,
      }
    : {
        msgtype: MsgType.Text,
        body,
      };
  applyMatrixFormatting(content, body);
  return content;
}

export function applyMatrixFormatting(content: MatrixFormattedContent, body: string): void {
  const formatted = markdownToMatrixHtml(body ?? "");
  if (!formatted) return;
  content.format = "org.matrix.custom.html";
  content.formatted_body = formatted;
}

export function buildReplyRelation(replyToId?: string): MatrixReplyRelation | undefined {
  const trimmed = replyToId?.trim();
  if (!trimmed) return undefined;
  return { "m.in_reply_to": { event_id: trimmed } };
}

export function buildThreadRelation(
  threadId: string,
  replyToId?: string,
): MatrixThreadRelation {
  const trimmed = threadId.trim();
  return {
    rel_type: RelationType.Thread,
    event_id: trimmed,
    is_falling_back: true,
    "m.in_reply_to": { event_id: (replyToId?.trim() || trimmed) },
  };
}

export function resolveMatrixMsgType(
  contentType?: string,
  _fileName?: string,
): MatrixMediaMsgType {
  const kind = getCore().media.mediaKindFromMime(contentType ?? "");
  switch (kind) {
    case "image":
      return MsgType.Image;
    case "audio":
      return MsgType.Audio;
    case "video":
      return MsgType.Video;
    default:
      return MsgType.File;
  }
}

export function resolveMatrixVoiceDecision(opts: {
  wantsVoice: boolean;
  contentType?: string;
  fileName?: string;
}): { useVoice: boolean } {
  if (!opts.wantsVoice) return { useVoice: false };
  if (
    getCore().media.isVoiceCompatibleAudio({
      contentType: opts.contentType,
      fileName: opts.fileName,
    })
  ) {
    return { useVoice: true };
  }
  return { useVoice: false };
}
