"""
Утилиты для генерации артикулов (SKU) для товаров, комплектов и категорий.

Формат артикулов:
- Товары: PROD-XXXXXX
- Комплекты: KIT-XXXXXX
- Категории: CAT-XXXX
- Вариативные товары: VAR-XXXXXX

Примеры:
- PROD-000001
- KIT-000001
- CAT-0001
- VAR-000001
"""
from string import ascii_uppercase


def ensure_sku_unique(base_sku, exclude_id=None, model_type=None):
    """
    Проверяет уникальность артикула и добавляет буквенный суффикс при конфликте.

    Если артикул уже существует:
    PROD-000001 -> PROD-000001A -> PROD-000001B -> ... -> PROD-000001Z

    Аргументы:
        base_sku (str): Базовый артикул для проверки
        exclude_id (int): ID товара/комплекта/категории/вариативного товара, который нужно исключить из проверки
        model_type (str): Тип модели ('product', 'kit', 'category', 'configurable') для исключения из проверки

    Возвращает:
        str: Уникальный артикул
    """
    from products.models import Product, ProductKit, ProductCategory, ConfigurableProduct

    # Проверяем, существует ли базовый артикул
    sku = base_sku

    # Проверка во всех моделях с артикулами
    def sku_exists(sku_to_check):
        product_exists = Product.objects.filter(sku=sku_to_check)
        if model_type == 'product' and exclude_id:
            product_exists = product_exists.exclude(id=exclude_id)
        product_exists = product_exists.exists()

        kit_exists = ProductKit.objects.filter(sku=sku_to_check)
        if model_type == 'kit' and exclude_id:
            kit_exists = kit_exists.exclude(id=exclude_id)
        kit_exists = kit_exists.exists()

        category_exists = ProductCategory.objects.filter(sku=sku_to_check)
        if model_type == 'category' and exclude_id:
            category_exists = category_exists.exclude(id=exclude_id)
        category_exists = category_exists.exists()

        configurable_exists = ConfigurableProduct.objects.filter(sku=sku_to_check)
        if model_type == 'configurable' and exclude_id:
            configurable_exists = configurable_exists.exclude(id=exclude_id)
        configurable_exists = configurable_exists.exists()

        return product_exists or kit_exists or category_exists or configurable_exists

    # Если базовый артикул свободен, возвращаем его
    if not sku_exists(sku):
        return sku

    # Иначе добавляем буквы A-Z
    for letter in ascii_uppercase:
        sku_with_letter = f"{base_sku}{letter}"
        if not sku_exists(sku_with_letter):
            return sku_with_letter

    # Если все буквы заняты (маловероятно), добавляем AA, AB, и т.д.
    for first_letter in ascii_uppercase:
        for second_letter in ascii_uppercase:
            sku_with_letters = f"{base_sku}{first_letter}{second_letter}"
            if not sku_exists(sku_with_letters):
                return sku_with_letters

    # В крайнем случае возвращаем базовый + timestamp
    from django.utils import timezone
    return f"{base_sku}-{timezone.now().strftime('%Y%m%d%H%M%S')}"


def generate_product_sku(product):
    """
    Генерирует уникальный артикул для товара.

    Формат: PROD-XXXXXX

    Аргументы:
        product: Экземпляр модели Product

    Возвращает:
        str: Сгенерированный артикул
    """
    from products.models import SKUCounter

    # FIX: SKU counter bug - increment only after successful save
    # Получаем следующий номер БЕЗ инкремента
    # Инкремент выполнится в post_save сигнале после успешного сохранения
    next_number = SKUCounter.peek_next_value('product')

    # Форматируем номер с ведущими нулями (6 цифр)
    base_sku = f"PROD-{next_number:06d}"

    # Обеспечиваем уникальность
    unique_sku = ensure_sku_unique(base_sku, exclude_id=product.id if product.id else None, model_type='product')

    return unique_sku


def generate_kit_sku():
    """
    Генерирует уникальный артикул для комплекта.

    Формат: KIT-XXXXXX

    Возвращает:
        str: Сгенерированный артикул
    """
    from products.models import SKUCounter

    # Получаем следующий номер из глобального счетчика
    next_number = SKUCounter.get_next_value('kit')

    # Форматируем номер с ведущими нулями (6 цифр)
    base_sku = f"KIT-{next_number:06d}"

    # Обеспечиваем уникальность
    unique_sku = ensure_sku_unique(base_sku, model_type='kit')

    return unique_sku


def generate_category_sku():
    """
    Генерирует уникальный артикул для категории.

    Формат: CAT-XXXX (4 цифры)

    Возвращает:
        str: Сгенерированный артикул
    """
    from products.models import SKUCounter

    # Получаем следующий номер из глобального счетчика
    next_number = SKUCounter.get_next_value('category')

    # Форматируем номер с ведущими нулями (4 цифры)
    base_sku = f"CAT-{next_number:04d}"

    # Обеспечиваем уникальность
    unique_sku = ensure_sku_unique(base_sku, model_type='category')

    return unique_sku


def generate_configurable_sku():
    """
    Генерирует уникальный артикул для вариативного товара.

    Формат: VAR-XXXXXX

    Возвращает:
        str: Сгенерированный артикул
    """
    from products.models import SKUCounter

    # Получаем следующий номер из глобального счетчика
    next_number = SKUCounter.get_next_value('configurable')

    # Форматируем номер с ведущими нулями (6 цифр)
    base_sku = f"VAR-{next_number:06d}"

    # Обеспечиваем уникальность
    unique_sku = ensure_sku_unique(base_sku, model_type='configurable')

    return unique_sku
