import { Injectable, Logger } from '@nestjs/common';
import { BotApiService } from './bot-api.service';
import { PrismaService } from '../../infra/prisma.service';
import { BOTFATHER_BOT_USERNAME, GET_MY_ID_DISPLAY_NAME, buildBotCreateWebAppUrl, buildBotManageWebAppUrl } from './bot-father.constants';
import { BotFatherSeedService } from './bot-father-seed.service';
import { BotFatherService } from './bot-father.service';
import { deriveTelegramChatId } from './bot-token.util';

@Injectable()
export class BotFatherAssistantService {
  private readonly logger = new Logger(BotFatherAssistantService.name);

  constructor(
    private readonly seed: BotFatherSeedService,
    private readonly botFather: BotFatherService,
    private readonly botApi: BotApiService,
    private readonly prisma: PrismaService
  ) {}

  async handleUserMessage(systemBotId: string, senderUserId: string, text: string) {
    if (systemBotId === await this.seed.getGetMyIdBotId()) {
      await this.handleGetMyIdMessage(senderUserId, text, systemBotId);
      return;
    }

    const botId = await this.seed.getBotFatherBotId();
    const trimmed = text.trim();
    const lower = trimmed.toLowerCase();

    if (lower === '/start' || lower === '/help') {
      await this.botApi.sendInternalBotMessage(botId, senderUserId, this.buildWelcomeText(), {
        inline_keyboard: [
          [{ text: '🤖 Создать бота', web_app: { url: this.botCreateMiniAppUrl() } }],
          [{ text: '📋 Мои боты', callback_data: 'mybots' }]
        ]
      });
      return;
    }

    if (lower.startsWith('/newbot')) {
      await this.handleNewBotCommand(senderUserId, trimmed, botId);
      return;
    }

    if (lower === '/mybots') {
      await this.handleMyBots(senderUserId, botId);
      return;
    }

    const profileCommand = this.parseProfileCommand(trimmed);
    if (profileCommand) {
      await this.handleProfileCommand(senderUserId, botId, profileCommand);
      return;
    }

    await this.botApi.sendInternalBotMessage(
      botId,
      senderUserId,
      'Неизвестная команда. Отправьте /help для списка команд или /newbot Название username для создания бота.'
    );
  }

  async handleCallbackQuery(systemBotId: string, senderUserId: string, callbackData: string) {
    if (systemBotId === await this.seed.getGetMyIdBotId()) {
      await this.handleGetMyIdMessage(senderUserId, '/id', systemBotId);
      return;
    }

    const botId = await this.seed.getBotFatherBotId();
    if (callbackData === 'newbot_help' || callbackData === 'newbot') {
      await this.botApi.sendInternalBotMessage(
        botId,
        senderUserId,
        'Откройте Mini App «Создать бота» — пошаговый мастер как в Telegram BotFather.\n\nИли отправьте:\n/newbot Название username',
        { inline_keyboard: [[{ text: '🤖 Создать бота', web_app: { url: this.botCreateMiniAppUrl() } }]] }
      );
      return;
    }
    if (callbackData === 'mybots') {
      await this.handleMyBots(senderUserId, botId);
    }
  }

  private async handleMyBots(senderUserId: string, botId: string) {
    const { bots, total } = await this.botFather.listMyBots(senderUserId);
    const list = bots.length
      ? bots.map((bot) => `• @${bot.username} — ${bot.name}`).join('\n')
      : 'У вас пока нет ботов.';
    const keyboard = bots.map((bot) => [
      { text: `⚙️ ${bot.name}`, web_app: { url: buildBotManageWebAppUrl(bot.id) } }
    ]);
    await this.botApi.sendInternalBotMessage(
      botId,
      senderUserId,
      `Ваши боты (${total}):\n\n${list}${bots.length ? '\n\nНажмите кнопку ниже, чтобы открыть настройки бота.' : ''}`,
      keyboard.length ? { inline_keyboard: keyboard } : undefined
    );
  }

  private async handleGetMyIdMessage(senderUserId: string, text: string, botId: string) {
    const lower = text.trim().toLowerCase();
    if (lower === '/start' || lower === '/help') {
      await this.botApi.sendInternalBotMessage(
        botId,
        senderUserId,
        [
          `Привет! Я ${GET_MY_ID_DISPLAY_NAME}.`,
          '',
          'Отправьте /id, чтобы получить:',
          '• UUID пользователя',
          '• username',
          '• chat_id для этого бота',
          '• chat_id для ваших ботов, которые можно вставлять в Bot API-скрипты'
        ].join('\n'),
        { inline_keyboard: [[{ text: 'Показать мои ID', callback_data: 'get_my_id' }]] }
      );
      return;
    }

    await this.sendMyIdReport(senderUserId, botId);
  }

  private async sendMyIdReport(senderUserId: string, botId: string) {
    const user = await this.prisma.user.findUnique({
      where: { id: senderUserId },
      select: { id: true, displayName: true, username: true, email: true, phone: true }
    });
    if (!user) {
      await this.botApi.sendInternalBotMessage(botId, senderUserId, 'Пользователь не найден');
      return;
    }

    const ownBots = await this.prisma.bot.findMany({
      where: { ownerId: senderUserId, isActive: true },
      orderBy: { name: 'asc' },
      select: { id: true, name: true, username: true }
    });

    const currentChatId = deriveTelegramChatId(`${botId}:${senderUserId}`).toString();
    const botLines = ownBots.length
      ? ownBots.map((bot) => `• ${bot.name} (@${bot.username})\n  bot_id: ${bot.id}\n  chat_id: ${deriveTelegramChatId(`${bot.id}:${senderUserId}`).toString()}`)
      : ['У вас пока нет созданных ботов.'];

    await this.botApi.sendInternalBotMessage(
      botId,
      senderUserId,
      [
        'Ваши ID для интеграций:',
        '',
        `user_id: ${user.id}`,
        `name: ${user.displayName}`,
        `username: ${user.username ? `@${user.username}` : 'не указан'}`,
        `email: ${user.email ?? 'не указан'}`,
        `phone: ${user.phone ?? 'не указан'}`,
        '',
        `chat_id с ${GET_MY_ID_DISPLAY_NAME}: ${currentChatId}`,
        '',
        'chat_id для ваших ботов:',
        ...botLines,
        '',
        'Используйте нужный chat_id в методах sendMessage, editMessageText, pinChatMessage и getChat.'
      ].join('\n')
    );
  }

  private parseProfileCommand(text: string):
    | { kind: 'setdescription' | 'setabouttext' | 'setuserpic' | 'setmenubutton'; botUsername: string; value: string }
    | null {
    const match = text.match(/^\/(setdescription|setabouttext|setuserpic|setmenubutton)\s+@?(\S+)\s+([\s\S]+)$/i);
    if (!match) {
      return null;
    }
    return {
      kind: match[1]!.toLowerCase() as 'setdescription' | 'setabouttext' | 'setuserpic' | 'setmenubutton',
      botUsername: match[2]!,
      value: match[3]!.trim()
    };
  }

  private async handleProfileCommand(
    senderUserId: string,
    botId: string,
    command: { kind: 'setdescription' | 'setabouttext' | 'setuserpic' | 'setmenubutton'; botUsername: string; value: string }
  ) {
    try {
      if (command.kind === 'setdescription') {
        await this.botFather.updateBotProfileByOwner(senderUserId, command.botUsername, { description: command.value });
        await this.botApi.sendInternalBotMessage(
          botId,
          senderUserId,
          `✅ Описание бота @${command.botUsername.replace(/_bot$/i, '')}_bot обновлено.`
        );
        return;
      }

      if (command.kind === 'setabouttext') {
        await this.botFather.updateBotProfileByOwner(senderUserId, command.botUsername, { aboutText: command.value });
        await this.botApi.sendInternalBotMessage(
          botId,
          senderUserId,
          `✅ Краткое описание бота @${command.botUsername.replace(/_bot$/i, '')}_bot обновлено.`
        );
        return;
      }

      if (command.kind === 'setuserpic') {
        await this.botFather.updateBotProfileByOwner(senderUserId, command.botUsername, { botPicUrl: command.value });
        await this.botApi.sendInternalBotMessage(
          botId,
          senderUserId,
          `✅ Аватар бота @${command.botUsername.replace(/_bot$/i, '')}_bot обновлён.`
        );
        return;
      }

      await this.botFather.updateBotProfileByOwner(senderUserId, command.botUsername, { menuButton: command.value });
      await this.botApi.sendInternalBotMessage(
        botId,
        senderUserId,
        `✅ Глобальная кнопка меню бота @${command.botUsername.replace(/_bot$/i, '')}_bot обновлена.`
      );
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Не удалось обновить профиль бота';
      this.logger.warn(`BotFather profile command error for ${senderUserId}: ${message}`);
      await this.botApi.sendInternalBotMessage(botId, senderUserId, `❌ ${message}`);
    }
  }

  private botCreateMiniAppUrl() {
    return buildBotCreateWebAppUrl();
  }

  private async handleNewBotCommand(senderUserId: string, text: string, botId: string) {
    const parts = text.split(/\s+/);
    if (parts.length < 3) {
      await this.botApi.sendInternalBotMessage(
        botId,
        senderUserId,
        'Создайте бота через Mini App — это быстрее и удобнее, чем вводить команду вручную.',
        { inline_keyboard: [[{ text: '🤖 Создать бота', web_app: { url: this.botCreateMiniAppUrl() } }]] }
      );
      return;
    }

    const username = parts[parts.length - 1]!;
    const name = parts.slice(1, -1).join(' ').trim();
    if (!name) {
      await this.botApi.sendInternalBotMessage(botId, senderUserId, 'Укажите название бота перед username.');
      return;
    }

    try {
      const result = await this.botFather.createBot(senderUserId, name, username);
      await this.botApi.sendInternalBotMessage(
        botId,
        senderUserId,
        `✅ Бот @${result.bot.username} создан!\n\nСохраните токен — он больше не будет показан:\n${result.token}\n\nУправление: раздел «Боты» или REST /bots`
      );
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Не удалось создать бота';
      this.logger.warn(`BotFather createBot error for ${senderUserId}: ${message}`);
      await this.botApi.sendInternalBotMessage(botId, senderUserId, `❌ ${message}`);
    }
  }

  private buildWelcomeText() {
    return [
      `Привет! Я ${BOTFATHER_BOT_USERNAME.replace(/_bot$/, '')} — помогу создать Telegram-бота в Lendry ID.`,
      '',
      'Команды:',
      '/newbot — создать бота (Mini App или команда с названием и username)',
      '/mybots — список ваших ботов',
      '/setdescription username текст — описание перед /start',
      '/setabouttext username текст — краткое описание в профиле',
      '/setuserpic username URL — аватар бота',
      '/setmenubutton username JSON|URL — глобальная кнопка меню (Web App)',
      '/help — эта справка',
      '',
      'Username указывайте без суффикса _bot — он добавится автоматически.'
    ].join('\n');
  }
}
