initChatController method

Future<void> initChatController()

Implementation

Future<void> initChatController() async {
  try {
    // Show cached assistant immediately so app bar updates before any network call
    applyCachedAssistantIfAvailable();
    if (assistant.value?.id.trim().isNotEmpty == true) {
      _cachedAssistantId = assistant.value!.id;
    }
    initScrollControllers();
    initLanguage();
    hasApiError.value = false;

    // Always call single-assistant API when chat is opened (no dependency on AssistantsController).
    // This guarantees the assistant is loaded every time, including welcome for marketplace.
    if (assistantId.isNotEmpty) {
      isLoadingAssistant.value = true;
      try {
        final Assistant? a = await AssistantService.getAssistant(
          assistantId,
          isMarketplace,
        );
        if (a != null) {
          assistant.value = a;
          if (a.id.trim().isNotEmpty) {
            _cachedAssistantId = a.id;
          }
          _preserveInitialWelcomeIfAssistantEmpty();
          assistant.refresh();
          update();
          if (Get.isRegistered<PupauAssistantsController>()) {
            final assistantsController =
                Get.find<PupauAssistantsController>();
            final int idx = assistantsController.assistants.indexWhere(
              (x) => x.id == a.id && x.type == a.type,
            );
            if (idx >= 0) {
              assistantsController.assistants[idx] = a;
            } else {
              assistantsController.assistants.add(a);
            }
            assistantsController.assistants.refresh();
            assistantsController.update();
          }
        }
      } finally {
        isLoadingAssistant.value = false;
      }
    }

    // Only fetch again if we don't have the assistant yet (e.g. first fetch failed or was skipped)
    if (assistant.value == null) {
      await getAssistant();
    } else {
      await setAssistantSettings();
    }
    messageNotifier.setAssistantId(assistant.value?.id ?? "");
    if (assistant.value != null) {
      // Component successfully booted - config received and first remote call succeeded
      _updateBootStatus(BootState.ok);
      if (DeviceService.isTablet) setDefautMessageInputFieldHeight();
      if (hasApiError.value) {
        _updateBootStatus(BootState.error);
        _signalFirstInitComplete();
        return;
      }
      if (!isAnonymous &&
          pupauConfig?.conversationId != null &&
          pupauConfig?.conversationId?.trim() != "") {
        await loadConversation(pupauConfig?.conversationId ?? "");
      }

      _signalFirstInitComplete();
    } else {
      _updateBootStatus(BootState.error);
      _signalFirstInitComplete();
    }
  } catch (e, stackTrace) {
    _updateBootStatus(BootState.error);
    PupauEventService.instance.emitPupauEvent(
      PupauEvent(
        type: UpdateConversationType.error,
        payload: {
          "error": "Error initializing chat controller: ${e.toString()}",
          "errorType": e.runtimeType.toString(),
          "stackTrace": stackTrace.toString(),
          "assistantId": assistantId,
          "isMarketplace": isMarketplace,
          "isAnonymous": isAnonymous,
          "conversationId": pupauConfig?.conversationId,
          "configExists": pupauConfig != null,
          "assistantExists": assistant.value != null,
        },
      ),
    );
    _signalFirstInitComplete();
  }
}