import { createDbService } from '@/server/services/db.js';
import { decryptChannelSecret } from '@/server/db/queries/alert-channels.js';
import { buildAlertText } from '../render.js';
import { redactError } from '../redact.js';
import type {
  ChannelAdapter,
  AlertPayload,
  AlertChannelRow,
  MonitorEnv,
  ChannelSendResult,
} from '../types.js';

type ChannelWithSecret = AlertChannelRow & { __decryptedSecret?: string | null };

export const telegram: ChannelAdapter = {
  kind: 'telegram',
  async send(
    payload: AlertPayload,
    channel: ChannelWithSecret,
    env: MonitorEnv,
  ): Promise<ChannelSendResult> {
    let token: string | null = null;
    let url: string | null = null;
    try {
      token = channel.__decryptedSecret ?? null;
      if (token == null) {
        const db = createDbService({ DATABASE_URL: env.DATABASE_URL });
        token = await decryptChannelSecret(db, channel.id, env.PII_KEY);
      }
      if (!token) return { ok: false, error: 'telegram channel has no bot token' };

      const chatId = (channel.config as { chatId?: string })?.chatId;
      if (!chatId) return { ok: false, error: 'telegram channel missing chatId' };

      const text = buildAlertText(payload);
      url = `https://api.telegram.org/bot${token}/sendMessage`;
      const resp = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ chat_id: chatId, text }),
      });
      if (!resp.ok) {
        // NEVER include `token` or the request URL in the error.
        return { ok: false, error: `telegram HTTP ${resp.status}` };
      }
      return { ok: true };
    } catch (err) {
      return { ok: false, error: redactError(err, 'telegram send failed', token, url) };
    }
  },
};
