from django.db import models
from django.contrib.auth.models import User
import os
from django.conf import settings
import json
from pathlib import Path

def protected_file_path(instance, filename):
    # Génère un chemin unique par utilisateur
    return f'user_{instance.owner.id}/{filename}'

class ProtectedFile(models.Model):
    title = models.CharField(max_length=255)
    file = models.FileField(upload_to=protected_file_path)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='owned_files')
    allowed_users = models.ManyToManyField(User, related_name='accessible_files', blank=True)
    date_uploaded = models.DateTimeField(auto_now_add=True)

    # Stocker le fichier dans le répertoire protégé
    def save(self, *args, **kwargs):
        if not self.id:
            super().save(*args, **kwargs)
            # Déplacer le fichier vers le répertoire protégé après le premier enregistrement
            original_path = self.file.path
            relative_path = self.file.name
            new_path = os.path.join(settings.PROTECTED_MEDIA_ROOT, relative_path)

            # Créer le répertoire si nécessaire
            os.makedirs(os.path.dirname(new_path), exist_ok=True)

            # Déplacer le fichier
            if os.path.exists(original_path):
                with open(original_path, 'rb') as f_src:
                    with open(new_path, 'wb') as f_dst:
                        f_dst.write(f_src.read())
                os.remove(original_path)
        else:
            super().save(*args, **kwargs)
    
    def get_file_path(self):
        return os.path.join(settings.PROTECTED_MEDIA_ROOT, self.file.name)
    
    def user_can_access(self, user):
        return (user.is_authenticated and 
                (user == self.owner or 
                 user in self.allowed_users.all() or 
                 user.is_superuser))

class UserFile(models.Model):
    """
    Modèle pour suivre les fichiers uploadés par les utilisateurs
    Les fichiers sont stockés dans le dossier uploads/
    """
    filename = models.CharField(max_length=255)  # Nom du fichier sur le disque (sanitisé)
    display_name = models.CharField(max_length=255, null=True, blank=True)  # Nom d'affichage original (avec accents)
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)  # Utilisateur propriétaire (peut être null)
    upload_date = models.DateTimeField(auto_now_add=True)  # Date d'upload
    ip_address = models.GenericIPAddressField(null=True, blank=True)  # Adresse IP de l'utilisateur lors de l'upload
    file_size = models.PositiveIntegerField(null=True, blank=True)  # Taille du fichier en octets
    
    def __str__(self):
        display = self.display_name or self.filename
        if self.user:
            return f"{display} (uploadé par {self.user.username})"
        return f"{display} (sans propriétaire)"
    
    def get_file_path(self):
        """Retourne le chemin complet du fichier sur le système"""
        return Path(settings.BASE_DIR) / 'uploads' / self.filename
    
    def get_size_display(self):
        """Retourne la taille du fichier dans un format lisible"""
        if not self.file_size:
            return "Inconnu"
        
        # Convertir en format lisible (KB, MB, GB)
        size = self.file_size
        for unit in ['B', 'KB', 'MB', 'GB']:
            if size < 1024.0 or unit == 'GB':
                break
            size /= 1024.0
        return f"{size:.2f} {unit}"
    
    @classmethod
    def save_to_json(cls):
        """Sauvegarde tous les fichiers dans un fichier JSON"""
        data = []
        for user_file in cls.objects.all():
            data.append({
                'utilisateur': user_file.user.username if user_file.user else None,
                'lien_fichier': user_file.filename
            })
        
        json_path = os.path.join(settings.BASE_DIR, 'uploads', 'files.json')
        with open(json_path, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=4)
        
        return json_path

class UserNote(models.Model):
    """
    Modèle pour les notes persistantes des utilisateurs
    """
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='notes')
    content = models.TextField(blank=True)
    title = models.CharField(max_length=255, default="Ma note")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    def __str__(self):
        return f"Note de {self.user.username}: {self.title}"
