const MESSENGER_MINI_APP_PATH_PREFIX = 'path_';

function getBuffer() {
  return (globalThis as typeof globalThis & {
    Buffer?: {
      from(input: string | Uint8Array, encoding?: string): {
        toString(encoding?: string): string;
      };
    };
  }).Buffer;
}

function encodeUtf8(value: string) {
  if (typeof TextEncoder !== 'undefined') {
    return new TextEncoder().encode(value);
  }

  const buffer = getBuffer();
  if (buffer) {
    return Uint8Array.from(buffer.from(value, 'utf8'));
  }

  return Uint8Array.from(value.split('').map((char) => char.charCodeAt(0)));
}

function decodeUtf8(bytes: Uint8Array) {
  if (typeof TextDecoder !== 'undefined') {
    return new TextDecoder().decode(bytes);
  }

  const buffer = getBuffer();
  if (buffer) {
    return buffer.from(bytes).toString('utf8');
  }

  return String.fromCharCode(...bytes);
}

function toBase64(bytes: Uint8Array) {
  const buffer = getBuffer();
  if (buffer) {
    return buffer.from(bytes).toString('base64');
  }

  let binary = '';
  for (const byte of bytes) {
    binary += String.fromCharCode(byte);
  }
  return btoa(binary);
}

function fromBase64(value: string) {
  const buffer = getBuffer();
  if (buffer) {
    return Uint8Array.from(buffer.from(value, 'base64'));
  }

  const binary = atob(value);
  return Uint8Array.from(binary, (char) => char.charCodeAt(0));
}

function normalizePath(value: string) {
  const normalizedPath = String(value || '').trim();
  return normalizedPath.startsWith('/') ? normalizedPath : '';
}

function toBase64Url(value: string) {
  return toBase64(encodeUtf8(value))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/g, '');
}

function fromBase64Url(value: string) {
  const normalizedValue = value.replace(/-/g, '+').replace(/_/g, '/');
  const padding = normalizedValue.length % 4 === 0 ? '' : '='.repeat(4 - (normalizedValue.length % 4));
  return decodeUtf8(fromBase64(`${normalizedValue}${padding}`));
}

function readWindowStartParam() {
  if (!import.meta.client) {
    return '';
  }

  const telegramStartParam = String(window.Telegram?.WebApp?.initDataUnsafe?.start_param || '').trim();
  if (telegramStartParam) {
    return telegramStartParam;
  }

  return String(window.WebApp?.initDataUnsafe?.start_param || '').trim();
}

export function encodeMessengerMiniAppPath(path: string) {
  const normalizedPath = normalizePath(path);
  if (!normalizedPath) {
    return '';
  }

  return `${MESSENGER_MINI_APP_PATH_PREFIX}${toBase64Url(normalizedPath)}`;
}

export function decodeMessengerMiniAppStartParam(startParam: string) {
  const normalizedStartParam = String(startParam || '').trim();
  if (!normalizedStartParam) {
    return '';
  }

  if (normalizedStartParam.startsWith('/')) {
    return normalizePath(normalizedStartParam);
  }

  if (!normalizedStartParam.startsWith(MESSENGER_MINI_APP_PATH_PREFIX)) {
    return '';
  }

  try {
    return normalizePath(fromBase64Url(normalizedStartParam.slice(MESSENGER_MINI_APP_PATH_PREFIX.length)));
  } catch {
    return '';
  }
}

export function readMessengerMiniAppStartPath() {
  return decodeMessengerMiniAppStartParam(readWindowStartParam());
}
