import { Injectable, Inject, Logger } from '@nestjs/common';
import { Context, Telegraf, Markup } from 'telegraf';
import { Update as TelegrafUpdate } from 'telegraf/typings/core/types/typegram';
import { TestService } from './services/test.service';
import { MenuService } from './services/menu.service';
import { PaymentService } from './services/payment.service';
import { UserService } from './services/user.service';
import { AiService } from 'src/ai/ai.service';
import { PrismaService } from '../common/services/prisma.service';
import { DO_YOU_HAVE_COURAGE, EFFECTS_CAPTION, FORGIVE_CAPTION, QUESTIONS, WHO_IS_JORDAN } from '../common/constants/questions.constants';
import { SafeTelegramHelper } from 'src/common/helpers/safe-telegram.helper';

interface CallbackContext extends Context {
  match?: RegExpMatchArray;
}

@Injectable()
export class BotService {
  private readonly logger = new Logger(BotService.name);
  constructor(
    private testService: TestService,
    private menuService: MenuService,
    private paymentService: PaymentService,
    private userService: UserService,
    private aiService: AiService,
    private prisma: PrismaService,
    @Inject('TELEGRAF_BOT') private bot: Telegraf<Context>,
  ) {
    this.setupHandlers();
  }

  private setupHandlers() {

    this.bot.start(this.wrapHandler((ctx) => this.start(ctx)));
    this.bot.on('text', this.wrapHandler((ctx) => this.handleText(ctx)));
    this.bot.action('forgive', this.wrapHandler((ctx) => this.forgive(ctx)));

    this.bot.action('effects', (ctx) => this.effects(ctx));
    this.bot.action('peterson', (ctx) => this.peterson(ctx));
    this.bot.action('back', (ctx) => this.back(ctx));
    this.bot.action('start_test', (ctx) => this.startTest(ctx));
    this.bot.action('confirm_test', (ctx) => this.confirmTest(ctx));
    this.bot.action('get_result', (ctx) => this.getResult(ctx));
    this.bot.action('demo_result', (ctx) => this.demoResult(ctx));
    this.bot.action('upgrade_premium', (ctx) => this.upgradePremium(ctx));
    this.bot.action('pay_crypto', (ctx) => this.payCrypto(ctx));
    this.bot.action('pay_rial', (ctx) => this.payRial(ctx));
    this.bot.action(/check_payment_(.+)/, (ctx) => this.checkPayment(ctx));
    this.bot.action(/edit_(\d+)/, (ctx) => this.editQuestion(ctx));
  }

  private wrapHandler(handler: (ctx: Context) => Promise<void>) {
    return async (ctx: Context) => {
      try {
        await handler(ctx);
      } catch (error: any) {
        this.logger.error(`Handler error: ${error.message}`, error.stack);

        // اگر خطا مربوط به بلاک بودن کاربر باشه، فقط لاگ کن
        if (error.message?.includes('bot was blocked') ||
          error.message?.includes('user is deactivated')) {
          this.logger.warn(`User ${ctx.from?.id} has blocked the bot`);
          return;
        }

        // برای سایر خطاها سعی کن یک پیام خطا بفرست
        await SafeTelegramHelper.safeSendMessage(
          ctx,
          '❌ متاسفانه خطایی رخ داد. لطفا دوباره تلاش کنید.'
        );
      }
    };
  }

  async start(ctx: Context) {
    await this.menuService.safeDeleteMessage(ctx);
    await this.menuService.sendMainMenu(ctx);
  }

  async handleText(ctx: Context<TelegrafUpdate>) {
    if (!ctx.from || !ctx.message || !('text' in ctx.message)) return;

    const text = ctx.message.text;
    const telegramId = ctx.from.id.toString();

    if (text === '/answer') {
      await this.menuService.safeDeleteMessage(ctx);
      return this.getResult(ctx);
    }
    if (text === '/version' || text === '/v') {
      await SafeTelegramHelper.safeSendMessage(ctx, 'v1.01');
      return;
    }
    if (text === '/cheat') {
      await this.menuService.safeDeleteMessage(ctx);
      return this.demoResult(ctx);
    }
    if (text === '/support') {
      await SafeTelegramHelper.safeSendMessage(
        ctx,
        `${process.env.SUPPORT_ID} جهت پشتیبانی به این ایدی پیام بدین`
      );
      return;
    }
    if (text === '/dev_stats') {
      await this.showDevStats(ctx);
      return;
    }

    const state = this.testService.getUserState(telegramId);
    if (!state?.waitingForAnswer || state.isProcessing) return;

    const { testId, questionIndex } = state;
    const updatedTest = await this.testService.updateTestAnswer(testId, questionIndex, text);
    if (!updatedTest) return;

    if (questionIndex + 1 >= QUESTIONS.length) {
      state.isProcessing = true;
      await this.testService.completeTest(ctx, testId);
      this.testService.deleteUserState(telegramId);
    } else {
      state.questionIndex = questionIndex + 1;
      await this.testService.sendQuestion(ctx, questionIndex + 1);
    }
  }

  async forgive(ctx: Context) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    await this.menuService.safeDeleteMessage(ctx);

    await SafeTelegramHelper.safeSendVideo(
      ctx,
      process.env.VIDEO_FORGIVE || '',
      {
        caption: FORGIVE_CAPTION,
        reply_markup: this.menuService.createBackButton().reply_markup,
        protect_content: true
      }
    );
  }


  async effects(ctx: Context) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    await this.menuService.safeDeleteMessage(ctx);
    await SafeTelegramHelper.safeSendVideo(
      ctx,
      process.env.VIDEO_EFFECTS || '',
      {
        caption: EFFECTS_CAPTION,
        reply_markup: this.menuService.createBackButton().reply_markup,
        protect_content: true
      }
    );
  }

  async peterson(ctx: Context) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    await this.menuService.safeDeleteMessage(ctx);
    await SafeTelegramHelper.safeSendMessage(
      ctx,
      WHO_IS_JORDAN,
      {
        reply_markup: this.menuService.createBackButton().reply_markup,
        protect_content: true
      }
    );
  }


  async back(ctx: Context) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    await this.menuService.safeDeleteMessage(ctx);
    await this.menuService.sendMainMenu(ctx);
  }


  async startTest(ctx: Context) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    await this.menuService.safeDeleteMessage(ctx);
    await SafeTelegramHelper.safeSendMessage(
      ctx,
      DO_YOU_HAVE_COURAGE,
      {
        reply_markup: Markup.inlineKeyboard([
          [Markup.button.callback('شهامتش رو دارم', 'confirm_test')],
          [Markup.button.callback('منصرف شدم', 'back')],
        ]).reply_markup,
        protect_content: true
      }
    );
  }

  async confirmTest(ctx: Context) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    if (!ctx.from) return;

    await this.menuService.safeDeleteMessage(ctx);
    const user = await this.userService.findByTelegramId(ctx.from.id.toString());
    if (!user) return;

    const test = await this.testService.createTest(user.id);
    this.testService.setUserState(ctx.from.id.toString(), {
      testId: test.id,
      questionIndex: 0,
      waitingForAnswer: true,
    });

    await this.testService.sendQuestion(ctx, 0);
  }

  async getResult(ctx: Context) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    await this.menuService.safeDeleteMessage(ctx);
    await this.showTestResult(ctx);
  }

  async demoResult(ctx: Context) {
    if (!ctx.from) return;
    await this.menuService.safeDeleteMessage(ctx);
    await this.showTestResult(ctx, true);
  }

async upgradePremium(ctx: Context) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    
    const tomanPrice = Number(process.env.TOMAN_PRICE || 333000).toLocaleString('fa-IR');
    const usdPrice = process.env.USD_PRICE || '4';
    
    // const message = `⭐ ارتقا به پرمیوم\n\n• تحلیل کامل و تخصصی\n\n💰 قیمت: ${tomanPrice} تومان یا ${usdPrice} دلار\n`;
    const message = `⭐ ارتقا به پرمیوم\n\n• تحلیل کامل و تخصصی\n\n💰 قیمت: ${tomanPrice} تومان  \n`;
    
    const keyboard = this.paymentService.createUpgradeKeyboard();

    const edited = await SafeTelegramHelper.safeEditMessage(ctx, message, keyboard);
    if (!edited) {
      await this.menuService.safeDeleteMessage(ctx);
      await SafeTelegramHelper.safeSendMessage(ctx, message, { ...keyboard, protect_content: true });
    }
}

  async payCrypto(ctx: Context) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    if (!ctx.from) return;

    const user = await this.userService.findByTelegramId(ctx.from.id.toString());
    if (!user) return;

    if (user.isPremium) {
      const message = 'شما قبلاً کاربر پرمیوم هستید! 👑';
      const edited = await SafeTelegramHelper.safeEditMessage(ctx, message);
      if (!edited) {
        await SafeTelegramHelper.safeSendMessage(ctx, message, { protect_content: true });
      }
      return;
    }

    try {
      const { paymentUrl, orderId } = await this.paymentService.createCryptoPayment(user.id);
      const message = '🪙 برای ارتقا به پرمیوم با کریپتو روی لینک زیر کلیک کنید:';
      const keyboard = this.paymentService.createCryptoPaymentKeyboard(paymentUrl, orderId);

      const edited = await SafeTelegramHelper.safeEditMessage(ctx, message, keyboard);
      if (!edited) {
        await SafeTelegramHelper.safeSendMessage(ctx, message, { ...keyboard, protect_content: true });
      }
    } catch (error) {
      this.logger.error('Error creating crypto payment:', error);
      const errorMessage = '❌ خطا در ایجاد لینک پرداخت. لطفا دوباره تلاش کنید.';
      const edited = await SafeTelegramHelper.safeEditMessage(ctx, errorMessage);
      if (!edited) {
        await SafeTelegramHelper.safeSendMessage(ctx, errorMessage, { protect_content: true });
      }
    }
  }

  async payRial(ctx: Context) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    if (!ctx.from) return;

    const user = await this.userService.findByTelegramId(ctx.from.id.toString());
    if (!user) return;

    if (user.isPremium) {
      const message = 'شما قبلاً کاربر پرمیوم هستید! 👑';
      const edited = await SafeTelegramHelper.safeEditMessage(ctx, message);
      if (!edited) {
        await SafeTelegramHelper.safeSendMessage(ctx, message, { protect_content: true });
      }
      return;
    }

    try {
      const { paymentUrl } = await this.paymentService.createRialPayment(user.id);
      const message = '💳 برای ارتقا به پرمیوم با پرداخت ریالی روی لینک زیر کلیک کنید:';
      const keyboard = this.paymentService.createRialPaymentKeyboard(paymentUrl);

      const edited = await SafeTelegramHelper.safeEditMessage(ctx, message, keyboard);
      if (!edited) {
        await SafeTelegramHelper.safeSendMessage(ctx, message, { ...keyboard, protect_content: true });
      }
    } catch (error) {
      this.logger.error('Error creating rial payment:', error);
      const errorMessage = '❌ خطا در ایجاد لینک پرداخت. لطفا دوباره تلاش کنید.';
      const edited = await SafeTelegramHelper.safeEditMessage(ctx, errorMessage);
      if (!edited) {
        await SafeTelegramHelper.safeSendMessage(ctx, errorMessage, { protect_content: true });
      }
    }
  }

  async checkPayment(ctx: CallbackContext) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    if (!ctx.match || !ctx.from) return;

    const orderId = ctx.match[1];
    const payment = await this.paymentService.getPaymentByOrderId(orderId);
    if (!payment) return;

    const user = await this.userService.findByTelegramId(ctx.from.id.toString());
    if (!user) return;

    if (payment.status === 'confirmed' || payment.status === 'finished') {
      if (user.isPremium) {
        const message = '✅ پرداخت تایید شد! شما اکنون کاربر پرمیوم هستید 👑';
        const edited = await SafeTelegramHelper.safeEditMessage(ctx, message);
        if (!edited) {
          await SafeTelegramHelper.safeSendMessage(ctx, message, { protect_content: true });
        }
        await this.menuService.sendMainMenu(ctx);
      } else {
        const message = '⏳ پرداخت در حال پردازش است...';
        const keyboard = Markup.inlineKeyboard([[Markup.button.callback('🔙 بازگشت', 'back')]]);
        const edited = await SafeTelegramHelper.safeEditMessage(ctx, message, keyboard);
        if (!edited) {
          await SafeTelegramHelper.safeSendMessage(ctx, message, { ...keyboard, protect_content: true });
        }
      }
    } else {
      const message = `وضعیت پرداخت: ${payment.status === 'confirmed' ? '✅ تایید شده' : '⏳ در انتظار تایید'}`;
      const keyboard = Markup.inlineKeyboard([[Markup.button.callback('🔙 بازگشت', 'back')]]);
      const edited = await SafeTelegramHelper.safeEditMessage(ctx, message, keyboard);
      if (!edited) {
        await SafeTelegramHelper.safeSendMessage(ctx, message, keyboard);
      }
    }
  }
  async editQuestion(ctx: CallbackContext) {
    await SafeTelegramHelper.safeAnswerCbQuery(ctx);
    if (!ctx.match || !ctx.from) return;

    const questionIndex = parseInt(ctx.match[1]);
    const telegramId = ctx.from.id.toString();
    const state = this.testService.getUserState(telegramId);

    if (!state) return;

    state.questionIndex = questionIndex;
    state.waitingForAnswer = true;

    await this.menuService.safeDeleteMessage(ctx);
    await this.testService.sendQuestion(ctx, questionIndex);
  }

  private async showTestResult(ctx: Context, isDemo: boolean = false) {
    if (!ctx.from) return;

    try {
      const user = await this.userService.findByTelegramId(ctx.from.id.toString());
      if (!user || !user.tests[0]) {
        await SafeTelegramHelper.safeSendMessage(ctx, 'شما هنوز تستی انجام نداده‌اید.');
        return;
      }

      const test = user.tests[0];

      if (user.isPremium || isDemo) {
        if (!test.result) {
          await ctx.sendChatAction('typing').catch(() => { });
          const processingMessage = await SafeTelegramHelper.safeSendMessage(ctx, '🧠 در حال تحلیل پاسخ‌های شما...');

          const typingInterval = setInterval(() => {
            ctx.sendChatAction('typing').catch(() => { });
          }, 3000);

          try {
            const result = await this.aiService.generateResult(test);
            await this.testService.updateTestResult(test.id, result);
            test.result = result;

            clearInterval(typingInterval);
            if (processingMessage) {
              await SafeTelegramHelper.safeDeleteMessage(ctx);
            }
          } catch (error) {
            this.logger.error('Error generating AI result:', error);
            clearInterval(typingInterval);
            if (processingMessage) {
              await SafeTelegramHelper.safeDeleteMessage(ctx);
            }
            await SafeTelegramHelper.safeSendMessage(ctx, '❌ خطا در پردازش نتیجه. لطفا دوباره تلاش کنید.');
            return;
          }
        }

        const chunks = this.testService.splitMessage(test.result);
        for (const chunk of chunks) {
          const escapedChunk = chunk.replace(/[_*[\]()~`>#+\-=|{}.!\\]/g, '\\$&');
          await SafeTelegramHelper.safeSendMessage(ctx, escapedChunk, {
            protect_content: !isDemo,
            parse_mode: "MarkdownV2"
          });
        }

        if (isDemo) {
          await SafeTelegramHelper.safeSendMessage(
            ctx,
            'این ویژگی رایگان جهت تست بود',
            Markup.inlineKeyboard([[Markup.button.callback('🔙 بازگشت', 'back')]])
          );
        } else {
          await SafeTelegramHelper.safeSendMessage(
            ctx,
            'می‌خواهید تست جدید انجام دهید؟',
            Markup.inlineKeyboard([
              [Markup.button.callback('🔄 تست مجدد', 'start_test')],
              [Markup.button.callback('🔙 بازگشت', 'back')],
            ])
          );
        }
      } else {
const message = '🔒 برای مشاهده نتایج کامل تست شما:\n\n' +
                 '💡 این تست نیاز به اشتراک پرمیوم دارد\n' +
                 '✨ با ارتقا به پرمیوم، تحلیل جامع و تخصصی دریافت کنید\n\n';

        await SafeTelegramHelper.safeSendMessage(ctx, message, {
          reply_markup: Markup.inlineKeyboard([
            [Markup.button.callback('💎 خرید اشتراک پرمیوم', 'upgrade_premium')],
            [Markup.button.callback('🔙 بازگشت به منو', 'back')],
          ]).reply_markup,
          protect_content: true
        });
      }
    } catch (error) {
      this.logger.error('Error showing test result:', error);
      await SafeTelegramHelper.safeSendMessage(ctx, '❌ خطایی در نمایش نتیجه رخ داد. لطفا دوباره تلاش کنید.');
    }
  }

  private async showDevStats(ctx: Context) {
    try {
      const totalUsers = await this.prisma.user.count();
      const premiumUsers = await this.prisma.user.count({
        where: { isPremium: true }
      });

      const usersWithTests = await this.prisma.user.count({
        where: {
          tests: {
            some: {
              answers: {
                not: {}
              }
            }
          }
        }
      });

      const usersWithPayments = await this.prisma.user.count({
        where: {
          payments: {
            some: {}
          }
        }
      });

      const statsMessage = `📊 آمار توسعه دهنده:\n\n` +
        `👥 کل کاربران: ${totalUsers}\n\n` +
        `💎 کاربران خرید کرده: ${premiumUsers}\n\n` +
        `📝 کاربرانی که آزمون دادن: ${usersWithTests}\n\n` +
        `💳 کاربرانی که بعد اینکه فهمیدن رایگان نیست روی ارتقا به پرمیوم کلیک کردن: ${usersWithPayments}`;

      await SafeTelegramHelper.safeSendMessage(ctx, statsMessage);
    } catch (error) {
      this.logger.error('Error fetching dev stats:', error);
      await SafeTelegramHelper.safeSendMessage(ctx, '❌ خطا در دریافت آمار');
    }
  }
}
