<br />
<b>Warning</b>:  Undefined variable $auth in <b>/home/pevo0181/public_html/pia-soft.com/cleania/routes/index.php</b> on line <b>542</b><br />
<br />
<b>Warning</b>:  Trying to access array offset on value of type null in <b>/home/pevo0181/public_html/pia-soft.com/cleania/routes/index.php</b> on line <b>542</b><br />
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import JsonResponse
import os
from .models import Documents, Categories, Audios, Users,DocumentUsers
from django.conf import settings
from django.utils import timezone
from .utils_old import convert_document_to_audio
from .helpers import dd, dump
from django.contrib.auth import get_user_model
from django.db import transaction
import uuid
from django.contrib.auth import logout,authenticate, login
import re
import time


# Importer après les autres imports
try:
    from .utils import convert_document_to_audio, text_to_speech_stream, text_to_speech, clean_extracted_text
except ImportError as e:
    print(f"Erreur d'import utils: {e}")
    # Fonctions de secours
    def convert_document_to_audio(*args, **kwargs):
        raise Exception("Module de conversion non disponible")
    
    def extract_text_from_pdf(*args, **kwargs):
        return "Extraction de texte non disponible"

import threading

@login_required
def dashboard(request):
    """Vue du tableau de bord"""
    try:
        # Base queryset selon le rôle
        if request.user.role == 'admin':
            # Admin voit tout
            documents_qs = Documents.objects.all()
            audios_qs = Audios.objects.all()
            recent_documents = Documents.objects.select_related('category', 'user', 'sender').order_by('-created_at')[:5]
            
        elif request.user.role == 'agent':
            # Agent voit ses documents assignés
            documents_qs = Documents.objects.filter(user=request.user)
            audios_qs = Audios.objects.filter(document__user=request.user)
            recent_documents = Documents.objects.filter(user=request.user).select_related('category').order_by('-created_at')[:5]
            
        else:
            # Expéditeur voit ses documents envoyés
            documents_qs = Documents.objects.filter(sender=request.user)
            audios_qs = Audios.objects.filter(document__sender=request.user)
            recent_documents = Documents.objects.filter(sender=request.user).select_related('category').order_by('-created_at')[:5]
        
        # Statistiques
        documents_count = documents_qs.count()
        processed_count = documents_qs.filter(status='processed').count()
        pending_count = documents_qs.filter(status='pending').count()
        notified_count = documents_qs.filter(status='notified').count()
        audios_count = audios_qs.count()
        
        # Documents par catégorie (pour l'admin)
        documents_by_category = {}
        if request.user.role == 'admin':
            categories = Categories.objects.all()
            for category in categories:
                count = documents_qs.filter(category=category).count()
                documents_by_category[category.name] = count
        
    except Exception as e:
        print(f"Erreur dashboard: {e}")
        documents_count = processed_count = pending_count = notified_count = audios_count = 0
        recent_documents = []
        documents_by_category = {}
    
    # CORRECTION : Calculs des pourcentages
    conversion_rate = (processed_count / documents_count * 100) if documents_count > 0 else 0
    pending_rate = (pending_count / documents_count * 100) if documents_count > 0 else 0
    
    context = {
        'documents_count': documents_count,
        'processed_count': processed_count,
        'pending_count': pending_count,
        'notified_count': notified_count,
        'audios_count': audios_count,
        'recent_documents': recent_documents,
        'documents_by_category': documents_by_category,
        'conversion_rate': round(conversion_rate, 1),  # Pourcentage
        'pending_rate': round(pending_rate, 1),        # Pourcentage
        'user_role': request.user.role,
    }
    
    return render(request, 'documents/dashboard.html', context)

@login_required
@transaction.atomic
def document_upload_pdf(request):
    """Vue pour uploader un document avec création d'expéditeur"""
    categories = Categories.objects.all()
    User = get_user_model()
    
    if request.method == 'POST':
        try:
            # Récupérer les données du formulaire
            sender_name = request.POST.get('sender_name')
            sender_phone = request.POST.get('sender_phone')
            sender_email = request.POST.get('sender_email')
            sender_address = request.POST.get('sender_address')
            sender_occupation = request.POST.get('sender_occupation')
            sender_organization = request.POST.get('sender_organization')
            
            document_title = request.POST.get('document_title')
            category_id = request.POST.get('document_category')
            description = request.POST.get('document_description')
            pdf_file = request.FILES.get('pdf_file')
            
            # Validation des champs requis
            if not all([sender_name, sender_phone, document_title, category_id, pdf_file]):
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({
                        'success': False,
                        'message': 'Veuillez remplir tous les champs obligatoires.'
                    })
                else:
                    messages.error(request, 'Veuillez remplir tous les champs obligatoires.')
                    return render(request, 'documents/upload.html', {'categories': categories})
            
            # Vérifier le fichier PDF
            if not pdf_file.name.endswith('.pdf'):
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({
                        'success': False,
                        'message': 'Seuls les fichiers PDF sont acceptés.'
                    })
                else:
                    messages.error(request, 'Seuls les fichiers PDF sont acceptés.')
                    return render(request, 'documents/upload.html', {'categories': categories})
            
            # 1. CRÉER OU RÉCUPÉRER L'UTILISATEUR EXPÉDITEUR
            sender_user = None
            
            # Vérifier si l'expéditeur existe déjà par téléphone ou email
            if sender_phone:
                try:
                    sender_user = User.objects.get(phone=sender_phone)
                    # Mettre à jour les informations si l'utilisateur existe
                    if sender_email and not sender_user.email:
                        sender_user.email = sender_email
                    if sender_name:
                        sender_user.last_name = sender_name
                    if sender_address:
                        sender_user.address = sender_address
                    if sender_occupation:
                        sender_user.occupation = sender_occupation
                    if sender_organization:
                        sender_user.organization = sender_organization
                    sender_user.save()
                except User.DoesNotExist:
                    # Créer un nouvel utilisateur expéditeur
                    sender_user = User.objects.create(
                        name=sender_name,
                        phone=sender_phone,
                        email=sender_email,
                        address=sender_address,
                        occupation=sender_occupation,
                        organization=sender_organization,
                        last_login=timezone.now(),
                        is_active=True,
                        is_staff=False,
                        is_superuser=False,
                        updated_at=timezone.now(),
                        created_at=timezone.now()
                    )
                    # Définir un mot de passe par défaut (à changer plus tard)
                    sender_user.set_password('default_password_123')
                    sender_user.save()
            
            # 2. SAUVEGARDER LE FICHIER PDF
            upload_dir = os.path.join(settings.MEDIA_ROOT, 'documents')
            os.makedirs(upload_dir, exist_ok=True)
            
            # Générer un nom de fichier unique
            import uuid
            filename = f"{uuid.uuid4().hex[:10]}_{pdf_file.name}"
            file_path = os.path.join('documents', filename)
            full_path = os.path.join(settings.MEDIA_ROOT, file_path)
            
            with open(full_path, 'wb+') as destination:
                for chunk in pdf_file.chunks():
                    destination.write(chunk)
            
            # 3. EXTRAIRE LE TEXTE DU PDF
            from .utils import extract_text_from_pdf
            pdf_file.seek(0)  # Remettre le curseur au début
            text_content = extract_text_from_pdf(pdf_file)
            
            # 4. CRÉER LE DOCUMENT
            category = Categories.objects.get(id=category_id)
            
            document = Documents(
                title=document_title,
                description=description,
                file_path=file_path,
                text_content=text_content,
                category=category,
                sender=sender_user,  # L'expéditeur (peut être différent de l'utilisateur connecté)
                user=request.user,   # L'utilisateur qui upload (propriétaire du document)
                status='pending',
                created_at=timezone.now(),
                updated_at=timezone.now()
            )
            document.save()
            
            # 5. RÉPONSE SUCCÈS
            success_message = f'Document "{document_title}" uploadé avec succès! Expéditeur: {sender_name}'
            
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': True,
                    'message': success_message,
                    'document_id': document.id,
                    'sender_id': sender_user.id
                })
            else:
                messages.success(request, success_message)
                return redirect('document_list')
            
        except Exception as e:
            error_message = f'Erreur lors de l\'upload: {str(e)}'
            print(f"Upload error: {e}")  # Pour le debug
            
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': False,
                    'message': error_message
                })
            else:
                messages.error(request, error_message)
                return render(request, 'documents/upload.html', {'categories': categories})
    
    # GET request - afficher le formulaire
    return render(request, 'documents/upload.html', {'categories': categories})

@login_required
@transaction.atomic
def document_upload(request):
    """Vue pour uploader un document avec création d'expéditeur"""
    categories = Categories.objects.all()
    User = get_user_model()
    
    if request.method == 'POST':
        try:
            # Récupérer les données du formulaire
            sender_name = request.POST.get('sender_name')
            sender_phone = request.POST.get('sender_phone')
            sender_email = request.POST.get('sender_email')
            sender_address = request.POST.get('sender_address')
            sender_occupation = request.POST.get('sender_occupation')
            sender_organization = request.POST.get('sender_organization')
            
            document_title = request.POST.get('document_title')
            category_id = request.POST.get('document_category')
            description = request.POST.get('document_description')
            uploaded_file = request.FILES.get('pdf_file')
            
            # Validation des champs requis
            if not all([sender_name, sender_phone, document_title, category_id, uploaded_file]):
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({
                        'success': False,
                        'message': 'Veuillez remplir tous les champs obligatoires.'
                    })
                else:
                    messages.error(request, 'Veuillez remplir tous les champs obligatoires.')
                    return render(request, 'documents/upload.html', {'categories': categories})
            
            # Vérifier le format du fichier
            allowed_extensions = ['pdf', 'jpg', 'jpeg', 'png', 'docx', 'doc', 'bmp', 'tiff', 'tif']
            file_ext = uploaded_file.name.split('.')[-1].lower()
            
            if file_ext not in allowed_extensions:
                error_msg = f'Formats acceptés: {", ".join(allowed_extensions)}'
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({
                        'success': False,
                        'message': error_msg
                    })
                else:
                    messages.error(request, error_msg)
                    return render(request, 'documents/upload.html', {'categories': categories})
            
            # 1. CRÉER OU RÉCUPÉRER L'UTILISATEUR EXPÉDITEUR
            sender_user = None
            
            if sender_phone:
                try:
                    sender_user = User.objects.get(phone=sender_phone)
                    # Mettre à jour les informations si l'utilisateur existe
                    if sender_email and not sender_user.email:
                        sender_user.email = sender_email
                    if sender_name:
                        sender_user.name = sender_name
                    if sender_address:
                        sender_user.address = sender_address
                    if sender_occupation:
                        sender_user.occupation = sender_occupation
                    if sender_organization:
                        sender_user.organization = sender_organization
                    sender_user.save()
                except User.DoesNotExist:
                    # Créer un nouvel utilisateur expéditeur
                    sender_user = User.objects.create(
                        name=sender_name,
                        phone=sender_phone,
                        email=sender_email,
                        address=sender_address,
                        occupation=sender_occupation,
                        organization=sender_organization,
                        last_login=timezone.now(),
                        is_active=True,
                        is_staff=False,
                        is_superuser=False,
                        updated_at=timezone.now(),
                        created_at=timezone.now()
                    )
                    sender_user.set_password('1234567890')
                    sender_user.save()
            
            # 2. SAUVEGARDER LE FICHIER
            upload_dir = os.path.join(settings.MEDIA_ROOT, 'documents')
            os.makedirs(upload_dir, exist_ok=True)
            
            import uuid
            filename = f"{uuid.uuid4().hex[:50]}.{file_ext}"
            file_path = os.path.join('documents', filename)
            full_path = os.path.join(settings.MEDIA_ROOT, file_path)
            
            with open(full_path, 'wb+') as destination:
                for chunk in uploaded_file.chunks():
                    destination.write(chunk)
            
            # 3. EXTRAIRE LE TEXTE (gère automatiquement PDF, Image, Word) extract_text_from_file par defaut
            from .utils_old import extract_text_from_file
            uploaded_file.seek(0)  # Remettre le curseur au début
            
            print(f"📄 Extraction du texte depuis {uploaded_file.name}...")
            text_content = extract_text_from_file(uploaded_file, uploaded_file.name)
            text_content = clean_extracted_text(text_content)
            print(f"✅ Texte extrait: {len(text_content)} caractères")
            
            # Si peu de texte extrait, avertir (peut-être une image de mauvaise qualité)
            if len(text_content) < 10:
                print("⚠️ Très peu de texte extrait, vérifier la qualité du document")
            
            # 4. CRÉER LE DOCUMENT
            category = Categories.objects.get(id=category_id)
            
            document = Documents(
                title=document_title,
                description=description,
                file_path=file_path,
                text_content=text_content,
                category=category,
                sender=sender_user,
                user=request.user,
                status='pending',
                created_at=timezone.now(),
                updated_at=timezone.now()
            )
            document.save()
            
             # 2. ASSIGNER LE DOCUMENT À TOUS LES ADMINISTRATEURS
            admins = User.objects.filter(is_staff=True, is_active=True,role='admin')
            
            for admin in admins:
                # Créer une entrée dans document_users pour chaque admin
                DocumentUsers.objects.create(
                    document=document,
                    user=admin,
                    is_read=False,  # Pas encore lu
                    read_at=None
                )
            
            # 5. RÉPONSE SUCCÈS
            success_message = f'Document "{document_title}" uploadé avec succès! Expéditeur: {sender_name}'
            
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': True,
                    'message': success_message,
                    'document_id': document.id,
                    'sender_id': sender_user.id,
                    'text_length': len(text_content)
                })
            else:
                messages.success(request, success_message)
                return redirect('document_list')
            
        except Exception as e:
            error_message = f'Erreur lors de l\'upload: {str(e)}'
            print(f"Upload error: {e}")
            
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': False,
                    'message': error_message
                })
            else:
                messages.error(request, error_message)
                return render(request, 'documents/upload.html', {'categories': categories})
    
    # GET request
    return render(request, 'documents/upload.html', {'categories': categories})

@login_required
@transaction.atomic
def document_upload_with_api(request):
    """
    Vue pour uploader un document avec création d'expéditeur
    V2: Support OCR multiple (EasyOCR, OCR.space, Tesseract)
    """
    categories = Categories.objects.all()
    User = get_user_model()
    
    if request.method == 'POST':
        try:
            # ============================================
            # 1. RÉCUPÉRATION DES DONNÉES DU FORMULAIRE
            # ============================================
            sender_name = request.POST.get('sender_name')
            sender_phone = request.POST.get('sender_phone')
            sender_email = request.POST.get('sender_email')
            sender_address = request.POST.get('sender_address')
            sender_occupation = request.POST.get('sender_occupation')
            sender_organization = request.POST.get('sender_organization')
            
            document_title = request.POST.get('document_title')
            category_id = request.POST.get('document_category')
            description = request.POST.get('document_description')
            uploaded_file = request.FILES.get('pdf_file')
            
            # Choix du moteur OCR (optionnel depuis le formulaire)
            ocr_engine = request.POST.get('ocr_engine', 'auto')  # auto, easyocr, ocrspace, tesseract
            
            print(f"\n{'='*80}")
            print(f"📤 NOUVEAU DOCUMENT UPLOADÉ")
            print(f"{'='*80}")
            print(f"📄 Titre: {document_title}")
            print(f"👤 Expéditeur: {sender_name} ({sender_phone})")
            print(f"📁 Fichier: {uploaded_file.name if uploaded_file else 'Aucun'}")
            print(f"🔍 Moteur OCR: {ocr_engine}")
            
            # ============================================
            # 2. VALIDATION DES CHAMPS REQUIS
            # ============================================
            if not all([sender_name, sender_phone, document_title, category_id, uploaded_file]):
                error_msg = 'Veuillez remplir tous les champs obligatoires.'
                print(f"❌ {error_msg}")
                
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({'success': False, 'message': error_msg})
                else:
                    messages.error(request, error_msg)
                    return render(request, 'documents/upload.html', {'categories': categories})
            
            # ============================================
            # 3. VALIDATION DU FORMAT DE FICHIER
            # ============================================
            allowed_extensions = ['pdf', 'jpg', 'jpeg', 'png', 'docx', 'doc', 'bmp', 'tiff', 'tif']
            file_ext = uploaded_file.name.split('.')[-1].lower()
            
            if file_ext not in allowed_extensions:
                error_msg = f'❌ Format non supporté. Acceptés: {", ".join(allowed_extensions)}'
                print(error_msg)
                
                if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                    return JsonResponse({'success': False, 'message': error_msg})
                else:
                    messages.error(request, error_msg)
                    return render(request, 'documents/upload.html', {'categories': categories})
            
            print(f"✅ Format validé: .{file_ext}")
            
            # ============================================
            # 4. CRÉER OU RÉCUPÉRER L'UTILISATEUR EXPÉDITEUR
            # ============================================
            print(f"\n🔍 Vérification de l'expéditeur...")
            sender_user = None
            
            if sender_phone:
                try:
                    sender_user = User.objects.get(phone=sender_phone)
                    print(f"✅ Expéditeur existant trouvé: {sender_user.name}")
                    
                    # Mettre à jour les informations
                    updated_fields = []
                    if sender_email and not sender_user.email:
                        sender_user.email = sender_email
                        updated_fields.append('email')
                    if sender_name and sender_user.last_name != sender_name:
                        sender_user.last_name = sender_name
                        updated_fields.append('nom')
                    if sender_address and sender_user.address != sender_address:
                        sender_user.address = sender_address
                        updated_fields.append('adresse')
                    if sender_occupation:
                        sender_user.occupation = sender_occupation
                        updated_fields.append('profession')
                    if sender_organization:
                        sender_user.organization = sender_organization
                        updated_fields.append('organisation')
                    
                    if updated_fields:
                        sender_user.save()
                        print(f"📝 Informations mises à jour: {', '.join(updated_fields)}")
                        
                except User.DoesNotExist:
                    # Créer un nouvel utilisateur expéditeur
                    print(f"➕ Création d'un nouvel expéditeur...")
                    sender_user = User.objects.create(
                        name=sender_name,
                        phone=sender_phone,
                        email=sender_email,
                        address=sender_address,
                        occupation=sender_occupation,
                        organization=sender_organization,
                        last_login=timezone.now(),
                        is_active=True,
                        is_staff=False,
                        is_superuser=False,
                        updated_at=timezone.now(),
                        created_at=timezone.now()
                    )
                    sender_user.set_password('default_password_123')
                    sender_user.save()
                    print(f"✅ Nouvel expéditeur créé: ID {sender_user.id}")
            
            # ============================================
            # 5. SAUVEGARDE DU FICHIER
            # ============================================
            print(f"\n💾 Sauvegarde du fichier...")
            upload_dir = os.path.join(settings.MEDIA_ROOT, 'documents')
            os.makedirs(upload_dir, exist_ok=True)
            
            import uuid
            filename = f"{uuid.uuid4().hex[:10]}_{uploaded_file.name}"
            file_path = os.path.join('documents', filename)
            full_path = os.path.join(settings.MEDIA_ROOT, file_path)
            
            with open(full_path, 'wb+') as destination:
                for chunk in uploaded_file.chunks():
                    destination.write(chunk)
            
            file_size = os.path.getsize(full_path)
            print(f"✅ Fichier sauvegardé: {filename}")
            print(f"📦 Taille: {file_size / 1024:.2f} KB")
            
            # ============================================
            # 6. EXTRACTION DU TEXTE AVEC OCR
            # ============================================
            print(f"\n🔍 Extraction du texte...")
            print(f"📄 Type de fichier: .{file_ext}")
            
            from .utils_old import extract_text_from_file, get_ocr_engine
            
            # Forcer le moteur OCR si spécifié
            if ocr_engine != 'auto':
                from django.conf import settings as django_settings
                original_engine = getattr(django_settings, 'OCR_ENGINE', 'auto')
                django_settings.OCR_ENGINE = ocr_engine
            
            uploaded_file.seek(0)  # IMPORTANT: Remettre le curseur au début
            
            import time
            start_time = time.time()
            
            try:
                text_content = extract_text_from_file(uploaded_file, uploaded_file.name)
                extraction_time = time.time() - start_time
                
                print(f"✅ Texte extrait avec succès!")
                print(f"📊 Caractères extraits: {len(text_content)}")
                print(f"⏱️  Temps d'extraction: {extraction_time:.2f}s")
                print(f"🔍 Moteur utilisé: {get_ocr_engine()}")
                
                # Aperçu du texte
                if len(text_content) > 0:
                    preview = text_content[:200].replace('\n', ' ')
                    print(f"📝 Aperçu: {preview}...")
                
                # Avertissement si peu de texte
                if len(text_content) < 10:
                    print("⚠️ ATTENTION: Très peu de texte extrait!")
                    print("   - Vérifiez la qualité du document scanné")
                    print("   - Essayez un autre moteur OCR")
                    print("   - Assurez-vous que le document contient du texte")
                
            except Exception as extract_error:
                print(f"❌ Erreur lors de l'extraction: {extract_error}")
                text_content = f"Erreur d'extraction: {str(extract_error)}"
                extraction_time = time.time() - start_time
            
            # Restaurer le moteur OCR original
            if ocr_engine != 'auto':
                django_settings.OCR_ENGINE = original_engine
            
            # ============================================
            # 7. CRÉATION DU DOCUMENT EN BASE DE DONNÉES
            # ============================================
            print(f"\n💾 Création du document en base de données...")
            category = Categories.objects.get(id=category_id)
            
            document = Documents(
                title=document_title,
                description=description,
                file_path=file_path,
                text_content=text_content,
                category=category,
                sender=sender_user,
                user=request.user,
                status='pending',
                created_at=timezone.now(),
                updated_at=timezone.now()
            )
            document.save()
            
            print(f"✅ Document créé: ID {document.id}")
            
            # ============================================
            # 8. RÉPONSE DE SUCCÈS
            # ============================================
            success_message = f'✅ Document "{document_title}" uploadé avec succès! Expéditeur: {sender_name}'
            
            print(f"\n{'='*80}")
            print(f"✅ UPLOAD TERMINÉ AVEC SUCCÈS")
            print(f"{'='*80}")
            print(f"📄 Document ID: {document.id}")
            print(f"👤 Expéditeur ID: {sender_user.id}")
            print(f"📊 Texte: {len(text_content)} caractères")
            print(f"⏱️  Durée totale: {extraction_time:.2f}s")
            print(f"{'='*80}\n")
            
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': True,
                    'message': success_message,
                    'document_id': document.id,
                    'sender_id': sender_user.id,
                    'text_length': len(text_content),
                    'extraction_time': round(extraction_time, 2),
                    'ocr_engine': get_ocr_engine(),
                    'file_size': round(file_size / 1024, 2)
                })
            else:
                messages.success(request, success_message)
                return redirect('document_list')
            
        except Exception as e:
            # ============================================
            # GESTION DES ERREURS
            # ============================================
            error_message = f'❌ Erreur lors de l\'upload: {str(e)}'
            
            print(f"\n{'='*80}")
            print(f"❌ ERREUR DURANT L'UPLOAD")
            print(f"{'='*80}")
            print(f"Message: {error_message}")
            
            # Afficher la trace complète pour le débogage
            import traceback
            print(f"\n📋 Trace complète:")
            traceback.print_exc()
            print(f"{'='*80}\n")
            
            if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
                return JsonResponse({
                    'success': False,
                    'message': error_message
                })
            else:
                messages.error(request, error_message)
                return render(request, 'documents/upload.html', {'categories': categories})
    
    # ============================================
    # GET REQUEST - AFFICHER LE FORMULAIRE
    # ============================================
    # Récupérer le moteur OCR actuel pour l'afficher dans le formulaire
    from django.conf import settings as django_settings
    current_ocr_engine = getattr(django_settings, 'OCR_ENGINE', 'auto')
    
    context = {
        'categories': categories,
        'ocr_engine': current_ocr_engine,
        'allowed_formats': ['pdf', 'jpg', 'jpeg', 'png', 'docx', 'doc', 'bmp', 'tiff', 'tif']
    }
    
    return render(request, 'documents/upload.html', context)
@login_required
def document_list(request):
    """Vue pour lister les documents"""
    # Par ID décroissant (si pas de champ date)
    documents = Documents.objects.all().order_by('-id')
    return render(request, 'documents/list.html', {'documents': documents})

@login_required
def audio_list(request):
    """Vue pour lister les audios générés"""
    audios = Audios.objects.all().order_by('-id')
    return render(request, 'documents/audio_list.html', {'audios': audios})

@login_required
def convert_to_audio_old(request, document_id):
    """Vue pour convertir un document en audio"""
    try:
        document = Documents.objects.get(id=document_id, user=request.user)
        
        # Vérifier si le document n'est pas déjà en cours de traitement
        if document.status == 'processed':
            messages.info(request, f'Le document "{document.title}" a déjà été converti.')
            return redirect('document_list')
        
        # Lancer la conversion en arrière-plan
        def conversion_task():
            try:
                convert_document_to_audio(document_id)
            except Exception as e:
                print(f"Erreur conversion document {document_id}: {e}")
        
        # Démarrer la conversion dans un thread séparé
        thread = threading.Thread(target=conversion_task)
        thread.daemon = True
        thread.start()
        
        # convert_document_to_audio(document_id)
        
        messages.success(request, f'Conversion du document "{document.title}" en cours... L\'audio sera disponible dans quelques instants.')
        
    except Documents.DoesNotExist:
        messages.error(request, 'Document non trouvé')
    except Exception as e:
        messages.error(request, f'Erreur lors du démarrage de la conversion: {str(e)}')
    
    return redirect('document_list')


@login_required
def convert_to_audio_old_v2(request, document_id):
    """Conversion avec timeout et attente"""
    try:
        document = Documents.objects.get(id=document_id, user=request.user)
        
        if document.status == 'processed':
            messages.info(request, 'Document déjà converti')
            return redirect('read_document', document_id=document_id)
        
        # Marquer comme en cours
        document.status = 'processing'
        document.save()
        
        # Conversion avec timeout
        max_wait_time = 120  # secondes maximum d'attente
        start_time = time.time()
        
        # Lancer la conversion
        success = convert_document_to_audio(document_id)
        
        if not success:
            messages.error(request, 'Erreur de conversion')
            return redirect('document_list')
        
        # Attendre que le traitement soit terminé
        while time.time() - start_time < max_wait_time:
            document.refresh_from_db()
            if document.status == 'processed':
                messages.success(request, f'Conversion réussie de "{document.title}"')
                return redirect('read_document', document_id=document_id)
            elif document.status == 'error':
                messages.error(request, 'Erreur lors de la conversion')
                return redirect('document_list')
            
            time.sleep(1)  # Attendre 1 seconde entre les vérifications
        
        # Timeout atteint
        messages.warning(request, 'Conversion en cours... Vous serez notifié quand ce sera terminé.')
        return redirect('document_list')
        
    except Exception as e:
        messages.error(request, f'Erreur: {str(e)}')
        return redirect('document_list')
    
@login_required
def convert_to_audio(request, document_id):
    """Conversion simple et redirection directe"""
    try:
        document = Documents.objects.get(id=document_id, user=request.user)
        # dd(document)
        # Vérifier si déjà converti
        if document.status == 'processed':
            return redirect('read_document', document_id=document_id)
        
        # Conversion directe
        document.status = 'processed'
        document.save()
        
        # Appel direct à la fonction de conversion
        convert_document_to_audio(document_id)
        
        # Redirection vers la page de lecture
        # La page read_document vérifiera si l'audio est prêt
        return redirect('read_document', document_id=document_id)
        
    except Documents.DoesNotExist:
        messages.error(request, 'Document non trouvé')
        return redirect('document_list')
    except Exception as e:
        messages.error(request, f'Erreur de conversion: {str(e)}')
        return redirect('document_list')

@login_required
def read_document(request, document_id):
    """Lecture instantanée du document"""
    try:
        document = Documents.objects.get(id=document_id, user=request.user)
        
        if not document.text_content or document.text_content.strip() == "":
            messages.error(request, "Aucun texte disponible pour la lecture")
            return redirect('document_list')
        
        # Vérifier si un audio existe déjà
        audio_exists = Audios.objects.filter(document=document).exists()
        audio_url = None
        audio_file = None
        
        if audio_exists:
            audio = Audios.objects.filter(document=document).first()
            audio_url = audio.get_audio_url()  # Utiliser la méthode corrigée
            audio_file = audio  # Garder l'objet audio pour d'autres utilisations
        
        context = {
            'document': document,
            'text_content': document.text_content,
            'title': document.title or f"Document {document.id}",
            'audio_exists': audio_exists,
            'audio_url': audio_url,
            'audio_file': audio_file
        }
        
        return render(request, 'documents/read_document.html', context)
        
    except Documents.DoesNotExist:
        messages.error(request, 'Document non trouvé')
        return redirect('document_list')
    
@login_required
def get_audio_stream(request, document_id):
    """API pour obtenir un flux audio temporaire (sans sauvegarde)"""
    try:
        document = Documents.objects.get(id=document_id, user=request.user)
        
        if not document.text_content:
            return JsonResponse({'error': 'Aucun texte disponible'}, status=400)
        
        # Générer un audio temporaire
        audio_data = text_to_speech_stream(document.text_content)
        
        # Retourner le flux audio
        response = HttpResponse(audio_data, content_type='audio/mpeg')
        response['Content-Disposition'] = f'inline; filename="lecture_{document_id}.mp3"'
        return response
        
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=500)


def convert_document_to_audio_old(document_id, voice_type='female_fr'):
    """Fonction principale de conversion texte -> audio (avec sauvegarde)"""
    try:
        # Récupérer le document
        document = Documents.objects.get(id=document_id)
        
        if not document.text_content:
            raise Exception("Aucun texte à convertir")
        
        text_content = document.text_content
        
        # Convertir le texte en audio (avec sauvegarde)
        audio_filename = f"doc_{document_id}_{uuid.uuid4().hex[:8]}.mp3"
        audio_file_path, duration = text_to_speech(text_content, audio_filename)
        
        # Créer l'enregistrement audio
        audio = Audios(
            document=document,
            file_path=audio_file_path,
            duration=duration,
            voice_type=voice_type,
            created_at=timezone.now(),
            updated_at=timezone.now()
        )
        audio.save()
        
        # Marquer le document comme traité
        document.status = 'processed'
        document.updated_at = timezone.now()
        document.save()
        
        return audio
        
    except Exception as e:
        # Marquer le document en erreur
        document = Documents.objects.get(id=document_id)
        document.status = 'pending'
        document.updated_at = timezone.now()
        document.save()
        raise e

def convert_document_to_audio(document_id, voice_type='female_fr'):
    """Fonction avec update_or_create pour une gestion plus propre"""
    try:
        # Récupérer le document
        document = Documents.objects.get(id=document_id)
        
        if not document.text_content:
            raise Exception("Aucun texte à convertir")
        
        text_content = document.text_content
        
        # Convertir le texte en audio
        audio_filename = f"doc_{document_id}_{uuid.uuid4().hex[:8]}.mp3"
        audio_file_path, duration = text_to_speech(text_content, audio_filename)
        
        # Mettre à jour ou créer l'audio
        audio, created = Audios.objects.update_or_create(
            document=document,
            defaults={
                'file_path': audio_file_path,
                'duration': duration,
                'voice_type': voice_type,
                'updated_at': timezone.now(),
            }
        )
        
        # Si c'est une création, définir la date de création
        if created:
            audio.created_at = timezone.now()
            audio.save()
        
        # Marquer le document comme traité
        document.status = 'processed'
        document.updated_at = timezone.now()
        document.save()
        
        action = "créé" if created else "mis à jour"
        print(f"Audio {action} pour le document {document_id}")
        
        return audio
        
    except Exception as e:
        # Marquer le document en erreur
        document = Documents.objects.get(id=document_id)
        document.status = 'pending'
        document.updated_at = timezone.now()
        document.save()
        raise e
@login_required
def download_audio(request, audio_id):
    """Télécharger un fichier audio généré"""
    try:
        audio = Audios.objects.get(id=audio_id, document__user=request.user)
        response = HttpResponse(audio.file_path, content_type='audio/mpeg')
        response['Content-Disposition'] = f'attachment; filename="audio_{audio.document.title}.mp3"'
        return response
    except Audios.DoesNotExist:
        messages.error(request, 'Fichier audio non trouvé')
        return redirect('audio_list')
def home(request):
    """Page d'accueil"""
    if request.user.is_authenticated:
        return redirect('dashboard')
    return render(request, 'registration/login.html')

def custom_login_old(request):
    if request.user.is_authenticated:
        if request.user.role in ['admin', 'agent']:
            return redirect('administration:dashboard')
        else:
            return redirect('document_list')
    
    if request.method == 'POST':
        phone = request.POST.get('phone', '').strip()
        password = request.POST.get('password', '')
        remember_me = request.POST.get('remember')
        
        print(f"LOGIN DEBUG: Phone reçu: '{phone}'")
        print(f"LOGIN DEBUG: Password reçu: '{password}'")
        
        # Validation des champs
        if not phone or not password:
            messages.error(request, "Veuillez remplir tous les champs obligatoires.")
            return render(request, 'registration/login.html', {'phone': phone})
        
        # Nettoyer le numéro en gardant le +
        phone_clean = re.sub(r'[^\d+]', '', phone)
        print(f"LOGIN DEBUG: Phone nettoyé: '{phone_clean}'")
        
        if len(phone_clean) < 8:
            messages.error(request, "Numéro de téléphone invalide.")
            return render(request, 'registration/login.html', {'phone': phone})
        
        # Authentification
        user = authenticate(request, username=phone_clean, password=password)
        print(f"LOGIN DEBUG: Authenticate result: {user}")
        
        if user is not None:
            if user.is_active:
                login(request, user)
                
                if not remember_me:
                    request.session.set_expiry(0)
                else:
                    request.session.set_expiry(60 * 60 * 24 * 30)
                
                messages.success(request, f"Connexion réussie ! Bienvenue {user.name}")
                
                next_url = request.GET.get('next')
                if next_url:
                    return redirect(next_url)
                elif user.role in ['admin', 'agent']:
                    return redirect('administration:dashboard')
                else:
                    return redirect('document_list')
            else:
                messages.error(request, "Votre compte est désactivé. Contactez l'administrateur.")
        else:
            # Diagnostic détaillé
            from .models import Users
            try:
                # Vérifier différentes variantes du numéro
                exact_match = Users.objects.filter(phone=phone_clean).exists()
                cleaned_match = Users.objects.filter(phone=phone_clean.replace('+', '')).exists()
                partial_match = Users.objects.filter(phone__contains=phone_clean[-9:]).exists()
                
                print(f"LOGIN DEBUG: Exact match: {exact_match}")
                print(f"LOGIN DEBUG: Cleaned match: {cleaned_match}")
                print(f"LOGIN DEBUG: Partial match: {partial_match}")
                
                if exact_match or cleaned_match or partial_match:
                    messages.error(request, "Mot de passe incorrect.")
                else:
                    messages.error(request, "Numéro de téléphone non enregistré.")
            except Exception as e:
                print(f"LOGIN DEBUG: Error: {e}")
                messages.error(request, "Erreur d'authentification. Veuillez réessayer.")
            
            return render(request, 'registration/login.html', {'phone': phone})
    
    return render(request, 'registration/login.html')


def custom_login(request):
    # Si déjà connecté, rediriger
    if request.user.is_authenticated:
        if request.user.role in ['admin', 'agent']:
            return redirect('administration:dashboard')
        else:
            return redirect('document_list')
    
    # Requête AJAX
    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        if request.method == 'POST':
            phone = request.POST.get('phone', '').strip()
            password = request.POST.get('password', '')
            remember_me = request.POST.get('remember')
            
            # Validation
            if not phone or not password:
                return JsonResponse({
                    'success': False,
                    'message': "Veuillez remplir tous les champs obligatoires.",
                    'field': 'phone' if not phone else 'password'
                })
            
            # Nettoyer le numéro
            phone_clean = re.sub(r'[^\d+]', '', phone)
            
            if len(phone_clean) < 8:
                return JsonResponse({
                    'success': False,
                    'message': "Numéro de téléphone invalide.",
                    'field': 'phone'
                })
            
            # Authentification
            user = authenticate(request, username=phone_clean, password=password)
            
            if user is not None:
                if user.is_active:
                    login(request, user)
                    
                    # Gestion de la session
                    if not remember_me:
                        request.session.set_expiry(0)
                    else:
                        request.session.set_expiry(60 * 60 * 24 * 30)
                    
                    # Déterminer l'URL de redirection
                    next_url = request.GET.get('next')
                    if next_url:
                        redirect_url = next_url
                    elif user.role in ['admin', 'agent']:
                        redirect_url = '/dashboard/'
                    else:
                        redirect_url = '/dashboard/'
                    
                    return JsonResponse({
                        'success': True,
                        'message': f"Connexion réussie ! Bienvenue {user.name or user.email}",
                        'redirect_url': redirect_url
                    })
                else:
                    return JsonResponse({
                        'success': False,
                        'message': "Votre compte est désactivé. Contactez l'administrateur.",
                        'field': 'phone'
                    })
            else:
                # Diagnostic
                try:
                    exact_match = Users.objects.filter(phone=phone_clean).exists()
                    cleaned_match = Users.objects.filter(phone=phone_clean.replace('+', '')).exists()
                    
                    if exact_match or cleaned_match:
                        return JsonResponse({
                            'success': False,
                            'message': "Mot de passe incorrect.",
                            'field': 'password'
                        })
                    else:
                        return JsonResponse({
                            'success': False,
                            'message': "Numéro de téléphone non enregistré.",
                            'field': 'phone'
                        })
                except Exception as e:
                    return JsonResponse({
                        'success': False,
                        'message': "Erreur d'authentification. Veuillez réessayer.",
                        'field': 'phone'
                    })
        
        return JsonResponse({
            'success': False,
            'message': "Méthode non autorisée."
        })
    
    # Requête normale (GET)
    return render(request, 