/**
 * Outbound messaging to users via platform IPC.
 */
import path from "path";
import fs from "fs";
import { randomBytes } from "crypto";
import { getContext } from "../client.js";
import { writeIpcFile } from "../ipc.js";

function chatJid(): string {
  return process.env.NANOCLAW_CHAT_JID ?? "";
}

function groupFolder(): string {
  return process.env.NANOCLAW_GROUP_FOLDER ?? "";
}

function messagesDir(ipcDir: string): string {
  return path.join(ipcDir, "messages");
}

export async function sendMessage(
  text: string,
  opts?: { kind?: "progress" | "user_message"; sender?: string },
  ipcDir?: string
): Promise<void> {
  const dir = ipcDir ?? getContext().ipcDir;
  writeIpcFile(messagesDir(dir), {
    type: "message",
    chatJid: chatJid(),
    groupFolder: groupFolder(),
    text,
    kind: opts?.kind,
    sender: opts?.sender,
  });
}

export async function sendMessageToGroup(
  groupJid: string,
  text: string,
  opts?: { kind?: "progress" | "user_message"; sender?: string },
  ipcDir?: string
): Promise<void> {
  const dir = ipcDir ?? getContext().ipcDir;
  writeIpcFile(messagesDir(dir), {
    type: "message",
    chatJid: groupJid,
    groupFolder: groupFolder(),
    text,
    kind: opts?.kind,
    sender: opts?.sender,
  });
}

export async function sendFile(filePath: string, caption?: string, ipcDir?: string): Promise<void> {
  const dir = ipcDir ?? getContext().ipcDir;

  // Files must be accessible to nanoclaw on the host. Only /workspace/group/ is
  // bind-mounted with a known host translation. If the file is elsewhere (e.g.
  // /tmp/), copy it into /workspace/group/.send-outbox/ so nanoclaw can find it.
  let ipcPath = filePath;
  if (!filePath.startsWith("/workspace/group/")) {
    if (!fs.existsSync(filePath)) {
      throw new Error(`tc send file: file not found: ${filePath}`);
    }
    const outbox = "/workspace/group/.send-outbox";
    const slot = path.join(outbox, randomBytes(8).toString("hex"));
    fs.mkdirSync(slot, { recursive: true });
    const dest = path.join(slot, path.basename(filePath));
    fs.copyFileSync(filePath, dest);
    ipcPath = dest;
  }

  writeIpcFile(messagesDir(dir), {
    type: "file",
    chatJid: chatJid(),
    groupFolder: groupFolder(),
    filePath: ipcPath,
    caption,
  });
}

export async function sendVoice(
  text: string,
  opts?: { provider?: string; voice?: string; caption?: string },
  ipcDir?: string
): Promise<void> {
  const dir = ipcDir ?? getContext().ipcDir;
  writeIpcFile(messagesDir(dir), {
    type: "send_voice_message",
    chatJid: chatJid(),
    groupFolder: groupFolder(),
    text,
    provider: opts?.provider,
    voice: opts?.voice,
    caption: opts?.caption,
  });
}
