import { BOTFATHER_BOT_USERNAME, buildBotFatherWebAppUrl, isBotManageWebAppUrl } from './bot-father.constants';

export type TelegramMenuButtonDefault = { type: 'default' };
export type TelegramMenuButtonCommands = { type: 'commands' };
export type TelegramMenuButtonWebApp = {
  type: 'web_app';
  text: string;
  web_app: { url: string };
};

export type TelegramMenuButton =
  | TelegramMenuButtonDefault
  | TelegramMenuButtonCommands
  | TelegramMenuButtonWebApp;

export type ResolvedComposerMenuButton = {
  menuButton: TelegramMenuButtonWebApp | null;
  composerWebAppUrl?: string;
  buttonText?: string;
};

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

function coerceJsonValue(raw: unknown): unknown {
  if (typeof raw !== 'string') {
    return raw;
  }
  const trimmed = raw.trim();
  if (!trimmed) {
    return raw;
  }
  try {
    return JSON.parse(trimmed);
  } catch {
    return raw;
  }
}

function normalizeWebAppButton(value: Record<string, unknown>): TelegramMenuButtonWebApp | null {
  const text = typeof value.text === 'string' ? value.text.trim() : '';
  const webApp = isRecord(value.web_app) ? value.web_app : null;
  const url = typeof webApp?.url === 'string' ? webApp.url.trim() : '';
  if (!text || !url || !/^https?:\/\//i.test(url)) {
    return null;
  }
  return { type: 'web_app', text, web_app: { url } };
}

export function parseMenuButtonInput(raw: unknown): TelegramMenuButton | null | undefined {
  if (raw === undefined) {
    return undefined;
  }
  if (raw === null) {
    return null;
  }

  const coerced = coerceJsonValue(raw);
  if (typeof coerced === 'string') {
    const trimmed = coerced.trim();
    if (!trimmed) {
      return null;
    }
    if (/^https?:\/\//i.test(trimmed)) {
      return { type: 'web_app', text: 'App', web_app: { url: trimmed } };
    }
    const pipeParts = trimmed.split('|');
    if (pipeParts.length === 2 && /^https?:\/\//i.test(pipeParts[0]!.trim())) {
      return {
        type: 'web_app',
        text: pipeParts[1]!.trim() || 'App',
        web_app: { url: pipeParts[0]!.trim() }
      };
    }
    return null;
  }

  if (!isRecord(coerced)) {
    return null;
  }

  const type = typeof coerced.type === 'string' ? coerced.type.trim().toLowerCase() : '';
  if (!type || type === 'default') {
    return { type: 'default' };
  }
  if (type === 'commands') {
    return { type: 'commands' };
  }
  if (type === 'web_app') {
    return normalizeWebAppButton(coerced);
  }
  return null;
}

export function menuButtonToJson(menuButton: TelegramMenuButton | null | undefined): Record<string, unknown> | null {
  if (!menuButton || menuButton.type === 'default') {
    return null;
  }
  if (menuButton.type === 'commands') {
    return { type: 'commands' };
  }
  return {
    type: 'web_app',
    text: menuButton.text,
    web_app: { url: menuButton.web_app.url }
  };
}

export function extractWebAppUrl(menuButton: unknown): string | undefined {
  const parsed = parseMenuButtonInput(menuButton);
  if (!parsed || parsed.type !== 'web_app') {
    return undefined;
  }
  const url = parsed.web_app.url.trim();
  if (!url || isBotManageWebAppUrl(url)) {
    return undefined;
  }
  return url;
}

export function resolveComposerMenuButton(options: {
  chatOverride?: unknown;
  globalMenuButton?: unknown;
  bot: { isSystemBot: boolean; username: string; webAppUrl?: string | null };
}): ResolvedComposerMenuButton {
  const chatParsed = parseMenuButtonInput(options.chatOverride);
  if (chatParsed && chatParsed.type === 'web_app') {
    const url = extractWebAppUrl(chatParsed);
    if (url) {
      return { menuButton: chatParsed, composerWebAppUrl: url, buttonText: chatParsed.text };
    }
  }

  const globalParsed = parseMenuButtonInput(options.globalMenuButton);
  if (globalParsed && globalParsed.type === 'web_app') {
    const url = extractWebAppUrl(globalParsed);
    if (url) {
      return { menuButton: globalParsed, composerWebAppUrl: url, buttonText: globalParsed.text };
    }
  }

  if (options.bot.isSystemBot || options.bot.username === BOTFATHER_BOT_USERNAME) {
    const url = buildBotFatherWebAppUrl();
    return {
      menuButton: { type: 'web_app', text: 'BotFather', web_app: { url } },
      composerWebAppUrl: url,
      buttonText: 'BotFather'
    };
  }

  const legacyUrl = options.bot.webAppUrl?.trim();
  if (legacyUrl && !isBotManageWebAppUrl(legacyUrl)) {
    return {
      menuButton: { type: 'web_app', text: 'App', web_app: { url: legacyUrl } },
      composerWebAppUrl: legacyUrl,
      buttonText: 'App'
    };
  }

  return { menuButton: null };
}
