const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN!;
const DEFAULT_CHAT_ID = process.env.TELEGRAM_CHAT_ID!;
const ALLOWED_IDS = new Set(
  (process.env.TELEGRAM_ALLOWED_CHAT_IDS || DEFAULT_CHAT_ID)
    .split(",")
    .map((id) => id.trim())
);

const api = async (method: string, body?: Record<string, unknown>) => {
  const res = await fetch(
    `https://api.telegram.org/bot${BOT_TOKEN}/${method}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: body ? JSON.stringify(body) : undefined,
    }
  );
  return res.json();
};

export function isAllowed(chatId: number | string): boolean {
  return ALLOWED_IDS.has(String(chatId));
}

export async function send(
  text: string,
  chatId: string | number = DEFAULT_CHAT_ID,
  opts?: { reply_to?: number; keyboard?: InlineKeyboard }
): Promise<any> {
  if (!isAllowed(chatId)) return null;

  // Telegram limits messages to 4096 chars
  const truncated =
    text.length > 4000 ? text.slice(0, 4000) + "\n\n... (truncated)" : text;

  const body: Record<string, unknown> = {
    chat_id: chatId,
    text: truncated,
    parse_mode: "Markdown",
  };
  if (opts?.reply_to) body.reply_to_message_id = opts.reply_to;
  if (opts?.keyboard) {
    body.reply_markup = { inline_keyboard: opts.keyboard };
  }
  return api("sendMessage", body);
}

export async function editMessage(
  chatId: string | number,
  messageId: number,
  text: string,
  keyboard?: InlineKeyboard
): Promise<any> {
  const truncated =
    text.length > 4000 ? text.slice(0, 4000) + "\n\n... (truncated)" : text;
  const body: Record<string, unknown> = {
    chat_id: chatId,
    message_id: messageId,
    text: truncated,
    parse_mode: "Markdown",
  };
  if (keyboard) body.reply_markup = { inline_keyboard: keyboard };
  return api("editMessageText", body);
}

export async function answerCallback(
  callbackId: string,
  text?: string
): Promise<any> {
  return api("answerCallbackQuery", {
    callback_query_id: callbackId,
    text,
  });
}

export type InlineKeyboard = Array<
  Array<{ text: string; callback_data: string }>
>;

export function agentKeyboard(agentId: number): InlineKeyboard {
  return [
    [
      { text: "📋 Logs", callback_data: `logs_${agentId}` },
      { text: "💬 Talk", callback_data: `talk_${agentId}` },
      { text: "🛑 Kill", callback_data: `kill_${agentId}` },
    ],
  ];
}

let offset = 0;

export interface TelegramUpdate {
  update_id: number;
  message?: {
    message_id: number;
    from?: { id: number; first_name: string };
    chat: { id: number; type: string };
    text?: string;
    reply_to_message?: { message_id: number };
  };
  callback_query?: {
    id: string;
    from: { id: number };
    message?: { message_id: number; chat: { id: number } };
    data?: string;
  };
}

export async function poll(): Promise<TelegramUpdate[]> {
  try {
    const data = await api("getUpdates", {
      offset,
      timeout: 30,
      allowed_updates: ["message", "callback_query"],
    });
    const updates: TelegramUpdate[] = data.result || [];
    if (updates.length > 0) {
      offset = updates[updates.length - 1].update_id + 1;
    }
    return updates;
  } catch (e) {
    console.error("[telegram] poll error:", e);
    return [];
  }
}

export async function deleteMessage(
  chatId: string | number,
  messageId: number
): Promise<boolean> {
  try {
    const res = await api("deleteMessage", {
      chat_id: chatId,
      message_id: messageId,
    });
    return !!res?.ok;
  } catch {
    return false;
  }
}

export default { send, editMessage, deleteMessage, poll, isAllowed, agentKeyboard, answerCallback };
