import 'dart:js_interop';

import 'package:web/web.dart' as web;

const telegramLoginStorageKey = 'mapflow.telegramLoginData';
const mapflowSessionStorageKey = 'mapflow.sessionToken';

@JS('Telegram')
external _Telegram? get _telegram;

extension type _Telegram(JSObject _) implements JSObject {
  @JS('WebApp')
  external _TelegramWebApp? get webApp;
}

extension type _TelegramWebApp(JSObject _) implements JSObject {
  external JSString? get initData;
  external void ready();
  external void expand();
  external bool isVersionAtLeast(String version);
  external void disableVerticalSwipes();
}

@JS('JSON.stringify')
external JSString _jsonStringify(JSAny? value);

_TelegramWebApp? get _webApp => _telegram?.webApp;

String telegramInitData() => _webApp?.initData?.toDart ?? '';

String telegramLoginData() =>
    web.window.localStorage.getItem(telegramLoginStorageKey) ?? '';

String mapflowSessionToken() =>
    web.window.localStorage.getItem(mapflowSessionStorageKey) ?? '';

String telegramLoginTokenFromUrl() {
  final uri = Uri.parse(web.window.location.href);
  return uri.queryParameters['telegram_login'] ?? '';
}

void saveTelegramLoginData(JSAny? user) {
  final encoded = _jsonStringify(user).toDart;
  web.window.localStorage.setItem(telegramLoginStorageKey, encoded);
}

void saveMapflowSessionToken(String token) {
  web.window.localStorage.setItem(mapflowSessionStorageKey, token);
}

void clearMapflowSession() {
  web.window.localStorage.removeItem(mapflowSessionStorageKey);
  web.window.localStorage.removeItem(telegramLoginStorageKey);
}

void configureTelegramWebApp() {
  final webApp = _webApp;
  if (webApp == null) {
    return;
  }

  webApp.ready();
  webApp.expand();
  if (webApp.isVersionAtLeast('7.7')) {
    webApp.disableVerticalSwipes();
  }
}

void openExternalUrl(String url) {
  web.window.location.assign(url);
}

void reloadApp() {
  web.window.location.replace(_currentUrlWithoutTelegramLoginToken());
}

String _currentUrlWithoutTelegramLoginToken() {
  final uri = Uri.parse(web.window.location.href);
  final queryParameters = Map<String, String>.of(uri.queryParameters)
    ..remove('telegram_login');
  return uri
      .replace(
        queryParameters: queryParameters.isEmpty ? null : queryParameters,
      )
      .toString();
}
