import datetime
import hashlib
from django.db import models
from django.db.models import Sum
from django.forms import ValidationError
from django.template.defaultfilters import slugify
import random
from userapp.models import User, CostumUser
from django.core.validators import MinValueValidator, MaxValueValidator
from tinymce.models import HTMLField
import uuid
from django.urls import reverse
from PIL import Image
import os
from django.utils import timezone


# paramètres de configuration


class Parameter(models.Model):

    class Meta:
        verbose_name = "Paramètre"
        verbose_name_plural = "Paramètres"

    name = models.CharField(
        max_length=255,
        blank=True,
        default="Ecolux BTP",
        unique=True,
        verbose_name="Nom de la société",
    )

    phone = models.CharField(
        max_length=45, blank=True, default="", verbose_name="Numéro de téléphone"
    )
    email = models.CharField(max_length=255, blank=True, default="")

    contractFooter = HTMLField(
        blank=True, default="", verbose_name="Pied de page du contrat"
    )
    logo = models.ImageField(
        upload_to="az-images/", blank=True, default="", verbose_name="Logo"
    )
    createdAt = models.DateTimeField(auto_now_add=True, blank=True)

    def __str__(self):
        return self.name


# Modèle Client pour tracker les clients par email
class Customer(models.Model):
    
    class Meta:
        verbose_name = "Client"
        verbose_name_plural = "Clients"
        ordering = ['-created_at']

    # Informations personnelles
    email = models.EmailField(
        unique=True, 
        verbose_name="Email",
        help_text="Email unique du client"
    )
    full_name = models.CharField(
        max_length=255, 
        verbose_name="Nom complet"
    )
    phone = models.CharField(
        max_length=20, 
        blank=True, 
        verbose_name="Téléphone"
    )
    
    # Métadonnées
    created_at = models.DateTimeField(
        auto_now_add=True, 
        verbose_name="Date de création"
    )
    updated_at = models.DateTimeField(
        auto_now=True, 
        verbose_name="Dernière modification"
    )
    
    # Statistiques
    simulation_count = models.PositiveIntegerField(
        default=0,
        verbose_name="Nombre de simulations"
    )
    last_simulation_date = models.DateTimeField(
        blank=True, 
        null=True,
        verbose_name="Dernière simulation"
    )

    def __str__(self):
        return f"{self.full_name} ({self.email})"

    def update_simulation_stats(self):
        """Met à jour les statistiques de simulation du client"""
        self.simulation_count = self.simulations.count()
        latest_sim = self.simulations.order_by('-created_at').first()
        if latest_sim:
            self.last_simulation_date = latest_sim.created_at
        self.save()


# Modèle Simulation pour enregistrer chaque simulation
class Simulation(models.Model):
    
    class Meta:
        verbose_name = "Simulation"
        verbose_name_plural = "Simulations"
        ordering = ['-created_at']

    # Statuts de simulation
    STATUS_CHOICES = [
        ('DRAFT', 'Brouillon'),
        ('COMPLETED', 'Terminée'),
        ('QUOTE_REQUESTED', 'Devis demandé'),
        ('QUOTE_SENT', 'Devis envoyé'),
    ]

    # Relation avec le client
    customer = models.ForeignKey(
        Customer, 
        on_delete=models.CASCADE,
        related_name='simulations',
        verbose_name="Client"
    )
    
    # Paramètres du projet
    project_type = models.CharField(
        max_length=50,
        verbose_name="Type de projet",
        choices=[
            ('Villa', 'Villa'),
            ('Mini immeuble', 'Mini immeuble'),
            ('Immeuble', 'Immeuble'),
            ('Immeuble avec sous-sol', 'Immeuble avec sous-sol'),
        ]
    )
    
    standing = models.CharField(
        max_length=20,
        verbose_name="Standing",
        choices=[
            ('Éco', 'Éco'),
            ('Moyen', 'Moyen'),
            ('Haut', 'Haut'),
        ]
    )
    
    niveau = models.CharField(
        max_length=10,
        verbose_name="Niveau",
        choices=[
            ('RDC', 'RDC'),
            ('R+1', 'R+1'),
            ('R+2', 'R+2'),
            ('R+3', 'R+3'),
            ('R+4', 'R+4'),
            ('R+5', 'R+5'),
            ('R+6', 'R+6'),
            ('R+7', 'R+7'),
            ('R+8', 'R+8'),
            ('R+9', 'R+9'),
            ('R+10', 'R+10'),
        ]
    )
    
    region = models.CharField(
        max_length=50,
        verbose_name="Région",
        choices=[
            ('Dakar', 'Dakar'),
            ('Thiès', 'Thiès'),
            ('Diourbel', 'Diourbel'),
            ('Kaolack', 'Kaolack'),
            ('Fatick', 'Fatick'),
            ('Saint-Louis', 'Saint-Louis'),
            ('Louga', 'Louga'),
            ('Matam', 'Matam'),
            ('Tambacounda', 'Tambacounda'),
            ('Kédougou', 'Kédougou'),
            ('Kolda', 'Kolda'),
            ('Sédhiou', 'Sédhiou'),
            ('Ziguinchor', 'Ziguinchor'),
            ('Podor/Bakel (isolé)', 'Podor/Bakel (isolé)'),
        ]
    )
    
    # Surfaces
    surface_terrain = models.PositiveIntegerField(
        verbose_name="Surface terrain (m²)"
    )
    surface_batie = models.PositiveIntegerField(
        verbose_name="Surface bâtie (m²)"
    )
    
    # Options
    ascenseur = models.BooleanField(
        default=False,
        verbose_name="Ascenseur"
    )
    
    fondation_choice = models.CharField(
        max_length=20,
        verbose_name="Choix fondation",
        choices=[
            ('Auto', 'Automatique'),
            ('Semelles', 'Semelles isolées'),
            ('Radier', 'Radier général'),
        ],
        default='Auto'
    )
    
    # Options sans prix (JSON field pour flexibilité)
    options_sans_prix = models.JSONField(
        default=list,
        blank=True,
        verbose_name="Options sans prix",
        help_text="Liste des options sélectionnées (piscine, panneaux solaires, etc.)"
    )
    
    # Résultats de la simulation
    cout_gros_oeuvre = models.BigIntegerField(
        verbose_name="Coût Gros Œuvre (FCFA)"
    )
    cout_second_oeuvre = models.BigIntegerField(
        verbose_name="Coût Second Œuvre (FCFA)"
    )
    cout_ascenseur = models.BigIntegerField(
        default=0,
        verbose_name="Coût Ascenseur (FCFA)"
    )
    cout_total = models.BigIntegerField(
        verbose_name="Coût Total (FCFA)"
    )
    prix_m2 = models.PositiveIntegerField(
        verbose_name="Prix au m² (FCFA)"
    )
    
    # Informations de devis
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='COMPLETED',
        verbose_name="Statut"
    )
    
    # Informations complémentaires pour le devis
    localisation_projet = models.CharField(
        max_length=255,
        blank=True,
        verbose_name="Localisation du projet"
    )
    a_terrain = models.BooleanField(
        null=True,
        blank=True,
        verbose_name="Possède un terrain"
    )
    adresse_terrain = models.TextField(
        blank=True,
        verbose_name="Adresse du terrain"
    )
    conseil_terrain = models.BooleanField(
        default=False,
        verbose_name="Souhaite conseil terrain"
    )
    projet_actuel = models.BooleanField(
        null=True,
        blank=True,
        verbose_name="Projet actuel"
    )
    delai_projet = models.CharField(
        max_length=20,
        blank=True,
        verbose_name="Délai du projet",
        choices=[
            ('3mois', '3 mois'),
            ('6mois', '6 mois'),
            ('1an', '1 an ou +'),
        ]
    )
    a_plan = models.BooleanField(
        null=True,
        blank=True,
        verbose_name="Possède un plan"
    )
    message_client = models.TextField(
        blank=True,
        verbose_name="Message du client"
    )
    
    # Métadonnées
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date de création"
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name="Dernière modification"
    )
    
    # Tracking
    ip_address = models.GenericIPAddressField(
        blank=True,
        null=True,
        verbose_name="Adresse IP"
    )
    user_agent = models.TextField(
        blank=True,
        verbose_name="User Agent"
    )

    def __str__(self):
        return f"Simulation {self.id} - {self.customer.full_name} - {self.project_type} {self.standing}"

    def save(self, *args, **kwargs):
        is_new = self.pk is None
        super().save(*args, **kwargs)
        
        # Mettre à jour les statistiques du client
        if is_new:
            self.customer.update_simulation_stats()

    @property
    def cout_total_formatted(self):
        """Retourne le coût total formaté"""
        return f"{self.cout_total:,}".replace(',', ' ')

    @property
    def is_quote_requested(self):
        """Vérifie si un devis a été demandé"""
        return self.status == 'QUOTE_REQUESTED'


# ========================================
# MODÈLES POUR LE BLOG
# ========================================

class BlogCategory(models.Model):
    """Catégories pour les articles de blog"""
    
    class Meta:
        verbose_name = "Catégorie de blog"
        verbose_name_plural = "Catégories de blog"
        ordering = ['name']

    name = models.CharField(
        max_length=100,
        unique=True,
        verbose_name="Nom de la catégorie"
    )
    slug = models.SlugField(
        max_length=100,
        unique=True,
        verbose_name="Slug"
    )
    description = models.TextField(
        blank=True,
        verbose_name="Description"
    )
    color = models.CharField(
        max_length=7,
        default="#3B82F6",
        verbose_name="Couleur (hex)",
        help_text="Couleur d'affichage de la catégorie (ex: #3B82F6)"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date de création"
    )

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('app:blog_category', kwargs={'slug': self.slug})


class BlogPost(models.Model):
    """Articles de blog"""
    
    class Meta:
        verbose_name = "Article de blog"
        verbose_name_plural = "Articles de blog"
        ordering = ['-created_at']

    STATUS_CHOICES = [
        ('DRAFT', 'Brouillon'),
        ('PUBLISHED', 'Publié'),
        ('ARCHIVED', 'Archivé'),
    ]

    title = models.CharField(
        max_length=200,
        verbose_name="Titre"
    )
    slug = models.SlugField(
        max_length=200,
        unique=True,
        verbose_name="Slug"
    )
    excerpt = models.TextField(
        max_length=300,
        verbose_name="Extrait",
        help_text="Résumé court de l'article (max 300 caractères)"
    )
    content = HTMLField(
        verbose_name="Contenu"
    )
    featured_image = models.ImageField(
        upload_to="blog/images/",
        blank=True,
        null=True,
        verbose_name="Image à la une"
    )
    category = models.ForeignKey(
        BlogCategory,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='posts',
        verbose_name="Catégorie"
    )
    author = models.ForeignKey(
        CostumUser,
        on_delete=models.CASCADE,
        related_name='blog_posts',
        verbose_name="Auteur"
    )
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='DRAFT',
        verbose_name="Statut"
    )
    featured = models.BooleanField(
        default=False,
        verbose_name="Article en vedette"
    )
    views_count = models.PositiveIntegerField(
        default=0,
        verbose_name="Nombre de vues"
    )
    tags = models.CharField(
        max_length=500,
        blank=True,
        verbose_name="Tags",
        help_text="Séparez les tags par des virgules"
    )
    meta_description = models.CharField(
        max_length=160,
        blank=True,
        verbose_name="Meta description",
        help_text="Description pour les moteurs de recherche (max 160 caractères)"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date de création"
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name="Dernière modification"
    )
    published_at = models.DateTimeField(
        blank=True,
        null=True,
        verbose_name="Date de publication"
    )

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        
        # Définir la date de publication si l'article passe en statut publié
        if self.status == 'PUBLISHED' and not self.published_at:
            self.published_at = timezone.now()
        
        super().save(*args, **kwargs)
        
        # Redimensionner l'image si nécessaire
        if self.featured_image:
            self.resize_image()

    def resize_image(self):
        """Redimensionne l'image à la une pour optimiser les performances"""
        if self.featured_image:
            img_path = self.featured_image.path
            if os.path.exists(img_path):
                with Image.open(img_path) as img:
                    # Redimensionner si l'image est trop grande
                    if img.width > 1200 or img.height > 800:
                        img.thumbnail((1200, 800), Image.Resampling.LANCZOS)
                        img.save(img_path, optimize=True, quality=85)

    def get_absolute_url(self):
        return reverse('app:blog_detail', kwargs={'slug': self.slug})

    def get_tags_list(self):
        """Retourne les tags sous forme de liste"""
        if self.tags:
            return [tag.strip() for tag in self.tags.split(',') if tag.strip()]
        return []

    def increment_views(self):
        """Incrémente le compteur de vues"""
        self.views_count += 1
        self.save(update_fields=['views_count'])

    @property
    def reading_time(self):
        """Calcule le temps de lecture estimé en minutes"""
        word_count = len(self.content.split())
        return max(1, round(word_count / 200))  # 200 mots par minute


# ========================================
# MODÈLES POUR LES RÉALISATIONS
# ========================================

class ProjectCategory(models.Model):
    """Catégories pour les projets/réalisations"""
    
    class Meta:
        verbose_name = "Catégorie de projet"
        verbose_name_plural = "Catégories de projet"
        ordering = ['name']

    name = models.CharField(
        max_length=100,
        unique=True,
        verbose_name="Nom de la catégorie"
    )
    slug = models.SlugField(
        max_length=100,
        unique=True,
        verbose_name="Slug"
    )
    description = models.TextField(
        blank=True,
        verbose_name="Description"
    )
    icon = models.CharField(
        max_length=50,
        blank=True,
        verbose_name="Icône",
        help_text="Nom de l'icône (ex: home, building, etc.)"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date de création"
    )

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('app:project_category', kwargs={'slug': self.slug})


class Project(models.Model):
    """Projets/Réalisations BTP"""
    
    class Meta:
        verbose_name = "Projet/Réalisation"
        verbose_name_plural = "Projets/Réalisations"
        ordering = ['-completed_date', '-created_at']

    STATUS_CHOICES = [
        ('PLANNING', 'En planification'),
        ('IN_PROGRESS', 'En cours'),
        ('COMPLETED', 'Terminé'),
        ('ON_HOLD', 'En pause'),
    ]

    title = models.CharField(
        max_length=200,
        verbose_name="Titre du projet"
    )
    slug = models.SlugField(
        max_length=200,
        unique=True,
        verbose_name="Slug"
    )
    description = HTMLField(
        verbose_name="Description",
        help_text="Description détaillée du projet avec mise en forme HTML"
    )
    short_description = models.CharField(
        max_length=200,
        verbose_name="Description courte",
        help_text="Description courte pour les aperçus"
    )
    category = models.ForeignKey(
        ProjectCategory,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='projects',
        verbose_name="Catégorie"
    )
    location = models.CharField(
        max_length=200,
        verbose_name="Localisation"
    )
    client_name = models.CharField(
        max_length=200,
        blank=True,
        verbose_name="Nom du client",
        help_text="Optionnel, peut être anonymisé"
    )
    
    # Détails techniques
    surface_built = models.PositiveIntegerField(
        blank=True,
        null=True,
        verbose_name="Surface construite (m²)"
    )
    surface_land = models.PositiveIntegerField(
        blank=True,
        null=True,
        verbose_name="Surface terrain (m²)"
    )
    floors_count = models.CharField(
        max_length=20,
        blank=True,
        verbose_name="Nombre d'étages",
        help_text="Ex: RDC, R+1, R+2, etc."
    )
    rooms_count = models.PositiveIntegerField(
        blank=True,
        null=True,
        verbose_name="Nombre de pièces"
    )
    
    # Dates et budget
    start_date = models.DateField(
        blank=True,
        null=True,
        verbose_name="Date de début"
    )
    completed_date = models.DateField(
        blank=True,
        null=True,
        verbose_name="Date de fin/livraison"
    )
    budget = models.BigIntegerField(
        blank=True,
        null=True,
        verbose_name="Budget (FCFA)",
        help_text="Budget du projet en FCFA"
    )
    
    # Statut et visibilité
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='COMPLETED',
        verbose_name="Statut"
    )
    featured = models.BooleanField(
        default=False,
        verbose_name="Projet en vedette"
    )
    published = models.BooleanField(
        default=True,
        verbose_name="Publié"
    )
    
    # Image principale
    main_image = models.ImageField(
        upload_to="projects/images/",
        verbose_name="Image principale"
    )
    
    # Métadonnées
    views_count = models.PositiveIntegerField(
        default=0,
        verbose_name="Nombre de vues"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date de création"
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name="Dernière modification"
    )

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        
        super().save(*args, **kwargs)
        
        # Redimensionner l'image principale
        if self.main_image:
            self.resize_main_image()

    def resize_main_image(self):
        """Redimensionne l'image principale"""
        if self.main_image:
            img_path = self.main_image.path
            if os.path.exists(img_path):
                with Image.open(img_path) as img:
                    if img.width > 1200 or img.height > 800:
                        img.thumbnail((1200, 800), Image.Resampling.LANCZOS)
                        img.save(img_path, optimize=True, quality=90)

    def get_absolute_url(self):
        return reverse('app:project_detail', kwargs={'slug': self.slug})

    def increment_views(self):
        """Incrémente le compteur de vues"""
        self.views_count += 1
        self.save(update_fields=['views_count'])

    @property
    def budget_formatted(self):
        """Retourne le budget formaté"""
        if self.budget:
            return f"{self.budget:,}".replace(',', ' ')
        return None

    @property
    def duration_months(self):
        """Calcule la durée du projet en mois"""
        if self.start_date and self.completed_date:
            delta = self.completed_date - self.start_date
            return round(delta.days / 30)
        return None


class ProjectImage(models.Model):
    """Images supplémentaires pour les projets"""
    
    class Meta:
        verbose_name = "Image de projet"
        verbose_name_plural = "Images de projet"
        ordering = ['order']

    project = models.ForeignKey(
        Project,
        on_delete=models.CASCADE,
        related_name='images',
        verbose_name="Projet"
    )
    image = models.ImageField(
        upload_to="projects/gallery/",
        verbose_name="Image"
    )
    title = models.CharField(
        max_length=200,
        blank=True,
        verbose_name="Titre de l'image"
    )
    description = models.TextField(
        blank=True,
        verbose_name="Description"
    )
    order = models.PositiveIntegerField(
        default=0,
        verbose_name="Ordre d'affichage"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date d'ajout"
    )

    def __str__(self):
        return f"{self.project.title} - Image {self.id}"

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        if self.image:
            self.resize_image()

    def resize_image(self):
        """Redimensionne l'image"""
        if self.image:
            img_path = self.image.path
            if os.path.exists(img_path):
                with Image.open(img_path) as img:
                    if img.width > 1200 or img.height > 800:
                        img.thumbnail((1200, 800), Image.Resampling.LANCZOS)
                        img.save(img_path, optimize=True, quality=90)


class ProjectVideo(models.Model):
    """Vidéos pour les projets"""
    
    class Meta:
        verbose_name = "Vidéo de projet"
        verbose_name_plural = "Vidéos de projet"
        ordering = ['order']

    VIDEO_TYPE_CHOICES = [
        ('UPLOAD', 'Fichier uploadé'),
        ('YOUTUBE', 'YouTube'),
        ('VIMEO', 'Vimeo'),
    ]

    project = models.ForeignKey(
        Project,
        on_delete=models.CASCADE,
        related_name='videos',
        verbose_name="Projet"
    )
    title = models.CharField(
        max_length=200,
        blank=True,
        verbose_name="Titre de la vidéo"
    )
    description = models.TextField(
        blank=True,
        verbose_name="Description"
    )
    video_type = models.CharField(
        max_length=20,
        choices=VIDEO_TYPE_CHOICES,
        default='UPLOAD',
        verbose_name="Type de vidéo"
    )
    video_file = models.FileField(
        upload_to="projects/videos/",
        blank=True,
        null=True,
        verbose_name="Fichier vidéo",
        help_text="Pour les vidéos uploadées"
    )
    video_url = models.URLField(
        blank=True,
        verbose_name="URL de la vidéo",
        help_text="Pour YouTube ou Vimeo"
    )
    thumbnail = models.ImageField(
        upload_to="projects/video_thumbnails/",
        blank=True,
        null=True,
        verbose_name="Miniature de la vidéo"
    )
    order = models.PositiveIntegerField(
        default=0,
        verbose_name="Ordre d'affichage"
    )
    duration = models.CharField(
        max_length=10,
        blank=True,
        verbose_name="Durée",
        help_text="Ex: 2:30"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date d'ajout"
    )

    def __str__(self):
        return f"{self.project.title} - {self.title}"

    def get_embed_url(self):
        """Retourne l'URL d'embed pour les vidéos externes"""
        if self.video_type == 'YOUTUBE' and self.video_url:
            # Extraire l'ID YouTube
            video_id = None
            if 'watch?v=' in self.video_url:
                video_id = self.video_url.split('watch?v=')[1].split('&')[0]
            elif 'youtu.be/' in self.video_url:
                video_id = self.video_url.split('youtu.be/')[1].split('?')[0]
            
            if video_id:
                return f"https://www.youtube.com/embed/{video_id}"
        
        elif self.video_type == 'VIMEO' and self.video_url:
            # Extraire l'ID Vimeo
            video_id = self.video_url.split('/')[-1]
            return f"https://player.vimeo.com/video/{video_id}"
        
        return None


# ================================
# NOUVEAUX MODÈLES POUR DASHBOARD
# ================================

class DashboardProject(models.Model):
    """Projets pour le dashboard interne"""
    
    class Meta:
        verbose_name = "Projet Dashboard"
        verbose_name_plural = "Projets Dashboard"
        ordering = ['-created_at']

    STATUS_CHOICES = [
        ('PLANNING', 'En planification'),
        ('IN_PROGRESS', 'En cours'),
        ('COMPLETED', 'Terminé'),
        ('ON_HOLD', 'En pause'),
    ]

    title = models.CharField(
        max_length=200,
        verbose_name="Titre du projet"
    )
    description = HTMLField(
        verbose_name="Description",
        help_text="Description détaillée du projet"
    )
    client = models.ForeignKey(
        'userapp.CostumUser',
        on_delete=models.CASCADE,
        limit_choices_to={'type': 'CLIENT'},
        related_name='dashboard_projects',
        verbose_name="Client"
    )
    assigned_technicians = models.ManyToManyField(
        'userapp.CostumUser',
        limit_choices_to={'type': 'TECHNICIEN'},
        related_name='assigned_projects',
        blank=True,
        verbose_name="Techniciens assignés"
    )
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='PLANNING',
        verbose_name="Statut"
    )
    # Nouvelle catégorisation et type de projet
    category = models.ForeignKey(
        ProjectCategory,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='dashboard_projects',
        verbose_name="Catégorie"
    )
    PROJECT_TYPE_CHOICES = [
        ('RESIDENTIEL', 'Résidentiel'),
        ('COMMERCIAL', 'Commercial'),
        ('INDUSTRIEL', 'Industriel'),
        ('INSTITUTIONNEL', 'Institutionnel'),
        ('AUTRE', 'Autre'),
    ]
    project_type = models.CharField(
        max_length=20,
        choices=PROJECT_TYPE_CHOICES,
        default='RESIDENTIEL',
        verbose_name="Type de projet"
    )
    start_date = models.DateField(
        blank=True,
        null=True,
        verbose_name="Date de début"
    )
    end_date = models.DateField(
        blank=True,
        null=True,
        verbose_name="Date de fin prévue"
    )
    budget = models.BigIntegerField(
        blank=True,
        null=True,
        verbose_name="Budget (FCFA)"
    )
    created_by = models.ForeignKey(
        'userapp.CostumUser',
        on_delete=models.CASCADE,
        related_name='created_projects',
        verbose_name="Créé par"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date de création"
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name="Dernière modification"
    )

    def __str__(self):
        return f"{self.title} - {self.client.user.get_full_name()}"

    @property
    def activities_count(self):
        return self.activities.count()

    @property
    def completion_percentage(self):
        total_activities = self.activities.count()
        if total_activities == 0:
            return 0
        completed_activities = self.activities.filter(is_completed=True).count()
        return int((completed_activities / total_activities) * 100)
    
    @property
    def all_drh_users(self):
        """Retourne tous les utilisateurs DRH pour l'assignation d'activités"""
        from userapp.models import CostumUser
        return CostumUser.objects.filter(type='DRH').select_related('user')

    # --- Finance KPIs ---
    @property
    def total_decomptes_amount(self):
        agg = self.decomptes.aggregate(s=Sum('amount'))
        return agg['s'] or 0

    @property
    def total_invoices_amount(self):
        agg = self.invoices.aggregate(s=Sum('amount'))
        return agg['s'] or 0

    @property
    def total_payments_amount(self):
        agg = self.payments.aggregate(s=Sum('amount'))
        return agg['s'] or 0

    @property
    def remaining_amount(self):
        if self.budget:
            return max(0, int(self.budget) - (self.total_payments_amount or 0))
        # à défaut de budget, se baser sur décomptes
        base = self.total_decomptes_amount or 0
        return max(0, base - (self.total_payments_amount or 0))

    @property
    def percent_paid(self):
        base = int(self.budget) if self.budget else (self.total_decomptes_amount or 0)
        if not base:
            return 0
        return int(min(100, (self.total_payments_amount or 0) * 100 / base))
    
    # --- KPIs basés sur les activités ---
    @property
    def total_spent_from_activities(self):
        """Somme des budgets des activités terminées"""
        from django.db.models import Sum
        agg = self.activities.filter(
            is_completed=True,
            budget_amount__isnull=False
        ).aggregate(total=Sum('budget_amount'))
        return float(agg['total'] or 0)
    
    @property
    def budget_remaining_from_activities(self):
        """Montant restant (budget du projet - somme dépensée via activités)"""
        if self.budget:
            spent = self.total_spent_from_activities
            return max(0, float(self.budget) - spent)
        return 0
    
    @property
    def budget_usage_percentage(self):
        """Pourcentage du budget utilisé via les activités terminées"""
        if not self.budget or self.budget == 0:
            return 0
        spent = self.total_spent_from_activities
        return min(100, int((spent / float(self.budget)) * 100))


class ProjectActivity(models.Model):
    """Activités liées aux projets"""
    
    class Meta:
        verbose_name = "Activité Projet"
        verbose_name_plural = "Activités Projet"
        ordering = ['-created_at']

    ACTIVITY_TYPES = [
        # Types existants
        ('DESIGN', 'Design/Conception'),
        ('PLANNING', 'Planification'), 
        ('CONSTRUCTION', 'Construction'),
        ('INSPECTION', 'Inspection'),
        ('DOCUMENTATION', 'Documentation'),
        ('MEETING', 'Réunion'),
        ('FACTURE', 'Facture'),
        ('NOTE', 'Note'),
        ('DEVIS', 'Devis'),
        ('JUSTIFICATIF', 'Justificatif'),
        # Nouveaux types alignés ECOLUX CONNECT
        ('ETUDE', 'Étude'),
        ('REALISATION', 'Réalisation'),
        ('CONTROLE', 'Contrôle'),
        ('VALIDATION', 'Validation'),
        ('FINITION', 'Finition'),
        ('LIVRAISON', 'Livraison'),
        ('SAV', 'SAV'),
        ('OTHER', 'Autre'),
    ]

    PRIORITY_CHOICES = [
        ('LOW', 'Basse'),
        ('MEDIUM', 'Moyenne'),
        ('HIGH', 'Haute'),
        ('URGENT', 'Urgent'),
    ]

    project = models.ForeignKey(
        DashboardProject,
        on_delete=models.CASCADE,
        related_name='activities',
        verbose_name="Projet"
    )
    title = models.CharField(
        max_length=200,
        verbose_name="Titre de l'activité"
    )
    activity_type = models.CharField(
        max_length=15,
        choices=ACTIVITY_TYPES,
        verbose_name="Type d'activité"
    )
    description = HTMLField(
        verbose_name="Description",
        help_text="Description détaillée de l'activité"
    )
    is_completed = models.BooleanField(
        default=False,
        verbose_name="Activité terminée"
    )
    due_date = models.DateField(
        blank=True,
        null=True,
        verbose_name="Date d'échéance"
    )
    priority = models.CharField(
        max_length=10,
        choices=PRIORITY_CHOICES,
        default='MEDIUM',
        verbose_name="Priorité"
    )
    created_by = models.ForeignKey(
        'userapp.CostumUser',
        on_delete=models.CASCADE,
        related_name='created_activities',
        verbose_name="Créé par"
    )
    assigned_to = models.ForeignKey(
        'userapp.CostumUser',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='assigned_activities',
        verbose_name="Assigné à"
    )
    assigned_users = models.ManyToManyField(
        'userapp.CostumUser',
        blank=True,
        related_name='assigned_activities_multiple',
        verbose_name="Assigné à (multiple)"
    )
    # Nouveaux champs: hiérarchie, facturation, budget, activation
    parent = models.ForeignKey(
        'self',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='children',
        verbose_name="Activité parente"
    )
    BILLING_TYPE_CHOICES = [
        ('NONE', 'Non facturable'),
        ('MILESTONE', 'Par jalon / décompte'),
        ('FIXED', 'Forfait'),
        ('TIME', 'Au temps (TJM)'),
    ]
    billing_type = models.CharField(
        max_length=12,
        choices=BILLING_TYPE_CHOICES,
        default='NONE',
        verbose_name="Type de facturation"
    )
    budget_amount = models.DecimalField(
        max_digits=14,
        decimal_places=2,
        null=True,
        blank=True,
        validators=[MinValueValidator(0)],
        verbose_name="Budget (FCFA)"
    )
    is_active = models.BooleanField(default=True, verbose_name="Activée")
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date de création"
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name="Dernière modification"
    )

    def __str__(self):
        return f"{self.project.title} - {self.title} ({self.get_activity_type_display()})"

    @property
    def is_overdue(self):
        if self.due_date and not self.is_completed:
            return timezone.now().date() > self.due_date
        return False


class ActivityImage(models.Model):
    """Images liées aux activités"""
    
    class Meta:
        verbose_name = "Image Activité"
        verbose_name_plural = "Images Activité"
        ordering = ['order']

    activity = models.ForeignKey(
        ProjectActivity,
        on_delete=models.CASCADE,
        related_name='images',
        verbose_name="Activité"
    )
    image = models.ImageField(
        upload_to="dashboard/activities/images/",
        verbose_name="Image"
    )
    title = models.CharField(
        max_length=200,
        blank=True,
        verbose_name="Titre de l'image"
    )
    description = models.TextField(
        blank=True,
        verbose_name="Description"
    )
    order = models.PositiveIntegerField(
        default=0,
        verbose_name="Ordre d'affichage"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date d'ajout"
    )

    def __str__(self):
        return f"{self.activity.title} - {self.title or 'Image'}"


class ActivityVideo(models.Model):
    """Vidéos liées aux activités"""
    
    class Meta:
        verbose_name = "Vidéo Activité"
        verbose_name_plural = "Vidéos Activité"
        ordering = ['order']

    VIDEO_TYPES = [
        ('FILE', 'Fichier uploadé'),
        ('YOUTUBE', 'YouTube'),
        ('VIMEO', 'Vimeo'),
    ]

    activity = models.ForeignKey(
        ProjectActivity,
        on_delete=models.CASCADE,
        related_name='videos',
        verbose_name="Activité"
    )
    title = models.CharField(
        max_length=200,
        blank=True,
        verbose_name="Titre de la vidéo"
    )
    video_type = models.CharField(
        max_length=10,
        choices=VIDEO_TYPES,
        default='FILE',
        verbose_name="Type de vidéo"
    )
    video_file = models.FileField(
        upload_to="dashboard/activities/videos/",
        blank=True,
        null=True,
        verbose_name="Fichier vidéo"
    )
    video_url = models.URLField(
        blank=True,
        verbose_name="URL de la vidéo"
    )
    description = models.TextField(
        blank=True,
        verbose_name="Description"
    )
    order = models.PositiveIntegerField(
        default=0,
        verbose_name="Ordre d'affichage"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date d'ajout"
    )

    def __str__(self):
        return f"{self.activity.title} - {self.title or 'Vidéo'}"


class ActivityFile(models.Model):
    """Fichiers liés aux activités"""
    
    class Meta:
        verbose_name = "Fichier Activité"
        verbose_name_plural = "Fichiers Activité"
        ordering = ['-created_at']

    activity = models.ForeignKey(
        ProjectActivity,
        on_delete=models.CASCADE,
        related_name='files',
        verbose_name="Activité"
    )
    title = models.CharField(
        max_length=200,
        verbose_name="Titre du fichier"
    )
    file = models.FileField(
        upload_to="dashboard/activities/files/",
        verbose_name="Fichier"
    )
    description = models.TextField(
        blank=True,
        verbose_name="Description"
    )
    file_size = models.PositiveIntegerField(
        blank=True,
        null=True,
        verbose_name="Taille du fichier (bytes)"
    )
    uploaded_by = models.ForeignKey(
        'userapp.CostumUser',
        on_delete=models.CASCADE,
        related_name='uploaded_files',
        verbose_name="Uploadé par"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date d'upload"
    )

    def __str__(self):
        return f"{self.activity.title} - {self.title}"

    def save(self, *args, **kwargs):
        if self.file:
            self.file_size = self.file.size
        super().save(*args, **kwargs)

    @property
    def file_extension(self):
        if self.file:
            return self.file.name.split('.')[-1].upper()
        return ''

    @property
    def human_readable_size(self):
        if self.file_size:
            for unit in ['B', 'KB', 'MB', 'GB']:
                if self.file_size < 1024.0:
                    return f"{self.file_size:.1f} {unit}"
                self.file_size /= 1024.0
        return '0 B'


# ========================================
# ECOLUX CONNECT: Phases, Sous-phases, Finances, Docs, SAV
# ========================================

class ProjectPhase(models.Model):
    """Phase d'un projet Dashboard (1 à 8)"""

    class Meta:
        verbose_name = "Phase du projet"
        verbose_name_plural = "Phases du projet"
        ordering = ['order']

    PHASE_CHOICES = [
        (1, 'Phase 1 - Études'),
        (2, 'Phase 2 - Fondations'),
        (3, 'Phase 3 - Soubassement'),
        (4, 'Phase 4 - Élévations (Gros Œuvre)'),
        (5, 'Phase 5 - Second Œuvre'),
        (6, 'Phase 6 - Finitions'),
        (7, 'Phase 7 - Livraison'),
        (8, 'Phase 8 - SAV / Garantie'),
    ]

    STATUS_CHOICES = [
        ('NOT_STARTED', 'Non démarrée'),
        ('IN_PROGRESS', 'En cours'),
        ('COMPLETED', 'Terminée'),
        ('ON_HOLD', 'En pause'),
    ]

    project = models.ForeignKey(
        'app.DashboardProject',
        on_delete=models.CASCADE,
        related_name='phases',
        verbose_name="Projet",
    )
    order = models.PositiveSmallIntegerField(
        choices=PHASE_CHOICES,
        verbose_name="Numéro/Phase"
    )
    name = models.CharField(
        max_length=120,
        verbose_name="Nom de la phase"
    )
    status = models.CharField(
        max_length=12,
        choices=STATUS_CHOICES,
        default='NOT_STARTED',
        verbose_name="Statut"
    )
    weight = models.DecimalField(
        max_digits=5,
        decimal_places=2,
        default=0.0,
        validators=[MinValueValidator(0), MaxValueValidator(100)],
        verbose_name="Poids (%)"
    )
    progress_percent = models.PositiveSmallIntegerField(
        default=0,
        validators=[MinValueValidator(0), MaxValueValidator(100)],
        verbose_name="Avancement (%)",
    )
    start_planned = models.DateField(blank=True, null=True, verbose_name="Début (prévu)")
    end_planned = models.DateField(blank=True, null=True, verbose_name="Fin (prévue)")
    start_actual = models.DateField(blank=True, null=True, verbose_name="Début (réel)")
    end_actual = models.DateField(blank=True, null=True, verbose_name="Fin (réelle)")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"{self.project.title} - {self.name}"


class ProjectSubphase(models.Model):
    """Sous-phase d'une phase (ex: Élévations par niveau: RDC, R+1, etc.)"""

    class Meta:
        verbose_name = "Sous-phase"
        verbose_name_plural = "Sous-phases"
        ordering = ['phase', 'order']

    TYPE_CHOICES = [
        ('STANDARD', 'Standard'),
        ('ELEVATION', 'Élévation (niveau)'),
        ('SOUS_SOL', 'Sous-sol'),
    ]

    phase = models.ForeignKey(
        ProjectPhase,
        on_delete=models.CASCADE,
        related_name='subphases',
        verbose_name="Phase"
    )
    name = models.CharField(max_length=120, verbose_name="Nom")
    type = models.CharField(max_length=12, choices=TYPE_CHOICES, default='STANDARD', verbose_name="Type")
    order = models.PositiveSmallIntegerField(default=0, verbose_name="Ordre")
    weight = models.DecimalField(
        max_digits=5,
        decimal_places=2,
        default=0.0,
        validators=[MinValueValidator(0), MaxValueValidator(100)],
        verbose_name="Poids (%)"
    )
    progress_percent = models.PositiveSmallIntegerField(
        default=0,
        validators=[MinValueValidator(0), MaxValueValidator(100)],
        verbose_name="Avancement (%)",
    )
    level_index = models.IntegerField(blank=True, null=True, verbose_name="Indice niveau (ex: 0 pour RDC)")
    level_label = models.CharField(max_length=20, blank=True, verbose_name="Libellé niveau (ex: RDC, R+1)")
    start_planned = models.DateField(blank=True, null=True, verbose_name="Début (prévu)")
    end_planned = models.DateField(blank=True, null=True, verbose_name="Fin (prévue)")
    start_actual = models.DateField(blank=True, null=True, verbose_name="Début (réel)")
    end_actual = models.DateField(blank=True, null=True, verbose_name="Fin (réelle)")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"{self.phase.name} - {self.name}"


class Decompte(models.Model):
    """Décompte financier par projet/phase/sous-phase"""

    class Meta:
        verbose_name = "Décompte"
        verbose_name_plural = "Décomptes"
        ordering = ['-date']

    STATUS_CHOICES = [
        ('DRAFT', 'Brouillon'),
        ('SUBMITTED', 'Soumis'),
        ('APPROVED', 'Approuvé'),
        ('REJECTED', 'Rejeté'),
        ('INVOICED', 'Facturé'),
        ('PAID', 'Payé'),
    ]

    project = models.ForeignKey(DashboardProject, on_delete=models.CASCADE, related_name='decomptes', verbose_name="Projet")
    phase = models.ForeignKey(ProjectPhase, on_delete=models.SET_NULL, blank=True, null=True, related_name='decomptes', verbose_name="Phase")
    subphase = models.ForeignKey(ProjectSubphase, on_delete=models.SET_NULL, blank=True, null=True, related_name='decomptes', verbose_name="Sous-phase")
    label = models.CharField(max_length=180, verbose_name="Libellé")
    amount = models.DecimalField(max_digits=14, decimal_places=2, validators=[MinValueValidator(0)], verbose_name="Montant")
    date = models.DateField(default=datetime.date.today, verbose_name="Date")
    period_start = models.DateField(blank=True, null=True, verbose_name="Période début")
    period_end = models.DateField(blank=True, null=True, verbose_name="Période fin")
    status = models.CharField(max_length=12, choices=STATUS_CHOICES, default='DRAFT', verbose_name="Statut")
    note = models.TextField(blank=True, verbose_name="Note")

    def __str__(self):
        return f"{self.project.title} - {self.label} ({self.amount} FCFA)"


class Invoice(models.Model):
    """Facture liée à un décompte"""

    class Meta:
        verbose_name = "Facture"
        verbose_name_plural = "Factures"
        ordering = ['-date']

    STATUS_CHOICES = [
        ('DRAFT', 'Brouillon'),
        ('SENT', 'Envoyée'),
        ('PAID', 'Payée'),
        ('CANCELLED', 'Annulée'),
    ]

    project = models.ForeignKey(DashboardProject, on_delete=models.CASCADE, related_name='invoices', verbose_name="Projet")
    decompte = models.ForeignKey(Decompte, on_delete=models.SET_NULL, blank=True, null=True, related_name='invoices', verbose_name="Décompte")
    number = models.CharField(max_length=50, verbose_name="Numéro")
    date = models.DateField(default=datetime.date.today, verbose_name="Date")
    due_date = models.DateField(blank=True, null=True, verbose_name="Échéance")
    amount = models.DecimalField(max_digits=14, decimal_places=2, validators=[MinValueValidator(0)], verbose_name="Montant")
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='DRAFT', verbose_name="Statut")
    file = models.FileField(upload_to="dashboard/invoices/", blank=True, null=True, verbose_name="Fichier")
    paid_date = models.DateField(blank=True, null=True, verbose_name="Date de paiement")

    def __str__(self):
        return f"{self.number} - {self.project.title}"


class ProjectPayment(models.Model):
    """Paiement reçu pour un projet (avance, partiel, solde, rétention)"""

    class Meta:
        verbose_name = "Paiement"
        verbose_name_plural = "Paiements"
        ordering = ['-date']

    TYPE_CHOICES = [
        ('ADVANCE', 'Avance'),
        ('PARTIAL', 'Partiel'),
        ('FINAL', 'Solde'),
        ('RETENTION_RELEASE', 'Libération rétention'),
    ]

    METHOD_CHOICES = [
        ('CASH', 'Espèces'),
        ('BANK', 'Virement bancaire'),
        ('CHEQUE', 'Chèque'),
        ('OTHER', 'Autre'),
    ]

    project = models.ForeignKey(DashboardProject, on_delete=models.CASCADE, related_name='payments', verbose_name="Projet")
    decompte = models.ForeignKey(Decompte, on_delete=models.SET_NULL, blank=True, null=True, related_name='payments', verbose_name="Décompte")
    invoice = models.ForeignKey(Invoice, on_delete=models.SET_NULL, blank=True, null=True, related_name='payments', verbose_name="Facture")
    type = models.CharField(max_length=20, choices=TYPE_CHOICES, verbose_name="Type")
    amount = models.DecimalField(max_digits=14, decimal_places=2, validators=[MinValueValidator(0)], verbose_name="Montant")
    date = models.DateField(default=datetime.date.today, verbose_name="Date")
    method = models.CharField(max_length=10, choices=METHOD_CHOICES, default='BANK', verbose_name="Méthode")
    reference = models.CharField(max_length=120, blank=True, verbose_name="Référence")
    note = models.TextField(blank=True, verbose_name="Note")

    def __str__(self):
        return f"{self.project.title} - {self.get_type_display()} - {self.amount} FCFA"


class ProjectRetention(models.Model):
    """Rétention du projet (montant retenu à libérer après SAV)"""

    class Meta:
        verbose_name = "Rétention"
        verbose_name_plural = "Rétentions"

    project = models.OneToOneField(DashboardProject, on_delete=models.CASCADE, related_name='retention', verbose_name="Projet")
    rate_percent = models.PositiveSmallIntegerField(default=5, validators=[MinValueValidator(0), MaxValueValidator(100)], verbose_name="Taux (%)")
    amount_held = models.DecimalField(max_digits=14, decimal_places=2, default=0, validators=[MinValueValidator(0)], verbose_name="Montant retenu")
    is_released = models.BooleanField(default=False, verbose_name="Libérée")
    release_date = models.DateField(blank=True, null=True, verbose_name="Date de libération")
    note = models.TextField(blank=True, verbose_name="Note")

    def __str__(self):
        return f"Rétention - {self.project.title}"


class ProjectDocument(models.Model):
    """Documents du projet avec versioning et publication client"""

    class Meta:
        verbose_name = "Document"
        verbose_name_plural = "Documents"
        ordering = ['-created_at']

    DOC_TYPES = [
        ('PLAN', 'Plan'),
        ('PV', 'Procès-verbal'),
        ('PHOTO', 'Photo'),
        ('VIDEO', 'Vidéo'),
        ('RAPPORT', 'Rapport'),
        ('CONTRAT', 'Contrat'),
        ('AUTRE', 'Autre'),
    ]

    project = models.ForeignKey(DashboardProject, on_delete=models.CASCADE, related_name='documents', verbose_name="Projet")
    phase = models.ForeignKey(ProjectPhase, on_delete=models.SET_NULL, blank=True, null=True, related_name='documents', verbose_name="Phase")
    subphase = models.ForeignKey(ProjectSubphase, on_delete=models.SET_NULL, blank=True, null=True, related_name='documents', verbose_name="Sous-phase")
    title = models.CharField(max_length=180, verbose_name="Titre")
    description = models.TextField(blank=True, verbose_name="Description")
    doc_type = models.CharField(max_length=10, choices=DOC_TYPES, default='PLAN', verbose_name="Type")
    file = models.FileField(upload_to="dashboard/documents/", blank=True, null=True, verbose_name="Fichier")
    tags = models.CharField(max_length=250, blank=True, verbose_name="Tags (séparés par des virgules)")
    is_public = models.BooleanField(default=False, verbose_name="Visible par le client")
    version = models.PositiveIntegerField(default=1, verbose_name="Version")
    previous_version = models.ForeignKey('self', on_delete=models.SET_NULL, blank=True, null=True, related_name='next_versions', verbose_name="Version précédente")
    uploaded_by = models.ForeignKey('userapp.CostumUser', on_delete=models.SET_NULL, blank=True, null=True, related_name='project_documents', verbose_name="Uploadé par")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Créé le")
    published_at = models.DateTimeField(blank=True, null=True, verbose_name="Publié le")

    def __str__(self):
        return f"{self.project.title} - {self.title} (v{self.version})"


class SavWarranty(models.Model):
    """Garantie SAV d'un projet"""

    class Meta:
        verbose_name = "Garantie SAV"
        verbose_name_plural = "Garanties SAV"

    project = models.OneToOneField(DashboardProject, on_delete=models.CASCADE, related_name='sav_warranty', verbose_name="Projet")
    start_date = models.DateField(blank=True, null=True, verbose_name="Début garantie")
    end_date = models.DateField(blank=True, null=True, verbose_name="Fin garantie")
    notes = models.TextField(blank=True, verbose_name="Notes")

    def __str__(self):
        return f"Garantie - {self.project.title}"


class SavTicket(models.Model):
    """Ticket SAV"""

    class Meta:
        verbose_name = "Ticket SAV"
        verbose_name_plural = "Tickets SAV"
        ordering = ['-created_at']

    STATUS_CHOICES = [
        ('OPEN', 'Ouvert'),
        ('IN_PROGRESS', 'En cours'),
        ('RESOLVED', 'Résolu'),
        ('CLOSED', 'Fermé'),
    ]

    PRIORITY_CHOICES = [
        ('LOW', 'Basse'),
        ('MEDIUM', 'Moyenne'),
        ('HIGH', 'Haute'),
        ('URGENT', 'Urgent'),
    ]

    project = models.ForeignKey(DashboardProject, on_delete=models.CASCADE, related_name='sav_tickets', verbose_name="Projet")
    title = models.CharField(max_length=180, verbose_name="Titre")
    description = models.TextField(verbose_name="Description")
    status = models.CharField(max_length=12, choices=STATUS_CHOICES, default='OPEN', verbose_name="Statut")
    priority = models.CharField(max_length=10, choices=PRIORITY_CHOICES, default='MEDIUM', verbose_name="Priorité")
    opened_by = models.ForeignKey('userapp.CostumUser', on_delete=models.SET_NULL, blank=True, null=True, related_name='sav_opened', verbose_name="Ouvert par")
    assigned_to = models.ForeignKey('userapp.CostumUser', on_delete=models.SET_NULL, blank=True, null=True, related_name='sav_assigned', verbose_name="Assigné à")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Créé le")
    closed_at = models.DateTimeField(blank=True, null=True, verbose_name="Clôturé le")

    def __str__(self):
        return f"SAV - {self.project.title} - {self.title}"


class SavRepairPV(models.Model):
    """Procès-verbal de réparation SAV"""

    class Meta:
        verbose_name = "PV de réparation"
        verbose_name_plural = "PV de réparation"

    ticket = models.ForeignKey(SavTicket, on_delete=models.CASCADE, related_name='repair_pvs', verbose_name="Ticket")
    description = models.TextField(blank=True, verbose_name="Description")
    date = models.DateField(default=datetime.date.today, verbose_name="Date")
    file = models.FileField(upload_to="dashboard/sav/pv/", blank=True, null=True, verbose_name="Fichier")
    signed_by_client = models.CharField(max_length=120, blank=True, verbose_name="Signé par (client)")
    signed_by_staff = models.CharField(max_length=120, blank=True, verbose_name="Signé par (équipe)")

    def __str__(self):
        return f"PV SAV - {self.ticket.project.title} - {self.ticket.title}"


class Testimonial(models.Model):
    """Témoignages clients"""
    
    class Meta:
        verbose_name = "Témoignage"
        verbose_name_plural = "Témoignages"
        ordering = ['order', '-created_at']

    author = models.CharField(
        max_length=100,
        verbose_name="Nom du client"
    )
    role = models.CharField(
        max_length=100,
        blank=True,
        verbose_name="Rôle/Position"
    )
    quote = models.TextField(
        verbose_name="Témoignage"
    )
    photo = models.ImageField(
        upload_to="testimonials/",
        blank=True,
        null=True,
        verbose_name="Photo du client"
    )
    is_active = models.BooleanField(
        default=True,
        verbose_name="Actif"
    )
    order = models.PositiveIntegerField(
        default=0,
        verbose_name="Ordre d'affichage"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Date de création"
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name="Date de modification"
    )

    def __str__(self):
        return f"Témoignage de {self.author}"

    def save(self, *args, **kwargs):
        # Redimensionner l'image si elle est trop grande
        super().save(*args, **kwargs)
        if self.photo:
            img_path = self.photo.path
            if os.path.exists(img_path):
                with Image.open(img_path) as img:
                    if img.height > 300 or img.width > 300:
                        img.thumbnail((300, 300), Image.LANCZOS)
                        img.save(img_path)


# ========================================
# BOUTIQUE (Produits & Catégories)
# ========================================

class ProductCategory(models.Model):
    """Catégories de produits pour la boutique ECOLUX"""
    class Meta:
        verbose_name = "Catégorie de produit"
        verbose_name_plural = "Catégories de produits"
        ordering = ["order", "name"]

    name = models.CharField(max_length=150, unique=True, verbose_name="Nom")
    slug = models.SlugField(max_length=160, unique=True, verbose_name="Slug")
    description = models.TextField(blank=True, verbose_name="Description")
    icon = models.CharField(max_length=50, blank=True, verbose_name="Icône")
    image = models.ImageField(upload_to="shop/categories/", blank=True, null=True, verbose_name="Image")
    order = models.PositiveIntegerField(default=0, verbose_name="Ordre")
    is_active = models.BooleanField(default=True, verbose_name="Active")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Créé le")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="Mis à jour le")

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)
        if self.image:
            img_path = self.image.path
            if os.path.exists(img_path):
                with Image.open(img_path) as img:
                    if img.width > 800 or img.height > 800:
                        img.thumbnail((800, 800), Image.Resampling.LANCZOS)
                        img.save(img_path, optimize=True, quality=85)

    def get_absolute_url(self):
        return reverse('app:shop_category', kwargs={'slug': self.slug})


class Product(models.Model):
    """Produits vendus via la boutique (achat via WhatsApp)"""
    class Meta:
        verbose_name = "Produit"
        verbose_name_plural = "Produits"
        ordering = ['-created_at']

    STATUS_CHOICES = [
        ('ACTIVE', 'Actif'),
        ('HIDDEN', 'Caché'),
        ('ARCHIVED', 'Archivé'),
    ]

    category = models.ForeignKey(ProductCategory, on_delete=models.SET_NULL, null=True, blank=True, related_name='products', verbose_name="Catégorie")
    name = models.CharField(max_length=200, verbose_name="Nom du produit")
    slug = models.SlugField(max_length=220, unique=True, verbose_name="Slug")
    short_description = models.CharField(max_length=300, blank=True, verbose_name="Description courte")
    description = HTMLField(blank=True, verbose_name="Description détaillée")
    image = models.ImageField(upload_to="shop/products/", blank=True, null=True, verbose_name="Image principale")
    gallery = models.JSONField(default=list, blank=True, verbose_name="Galerie (URLs)")
    price = models.DecimalField(max_digits=12, decimal_places=2, verbose_name="Prix", validators=[MinValueValidator(0)])
    currency = models.CharField(max_length=10, default='FCFA', verbose_name="Devise")
    stock = models.PositiveIntegerField(default=0, verbose_name="Stock disponible")
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='ACTIVE', verbose_name="Statut")
    is_featured = models.BooleanField(default=False, verbose_name="En vedette")
    whatsapp_message_template = models.CharField(max_length=300, blank=True, verbose_name="Template message WhatsApp", help_text="Variables: {product} {price} {currency}")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Créé le")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="Mis à jour le")

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        if not self.whatsapp_message_template:
            self.whatsapp_message_template = "Bonjour ECOLUX, je souhaite avoir plus d'informations sur le produit '{product}' au prix de {price} {currency}."
        super().save(*args, **kwargs)
        if self.image:
            img_path = self.image.path
            if os.path.exists(img_path):
                with Image.open(img_path) as img:
                    if img.width > 1000 or img.height > 1000:
                        img.thumbnail((1000, 1000), Image.Resampling.LANCZOS)
                        img.save(img_path, optimize=True, quality=85)

    def get_absolute_url(self):
        return reverse('app:product_detail', kwargs={'slug': self.slug})

    @property
    def whatsapp_message(self):
        return self.whatsapp_message_template.format(product=self.name, price=int(self.price), currency=self.currency)

    @property
    def is_available(self):
        return self.status == 'ACTIVE' and self.stock > 0

    def price_formatted(self):
        return f"{int(self.price):,}".replace(',', ' ')

