generateCards method

Future<void> generateCards({
  1. required String sessionId,
  2. required String sessionType,
  3. String? topicId,
  4. String? topicTitle,
  5. int? durationMinutes,
  6. ReflectionData? reflectionData,
})

Implementation

Future<void> generateCards({
  required String sessionId,
  required String sessionType,
  String? topicId,
  String? topicTitle,
  int? durationMinutes,
  ReflectionData? reflectionData,
}) async {
  state = const CardGenerationState(isGenerating: true);

  try {
    final supabase = ref.read(supabaseDatasourceProvider);

    // Fetch conversation messages for context
    final messages = await supabase.getMessages(sessionId);
    final conversationSummary = messages
        .map((m) => '${m['role']}: ${m['content']}')
        .join('\n');

    // Fetch content chunks if topic is available
    String chunkContext = '';
    if (topicId != null) {
      final chunks = await supabase.getChunksForTopic(topicId);
      if (chunks.isNotEmpty) {
        final buf = StringBuffer();
        for (final c in chunks) {
          if (buf.length + c.content.length > 30000) break;
          if (buf.isNotEmpty) buf.write('\n\n');
          buf.write(c.content);
        }
        chunkContext = buf.toString();
      }
    }

    final userMessage = _buildUserMessage(
      topicTitle: topicTitle ?? 'Unknown',
      topicId: topicId ?? '',
      sessionType: sessionType,
      durationMinutes: durationMinutes,
      reflectionData: reflectionData,
      conversationSummary: conversationSummary,
      chunkContext: chunkContext,
    );

    // Resolve proxy/direct AI datasource.
    final useProxy = ref.read(useAiProxyProvider).valueOrNull ?? false;
    final backendProvider =
        ref.read(selectedAiProviderProvider).valueOrNull ?? AiProvider.claude;

    final AiDatasource ai;
    if (useProxy) {
      final supabaseUrl = Supabase.instance.client.rest.url.replaceAll(
        '/rest/v1',
        '',
      );
      ai = ProxyAiDatasource(
        Dio(),
        backendProvider: backendProvider,
        functionUrl: '$supabaseUrl/functions/v1/ai-proxy',
        headersBuilder: () {
          final session = Supabase.instance.client.auth.currentSession;
          return {
            'Authorization': 'Bearer ${session?.accessToken ?? ''}',
            'Content-Type': 'application/json',
            'apikey': Supabase.instance.client.rest.headers['apikey'] ?? '',
          };
        },
        credentialProvider: () => getProviderCredential(ref, backendProvider),
        topicId: topicId,
        isCardGeneration: true,
      );
    } else {
      ai = ref.read(aiDatasourceProvider);
    }

    final systemPrompt = useProxy ? '' : _buildSystemPrompt();
    final response = await ai.sendMessage(
      systemPrompt: systemPrompt,
      messages: [
        {'role': 'user', 'content': userMessage},
      ],
      maxTokens: 4096,
    );

    final proposals = _parseResponse(response, topicId ?? '');
    state = CardGenerationState(proposals: proposals);
  } catch (e) {
    state = CardGenerationState(
      error: userFriendlyMessage(e, logName: 'CardGeneration'),
    );
  }
}