import 'package:flutter_test/flutter_test.dart';
import '../lib/core/services/vector_service.dart';
import '../lib/core/services/rag_service.dart';
import '../lib/core/services/rag_ai_service.dart';
import '../lib/core/models/content_chunk.dart';

void main() {
  group('AI Tutor RAG Services Tests', () {
    test('VectorService - Generate Embedding', () async {
      print('🔍 Testing VectorService embedding generation...');
      
      const testText = 'A fotossíntese é o processo pelo qual as plantas convertem luz solar em energia química.';
      
      final embedding = VectorService.generateEmbedding(testText);
      
      // Verify embedding properties
      expect(embedding.length, equals(384)); // Standard embedding size
      expect(embedding.every((x) => x >= -1.0 && x <= 1.0), isTrue); // Normalized
      
      print('✅ Embedding generated successfully: ${embedding.length} dimensions');
    });

    test('VectorService - Cosine Similarity', () {
      print('🔍 Testing cosine similarity calculation...');
      
      const text1 = 'A fotossíntese é importante para as plantas.';
      const text2 = 'As plantas usam fotossíntese para produzir energia.';
      const text3 = 'Os animais precisam de comida para sobreviver.';
      
      final embedding1 = VectorService.generateEmbedding(text1);
      final embedding2 = VectorService.generateEmbedding(text2);
      final embedding3 = VectorService.generateEmbedding(text3);
      
      final similarity12 = VectorService.cosineSimilarity(embedding1, embedding2);
      final similarity13 = VectorService.cosineSimilarity(embedding1, embedding3);
      
      // Similar texts should have higher similarity
      expect(similarity12, greaterThan(similarity13));
      expect(similarity12, greaterThan(0.5)); // Should be reasonably similar
      expect(similarity13, lessThan(0.3)); // Should be less similar
      
      print('✅ Cosine similarity working correctly');
      print('   Similar (fotossíntese): ${similarity12.toStringAsFixed(3)}');
      print('   Different (plantas vs animais): ${similarity13.toStringAsFixed(3)}');
    });

    test('VectorService - Search by Text', () async {
      print('🔍 Testing vector search by text...');
      
      // This would normally search the database, but we'll test the embedding part
      const query = 'O que é fotossíntese?';
      final results = await VectorService.searchByText(
        query: query,
        subject: 'Biologia',
        concept: 'Fotossíntese',
        grade: 10,
        k: 3,
      );
      
      // Results might be empty if no data in database, but the call should work
      expect(results, isA<List<ContentChunk>>());
      
      print('✅ Vector search completed');
      print('   Found ${results.length} results for: "$query"');
    });

    test('RAGAIService - Service Availability', () async {
      print('🔍 Testing Ollama service availability...');
      
      try {
        final isAvailable = await RAGAIService.isServiceAvailable();
        
        if (isAvailable) {
          print('✅ Ollama service is available');
          
          // Test model info
          final modelInfo = await RAGAIService.getModelInfo();
          if (modelInfo != null) {
            print('   Model: ${modelInfo['name']}');
            print('   Size: ${modelInfo['size']}');
            print('   Modified: ${modelInfo['modified']}');
          }
          
          // Test simple query
          final testResponse = await RAGAIService.testService();
          print('   Test response: "$testResponse"');
        } else {
          print('⚠️  Ollama service is not available');
          print('   This is expected if the service is not running');
        }
      } catch (e) {
        print('❌ Error testing service availability: $e');
      }
    });

    test('RAG Pipeline - End-to-End Simulation', () async {
      print('🔍 Testing complete RAG pipeline simulation...');
      
      try {
        const userQuery = 'O que é fotossíntese?';
        const mode = TutorMode.explanation;
        
        // Step 1: Test query embedding
        final queryEmbedding = VectorService.generateEmbedding(userQuery);
        print('   ✅ Query embedding generated (${queryEmbedding.length} dims)');
        
        // Step 2: Test vector search
        final searchResults = await VectorService.searchSimilar(
          queryEmbedding: queryEmbedding,
          subject: 'Biologia',
          concept: 'Fotossíntese',
          grade: 10,
          k: 3,
        );
        print('   ✅ Vector search completed (${searchResults.length} results)');
        
        // Step 3: Test RAG processing (with mock data if no real data)
        if (searchResults.isEmpty) {
          print('   ⚠️  No content found, creating mock data for testing...');
          
          // Create mock chunks for testing
          final mockChunks = [
            ContentChunk(
              id: 'mock1',
              contentId: 'mock_content1',
              text: 'A fotossíntese é o processo pelo qual as plantas convertem luz solar em energia química.',
              subject: 'Biologia',
              concept: 'Fotossíntese',
              unit: 'Processos Biológicos',
              difficulty: 0.6,
              grade: 10,
              embedding: VectorService.generateEmbedding('fotossíntese plantas energia'),
              sourceDocument: 'Biologia Manual.pdf',
              metadata: {'page': 45},
              createdAt: DateTime.now(),
            ),
          ];
          
          // Test RAG processing with mock data
          final ragResponse = await RAGService.processQuery(
            userQuery: userQuery,
            mode: mode,
            subject: 'Biologia',
            concept: 'Fotossíntese',
            grade: 10,
            maxSources: 3,
          );
          
          print('   ✅ RAG processing completed');
          print('   Answer: "${ragResponse.answer.substring(0, 100)}..."');
          print('   Confidence: ${ragResponse.confidence.toStringAsFixed(2)}');
          print('   Sources: ${ragResponse.sources.length}');
          print('   Related concepts: ${ragResponse.relatedConcepts.join(', ')}');
          
        } else {
          print('   ✅ Found real content for RAG processing');
          
          // Test with real data
          final ragResponse = await RAGService.processQuery(
            userQuery: userQuery,
            mode: mode,
            subject: 'Biologia',
            concept: 'Fotossíntese',
            grade: 10,
            maxSources: 3,
          );
          
          print('   ✅ RAG processing with real data completed');
          print('   Answer: "${ragResponse.answer.substring(0, 100)}..."');
          print('   Confidence: ${ragResponse.confidence.toStringAsFixed(2)}');
          print('   Sources: ${ragResponse.sources.length}');
        }
        
        print('✅ RAG pipeline simulation completed successfully');
        
      } catch (e) {
        print('❌ Error in RAG pipeline: $e');
      }
    });

    test('VectorService - Batch Embeddings', () async {
      print('🔍 Testing batch embedding generation...');
      
      final texts = [
        'A fotossíntese converte luz solar em energia.',
        'As plantas usam clorofila para capturar luz.',
        'O oxigénio é um subproduto da fotossíntese.',
      ];
      
      final embeddings = await VectorService.batchGenerateEmbeddings(texts);
      
      expect(embeddings.length, equals(texts.length));
      expect(embeddings.every((e) => e.length == 384), isTrue);
      
      print('✅ Batch embeddings generated successfully');
      print('   Generated ${embeddings.length} embeddings');
      
      // Test similarities between batch embeddings
      for (int i = 0; i < embeddings.length; i++) {
        for (int j = i + 1; j < embeddings.length; j++) {
          final similarity = VectorService.cosineSimilarity(embeddings[i], embeddings[j]);
          print('   Similarity ${i+1}-${j+1}: ${similarity.toStringAsFixed(3)}');
        }
      }
    });

    test('VectorService - Statistics', () async {
      print('🔍 Testing vector statistics...');
      
      final stats = await VectorService.getVectorStats();
      
      expect(stats, isA<Map<String, dynamic>>());
      expect(stats.containsKey('totalChunks'), isTrue);
      expect(stats.containsKey('embeddingDimension'), isTrue);
      expect(stats['embeddingDimension'], equals(384));
      
      print('✅ Vector statistics retrieved');
      print('   Total chunks: ${stats['totalChunks']}');
      print('   Embedding dimension: ${stats['embeddingDimension']}');
      print('   Subjects: ${stats['subjects'].keys.length}');
      print('   Concepts: ${stats['concepts'].keys.length}');
    });
  });
}
