// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@JS()
library;

import 'dart:async';
// TODO: https://github.com/dart-lang/webdev/issues/2508
// ignore: deprecated_member_use
import 'dart:js_util';

// TODO: https://github.com/dart-lang/webdev/issues/2508
// ignore: deprecated_member_use
import 'package:js/js.dart';

import 'chrome_api.dart';

Future<Tab> createTab(String url, {bool inNewWindow = false}) {
  final completer = Completer<Tab>();
  if (inNewWindow) {
    chrome.windows.create(
      WindowInfo(focused: true, url: url),
      allowInterop((WindowObj windowObj) {
        completer.complete(windowObj.tabs.first);
      }),
    );
  } else {
    chrome.tabs.create(
      TabInfo(active: true, url: url),
      allowInterop(completer.complete),
    );
  }
  return completer.future;
}

Future<Tab?> getTab(int tabId) {
  final completer = Completer<Tab?>();
  chrome.tabs.get(tabId, allowInterop(completer.complete));
  return completer.future;
}

Future<Tab?> get activeTab {
  final completer = Completer<Tab?>();
  final query = QueryInfo(active: true, currentWindow: true);
  chrome.tabs.query(
    query,
    allowInterop((List tabs) {
      if (tabs.isNotEmpty) {
        completer.complete(tabs.first as Tab);
      } else {
        completer.complete(null);
      }
    }),
  );
  return completer.future;
}

Future<bool> removeTab(int tabId) {
  final completer = Completer<bool>();
  chrome.tabs.remove(
    tabId,
    allowInterop(() {
      completer.complete(true);
    }),
  );
  return completer.future;
}

void displayNotification(
  String message, {
  bool isError = false,
  Function? callback,
}) {
  chrome.notifications.create(
    // notificationId
    null,
    NotificationOptions(
      title: '${isError ? '[Error] ' : ''}Dart Debug Extension',
      message: message,
      iconUrl: isError
          ? 'static_assets/dart_warning.png'
          : 'static_assets/dart.png',
      type: 'basic',
    ),
    callback,
  );
}

void setExtensionIcon(IconInfo info) {
  if (isMV3) {
    _setExtensionIconMV3(
      info,
      // callback
      null,
    );
  } else {
    _setExtensionIconMV2(
      info,
      // callback
      null,
    );
  }
}

void setExtensionPopup(PopupDetails details) {
  if (isMV3) {
    _setExtensionPopupMV3(
      details,
      // callback
      null,
    );
  } else {
    _setExtensionPopupMV2(
      details,
      // callback
      null,
    );
  }
}

final bool isDevMode = () {
  final extensionManifest = chrome.runtime.getManifest();
  final extensionName = getProperty<String?>(extensionManifest, 'name') ?? '';
  return extensionName.contains('DEV');
}();

final bool isMV3 = () {
  final extensionManifest = chrome.runtime.getManifest();
  final manifestVersion =
      getProperty(extensionManifest, 'manifest_version') ?? 2;
  return manifestVersion == 3;
}();

String addQueryParameters(
  String uri, {
  required Map<String, String> queryParameters,
}) {
  final originalUri = Uri.parse(uri);
  final newUri = originalUri.replace(
    path: '', // Replace the /debugger path so that the inspector url works.
    queryParameters: {...originalUri.queryParameters, ...queryParameters},
  );
  return newUri.toString();
}

@JS('chrome.browserAction.setIcon')
external void _setExtensionIconMV2(IconInfo iconInfo, Function? callback);

@JS('chrome.action.setIcon')
external void _setExtensionIconMV3(IconInfo iconInfo, Function? callback);

@JS('chrome.browserAction.setPopup')
external void _setExtensionPopupMV2(PopupDetails details, Function? callback);

@JS('chrome.action.setPopup')
external void _setExtensionPopupMV3(PopupDetails details, Function? callback);

@JS()
@anonymous
class IconInfo {
  external String get path;
  external factory IconInfo({required String path});
}

@JS()
@anonymous
class PopupDetails {
  external int get tabId;
  external String get popup;
  external factory PopupDetails({required int tabId, required String popup});
}
