from django.test import TestCase
from django.urls import reverse
from rest_framework.test import APITestCase, APIClient
from rest_framework import status
from user.models import User
from course.models import Course
from unittest.mock import patch, MagicMock
import json

class GenerateCourseViewTest(APITestCase):
    def setUp(self):
        # Créer un utilisateur de test avec create_user
        self.user = User.objects.create_user(
            email='test@example.com',
            password='testpass123'
        )
        self.client = APIClient()
        self.client.force_authenticate(user=self.user)
        
        # URL pour la vue GenerateCourseView
        self.url = '/generate_course/'
        
        # Données de test pour un document
        self.test_document = {
            'pages': [
                {
                    'text': 'Ceci est un texte de test pour le cours.',
                    'images': []
                }
            ]
        }

    @patch('utils.token_management.has_tokens')
    def test_generate_course_without_documents(self, mock_has_tokens):
        """Test la génération de cours sans documents"""
        mock_has_tokens.return_value = True
        response = self.client.post(
            self.url,
            {
                'name': 'Test Course',
                'user': self.user.publicIdentifier
            },
            format='json'
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertIn('error', response.data)

    @patch('utils.token_management.has_tokens')
    @patch('utils.generate_course.getCourseV2')
    def test_generate_course_without_name(self, mock_get_course, mock_has_tokens):
        """Test la génération de cours sans nom"""
        mock_has_tokens.return_value = True
        mock_get_course.return_value = ('Titre généré', [{'ops': [{'insert': 'Test content'}]}], 0)
        
        response = self.client.post(
            self.url,
            {
                'documents': [self.test_document],
                'user': self.user.publicIdentifier
            },
            format='json'
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        # Vérifier que le cours a été créé avec le titre généré
        course = Course.objects.get(publicIdentifier=response.data['publicIdentifier'])
        self.assertEqual(course.name, 'Titre généré')

    @patch('utils.token_management.has_tokens')
    @patch('utils.generate_course.getCourseV2')
    def test_generate_course_success(self, mock_get_course, mock_has_tokens):
        """Test la génération réussie d'un cours"""
        mock_has_tokens.return_value = True
        mock_get_course.return_value = ('Test Course', [{'ops': [{'insert': 'Test content'}]}], 0)
        
        response = self.client.post(
            self.url,
            {
                'name': 'Test Course',
                'documents': [self.test_document],
                'user': self.user.publicIdentifier,
                'academicLevel': 'L1',
                'language': 'fr'
            },
            format='json'
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        # Vérifier que le cours a été créé
        course = Course.objects.get(publicIdentifier=response.data['publicIdentifier'])
        self.assertEqual(course.name, 'Test Course')
        self.assertEqual(course.user.publicIdentifier, self.user.publicIdentifier)
        self.assertEqual(course.academicLevel, 'L1')

    @patch('utils.token_management.has_tokens')
    @patch('utils.generate_course.getCourseV2')
    def test_generate_course_with_multiple_documents(self, mock_get_course, mock_has_tokens):
        """Test la génération de cours avec plusieurs documents"""
        mock_has_tokens.return_value = True
        mock_get_course.return_value = ('Test Course Multiple Docs', [{'ops': [{'insert': 'Test content with multiple docs'}]}], 0)
        
        documents = [
            {
                'pages': [
                    {'text': 'Document 1, page 1', 'images': []}
                ]
            },
            {
                'pages': [
                    {'text': 'Document 2, page 1', 'images': []}
                ]
            }
        ]
        
        response = self.client.post(
            self.url,
            {
                'name': 'Test Course Multiple Docs',
                'documents': documents,
                'user': self.user.publicIdentifier
            },
            format='json'
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        # Vérifier que le cours a été créé
        course = Course.objects.get(publicIdentifier=response.data['publicIdentifier'])
        self.assertEqual(course.name, 'Test Course Multiple Docs')
        self.assertTrue(len(course.content) > 0)

    @patch('utils.token_management.has_tokens')
    def test_generate_course_no_tokens(self, mock_has_tokens):
        """Test la génération de cours sans tokens disponibles"""
        # Définir les tokens de l'utilisateur à 100000
        self.user.tokens_used = 100000
        self.user.save()
        
        mock_has_tokens.return_value = False
        response = self.client.post(
            self.url,
            {
                'name': 'Test Course',
                'documents': [self.test_document],
                'user': self.user.publicIdentifier
            },
            format='json'
        )
        self.assertEqual(response.status_code, status.HTTP_402_PAYMENT_REQUIRED)
        self.assertIn('error', response.data)
