import type { Context } from 'telegraf';
import type { TrelloClient } from '../trello/client.js';
import type { Db } from '../db/sqlite.js';
import { queryMessages } from '../db/messages.js';
import { GitHubClient } from '../integrations/github.js';
import {
  getProjectContext,
  buildContextPrompt,
  buildDirectPrompt,
} from '../integrations/project.js';
import { generateTextCLI } from '../gemini/cli.js';
import { sendChunked } from '../agent/chunker.js';
import { logger } from '../utils/logger.js';
import { env } from '../env.js';
import { formatHistory, parseTimeWindow } from './mention-history.js';

export interface MentionHandlerOptions {
  repoPath: string;
  trello: TrelloClient;
  githubRepo: string;
  githubToken?: string;
  db: Db;
  chatId: number;
  googleApiKey: string;
}

export function makeMentionHandler(opts: MentionHandlerOptions) {
  const github = new GitHubClient(opts.githubRepo, opts.githubToken);

  return async function mentionHandler(ctx: Context): Promise<void> {
    if (!ctx.message || !('text' in ctx.message)) return;

    const text = ctx.message.text;
    const botUsername = ctx.botInfo?.username;

    // Only respond when the bot is explicitly @-mentioned
    const mention = botUsername ? `@${botUsername}` : null;
    if (!mention || !text.includes(mention)) return;

    // Extract the question - everything that isn't the @mention
    const question = text.replace(new RegExp(`@${botUsername}`, 'gi'), '').trim();

    if (!question) {
      await ctx.reply(
        'שלום! שאל אותי כל שאלה על הפרויקט, Trello, GitHub, הקוד, או השיחה האחרונה 🤖',
        {
          reply_parameters: { message_id: ctx.message.message_id },
        },
      );
      return;
    }

    logger.debug('mention detected', { question: question.slice(0, 80) });

    await ctx.sendChatAction('typing');

    // Fetch recent chat history
    const timeWindow = parseTimeWindow(question);
    const messages = queryMessages(opts.db, {
      chatId: opts.chatId,
      fromDate: timeWindow.fromDate,
      limit: timeWindow.limit,
    });
    const chatHistory = messages.length > 0 ? formatHistory(messages) : null;

    logger.debug('chat history fetched', {
      count: messages.length,
      hasTimeWindow: !!timeWindow.fromDate,
    });

    let prompt: string;
    try {
      const context = await getProjectContext(opts.repoPath, opts.trello, github);
      prompt = buildContextPrompt(context, question, chatHistory, env.CUSTOM_SYSTEM_PROMPT);
    } catch (err) {
      logger.debug('context gathering failed, answering without it', { error: String(err) });
      prompt = buildDirectPrompt(question, chatHistory);
    }

    try {
      const answer = await generateTextCLI(prompt, opts.googleApiKey, 'mention');
      await sendChunked(ctx, answer, ctx.message.message_id);
    } catch (err) {
      logger.error('gemini call failed', { error: String(err) });
      await ctx.reply('לא הצלחתי לענות כרגע. נסה שוב.', {
        reply_parameters: { message_id: ctx.message.message_id },
      });
    }
  };
}
