import type { Context } from 'telegraf';
import type { Db } from '../db/sqlite.js';
import { insertMessage } from '../db/messages.js';
import { transcribeAudio } from '../gemini/client.js';
import { logger } from '../utils/logger.js';

export interface VoiceHandlerOptions {
  db: Db;
  botToken: string;
  googleApiKey: string;
}

export function makeVoiceHandler(opts: VoiceHandlerOptions) {
  return async function voiceHandler(ctx: Context): Promise<void> {
    if (!ctx.message || !('voice' in ctx.message)) return;

    const voice = ctx.message.voice;
    const from = ctx.message.from;
    const chatId = ctx.message.chat.id;

    try {
      // Download voice file from Telegram
      const file = await ctx.telegram.getFile(voice.file_id);
      if (!file.file_path) throw new Error('No file_path returned');

      const fileUrl = `https://api.telegram.org/file/bot${opts.botToken}/${file.file_path}`;
      const response = await fetch(fileUrl);
      if (!response.ok) throw new Error(`Download failed: ${response.status}`);

      const buffer = await response.arrayBuffer();
      const base64 = Buffer.from(buffer).toString('base64');
      const mimeType = voice.mime_type ?? 'audio/ogg';

      // Transcribe with Gemini
      const transcription = await transcribeAudio(base64, mimeType, opts.googleApiKey);

      if (!transcription) {
        await ctx.reply('🎤 _(could not transcribe)_', {
          reply_parameters: { message_id: ctx.message.message_id },
        });
        return;
      }

      // Reply to the voice message with transcription
      await ctx.reply(`🎤 ${transcription}`, {
        reply_parameters: { message_id: ctx.message.message_id },
      });

      // Store in DB as a text message
      insertMessage(opts.db, {
        message_id: ctx.message.message_id,
        chat_id: chatId,
        user_id: from?.id ?? null,
        username: from?.username ?? null,
        first_name: from?.first_name ?? null,
        text: `[Voice] ${transcription}`,
        date: ctx.message.date,
      });

      logger.debug('voice transcribed', { chars: transcription.length });
    } catch (err) {
      logger.error('voice transcription failed', {
        error: err instanceof Error ? err.message : String(err),
      });
      await ctx.reply('🎤 _(transcription failed)_', {
        reply_parameters: { message_id: ctx.message.message_id },
      });
    }
  };
}
