part of '../di_providers.dart';

final scriptWidgetRuntimeProvider = Provider<ScriptWidgetRuntime>((ref) {
  final runtime = QuickJsWidgetRuntime();
  ref.onDispose(() {
    unawaited(runtime.dispose());
  });
  return runtime;
});

final scriptWidgetRemoteGatewayProvider = Provider<ScriptWidgetRemoteGateway>(
  (ref) => ScriptWidgetRemoteClient(),
);

final scriptWidgetRepositoryProvider = FutureProvider<ScriptWidgetRepository>((
  ref,
) async {
  final appDataDirectory = await ref.watch(appDataDirProvider.future);
  return JsonScriptWidgetRepository(
    file: File('${appDataDirectory.path}/script_widgets.json'),
  );
});

final scriptWidgetServiceProvider = FutureProvider<ScriptWidgetService>((
  ref,
) async {
  final repository = await ref.watch(scriptWidgetRepositoryProvider.future);
  return ScriptWidgetService(
    repository: repository,
    remoteGateway: ref.watch(scriptWidgetRemoteGatewayProvider),
    runtime: ref.watch(scriptWidgetRuntimeProvider),
    danmakuSourcesStore: ref.watch(danmakuSourcesStoreProvider),
    onDanmakuSourcesChanged: () async {
      ref.invalidate(danmakuSettingsProvider);
    },
  );
});

final installedScriptWidgetsProvider =
    FutureProvider<List<InstalledScriptWidget>>((ref) async {
      final service = await ref.watch(scriptWidgetServiceProvider.future);
      return service.listWidgets();
    });

final scriptWidgetSubscriptionsProvider =
    FutureProvider<List<ScriptWidgetSubscription>>((ref) async {
      final service = await ref.watch(scriptWidgetServiceProvider.future);
      return service.listSubscriptions();
    });

final installedScriptWidgetProvider =
    FutureProvider.family<InstalledScriptWidget, String>((ref, widgetId) async {
      final service = await ref.watch(scriptWidgetServiceProvider.future);
      return service.requireWidget(widgetId);
    });

typedef ScriptWidgetModulePreviewKey = ({String widgetId, String moduleKey});

final scriptWidgetModulePreviewProvider =
    FutureProvider.family<
      List<ScriptWidgetContentSection>,
      ScriptWidgetModulePreviewKey
    >((ref, previewKey) async {
      final service = await ref.watch(scriptWidgetServiceProvider.future);
      final installedWidget = await service.requireWidget(previewKey.widgetId);
      final module = installedWidget.manifest.modules
          .where(
            (candidate) =>
                (candidate.id.isEmpty
                    ? candidate.functionName
                    : candidate.id) ==
                previewKey.moduleKey,
          )
          .firstOrNull;
      if (module == null) {
        throw StateError('未找到模块功能：${previewKey.moduleKey}');
      }

      return service.loadModuleSections(
        previewKey.widgetId,
        module,
        const <String, Object?>{},
      );
    });
