import type { Customer } from '../billing/middleware.js';
import type { OAuthCredentials } from '../multitenancy/credential-store.js';
import { createToolAudit } from '../multitenancy/audit-log.js';

const TELEGRAM_API_BASE = 'https://api.telegram.org';

function getEnvToken(account: string): string {
  const envKey = `TELEGRAM_${account.toUpperCase()}_BOT_TOKEN`;
  return process.env[envKey] ?? '';
}

async function resolveToken(args: { account?: string }, customer?: Customer): Promise<string> {
  if (customer) {
    const creds = await customer.getCredential<OAuthCredentials>('telegram');
    if (!creds) throw new Error('Telegram not connected for this account');
    return creds.accessToken;
  }
  const token = getEnvToken(args.account ?? 'default');
  if (!token) throw new Error('Missing Telegram credentials. Set TELEGRAM_{ACCOUNT}_BOT_TOKEN');
  return token;
}

async function telegramRequest(
  token: string,
  method: string,
  params?: Record<string, unknown>
) {
  const url = `${TELEGRAM_API_BASE}/bot${token}/${method}`;
  const res = await fetch(url, {
    method: params ? 'POST' : 'GET',
    headers: params ? { 'Content-Type': 'application/json' } : undefined,
    body: params ? JSON.stringify(params) : undefined,
    signal: AbortSignal.timeout(15000),
  });

  const data = await res.json();
  if (!data.ok) {
    throw new Error(`Telegram API error: ${data.description ?? 'Unknown error'}`);
  }
  return data.result;
}

export async function getMe(
  args: { account?: string },
  customer?: Customer
): Promise<{
  id: number;
  first_name: string;
  username: string;
  is_bot: boolean;
}> {
  const token = await resolveToken(args, customer);
  return telegramRequest(token, 'getMe');
}

export async function sendMessage(
  args: { chat_id: string | number; text: string; parse_mode?: 'HTML' | 'Markdown' | 'MarkdownV2'; account?: string },
  customer?: Customer
): Promise<{ message_id: number; chat_id: string | number }> {
  const audit = customer ? createToolAudit(customer.id, 'telegram:sendMessage') : null;
  const auditArgs = { chat_id: args.chat_id };
  const token = await resolveToken(args, customer);

  try {
    const result = await telegramRequest(token, 'sendMessage', {
      chat_id: args.chat_id,
      text: args.text,
      parse_mode: args.parse_mode,
    });
    const r = { message_id: result.message_id, chat_id: result.chat.id };
    if (audit) await audit.success(auditArgs);
    return r;
  } catch (err) {
    if (audit) await audit.error(auditArgs, String(err));
    throw err;
  }
}

export async function sendPhoto(
  args: { chat_id: string | number; photo: string; caption?: string; account?: string },
  customer?: Customer
): Promise<{ message_id: number; chat_id: string | number }> {
  const audit = customer ? createToolAudit(customer.id, 'telegram:sendPhoto') : null;
  const auditArgs = { chat_id: args.chat_id };
  const token = await resolveToken(args, customer);

  try {
    const result = await telegramRequest(token, 'sendPhoto', {
      chat_id: args.chat_id,
      photo: args.photo,
      caption: args.caption,
    });
    const r = { message_id: result.message_id, chat_id: result.chat.id };
    if (audit) await audit.success(auditArgs);
    return r;
  } catch (err) {
    if (audit) await audit.error(auditArgs, String(err));
    throw err;
  }
}

export async function getUpdates(
  args: { limit?: number; account?: string },
  customer?: Customer
): Promise<Array<{
  update_id: number;
  message?: {
    message_id: number;
    from?: { id: number; first_name: string; username?: string };
    chat: { id: number; type: string; title?: string };
    date: number;
    text?: string;
  };
}>> {
  const token = await resolveToken(args, customer);
  return telegramRequest(token, 'getUpdates', { limit: args.limit ?? 10 });
}

export async function getChat(
  args: { chat_id: string | number; account?: string },
  customer?: Customer
): Promise<{
  id: number;
  type: string;
  title?: string;
  username?: string;
  description?: string;
  member_count?: number;
}> {
  const token = await resolveToken(args, customer);
  return telegramRequest(token, 'getChat', { chat_id: args.chat_id });
}
