"""
Utilitaires pour les IDs courts et autres fonctionnalités core
"""

import uuid
import string
import secrets
from django.db import models


class ShortUUIDField(models.CharField):
    """
    Champ personnalisé pour générer des IDs courts basés sur UUID
    Utilise base62 pour réduire la longueur à ~22 caractères
    """

    def __init__(self, *args, **kwargs):
        kwargs.setdefault("max_length", 22)
        kwargs.setdefault("unique", True)
        kwargs.setdefault("editable", False)
        kwargs.setdefault("default", self.generate_short_uuid)
        super().__init__(*args, **kwargs)

    @staticmethod
    def generate_short_uuid():
        """Génère un UUID court en base62"""
        return uuid_to_base62(uuid.uuid4())


def uuid_to_base62(uuid_obj):
    """
    Convertit un UUID en string base62 (plus court)
    """
    # Caractères autorisés en base62
    alphabet = string.ascii_letters + string.digits  # a-z, A-Z, 0-9 = 62 caractères

    # Convertir UUID en entier
    uuid_int = uuid_obj.int

    # Convertir en base62
    if uuid_int == 0:
        return alphabet[0]

    result = []
    while uuid_int > 0:
        uuid_int, remainder = divmod(uuid_int, 62)
        result.append(alphabet[remainder])

    return "".join(reversed(result))


def base62_to_uuid(base62_string):
    """
    Convertit un string base62 en UUID
    """
    alphabet = string.ascii_letters + string.digits

    # Convertir base62 en entier
    result = 0
    for char in base62_string:
        result = result * 62 + alphabet.index(char)

    # Convertir en UUID
    return uuid.UUID(int=result)

def generate_nano_id(length=10, segments=None):
    """
    Génère un Nano ID de longueur spécifiée avec segments optionnels
    Plus court mais moins d'unicité que UUID
    
    Args:
        length: Longueur totale (sans compter les tirets)
        segments: Tuple définissant la taille des segments, ex: (4, 4, 4) pour xxxx-xxxx-xxxx
    
    Examples:
        generate_nano_id(10) -> 'v1stgxr8z5'
        generate_nano_id(12, (4, 4, 4)) -> 'v1st-gxr8-z5jh'
        generate_nano_id(15, (5, 5, 5)) -> 'v1stg-xr8z5-jh3k2'
    """
    # Alphabet sans tirets pour éviter la confusion
    alphabet = string.ascii_lowercase + string.digits
    
    # Générer les caractères
    chars = [secrets.choice(alphabet) for _ in range(length)]
    
    if segments:
        # Créer des segments
        result = []
        char_index = 0
        for segment_size in segments:
            if char_index >= len(chars):
                break
            segment = ''.join(chars[char_index:char_index + segment_size])
            result.append(segment)
            char_index += segment_size
        return '-'.join(result)
    else:
        return ''.join(chars)
    return "".join(secrets.choice(alphabet) for _ in range(length))


def generate_prefixed_id(prefix, length=6):
    """
    Génère un ID avec préfixe et numéro
    Exemple: USR-000001, TXN-123456
    """
    # Utiliser un compteur basé sur timestamp + random pour éviter les collisions
    import time

    timestamp = int(time.time() * 1000) % (10**length)
    return f"{prefix}-{timestamp:0{length}d}"


class CompactUUIDField(models.CharField):
    """
    Champ UUID compact (sans tirets) - 32 caractères au lieu de 36
    """

    def __init__(self, *args, **kwargs):
        kwargs.setdefault("max_length", 32)
        kwargs.setdefault("unique", True)
        kwargs.setdefault("editable", False)
        kwargs.setdefault("default", self.generate_compact_uuid)
        super().__init__(*args, **kwargs)

    @staticmethod
    def generate_compact_uuid():
        """Génère un UUID sans tirets"""
        return str(uuid.uuid4()).replace("-", "")


class NanoIDField(models.CharField):
    """
    Champ Nano ID - IDs très courts mais avec moins d'unicité
    """


# Exemples d'utilisation:
"""
# Dans un modèle Django:

class ExampleModel(BaseModel):
    # Option 1: UUID court base62 (~22 chars)
    id = ShortUUIDField(primary_key=True)
    
    # Option 2: UUID compact sans tirets (32 chars)
    # id = CompactUUIDField(primary_key=True)
    
    # Option 3: Nano ID très court (10-12 chars)
    # id = NanoIDField(length=12, primary_key=True)
    
    name = models.CharField(max_length=100)

# Usage:
>>> obj = ExampleModel.objects.create(name="Test")
>>> obj.id
'4f3k2m9n8p1q6r5s7t0u3v'  # Short UUID

# URL plus courte:
# /api/accounts/4f3k2m9n8p1q6r5s7t0u3v/
# au lieu de:
# /api/accounts/f47ac10b-58cc-4372-a567-0e02b2c3d479/
"""
