"""
Валидаторы и утилиты для оценки качества изображений товаров.

Система полностью гибкая - все параметры читаются из settings:
- Пороги качества из IMAGE_QUALITY_LEVELS
- Описания из IMAGE_QUALITY_LABELS
- Максимальные размеры из IMAGE_PROCESSING_CONFIG

Это позволяет менять поведение без изменения кода.
"""

from django.conf import settings
from django.core.exceptions import ValidationError
from PIL import Image
import logging

logger = logging.getLogger(__name__)


def get_max_dimension_from_config():
    """
    Динамически читает максимальный размер из IMAGE_PROCESSING_CONFIG.

    Получает max_width и max_height из original формата и возвращает максимальное значение.

    Returns:
        int: Максимальный размер оригинального изображения (из settings)

    Examples:
        >>> get_max_dimension_from_config()
        2160  # если original.max_width=2160 и original.max_height=2160
    """
    config = settings.IMAGE_PROCESSING_CONFIG
    original_config = config.get('formats', {}).get('original', {})

    # Получаем параметры с дефолтными значениями
    max_width = original_config.get('max_width', 2160)
    max_height = original_config.get('max_height', 2160)

    # Возвращаем максимальное значение
    max_dimension = max(max_width, max_height)

    logger.debug(f"Max dimension from config: {max_dimension}px")
    return max_dimension


def get_image_quality_level(width, height):
    """
    Определяет уровень качества изображения на основе его размеров.

    Логика:
    1. Берет минимальное измерение (ширина или высота)
    2. Вычисляет его как процент от максимального размера (из settings)
    3. Сравнивает с пороги из IMAGE_QUALITY_LEVELS
    4. Возвращает уровень качества и флаг требует ли обновления

    Args:
        width (int): Ширина изображения в пиксели
        height (int): Высота изображения в пиксели

    Returns:
        tuple: (quality_level, needs_update)
            quality_level (str): Один из: 'excellent', 'good', 'acceptable', 'poor', 'very_poor'
            needs_update (bool): True если требует обновления перед выгрузкой

    Examples:
        >>> get_image_quality_level(2160, 2160)
        ('excellent', False)

        >>> get_image_quality_level(1400, 1400)  # если max=2160
        ('good', False)  # 1400/2160 = 0.648 >= 0.70? НЕТ, но >= 0.40 (acceptable)

        >>> get_image_quality_level(800, 800)  # если max=2160
        ('acceptable', False)  # 800/2160 = 0.370 >= 0.40? НЕТ, но >= 0.20 (poor)
    """
    min_dimension = min(width, height)
    max_dimension = get_max_dimension_from_config()

    # Читаем пороги из settings с fallback значениями
    quality_levels = getattr(settings, 'IMAGE_QUALITY_LEVELS', {
        'excellent': 0.95,
        'good': 0.70,
        'acceptable': 0.40,
        'poor': 0.20,
    })

    # Вычисляем процент от максимума
    quality_percent = min_dimension / max_dimension

    logger.debug(f"Image size: {width}x{height}px, Quality: {quality_percent:.1%} of max {max_dimension}px")

    # Определяем уровень качества
    # 'poor' и 'very_poor' требуют обновления перед выгрузкой на сайт
    if quality_percent >= quality_levels.get('excellent', 0.95):
        return 'excellent', False
    elif quality_percent >= quality_levels.get('good', 0.70):
        return 'good', False
    elif quality_percent >= quality_levels.get('acceptable', 0.40):
        return 'acceptable', False
    elif quality_percent >= quality_levels.get('poor', 0.20):
        return 'poor', True  # ← Требует обновления
    else:
        return 'very_poor', True  # ← Требует обновления


def get_quality_info(quality_level):
    """
    Получить полную информацию о уровне качества.

    Читает описание, цвет, иконку и рекомендацию из IMAGE_QUALITY_LABELS в settings.

    Args:
        quality_level (str): Уровень качества ('excellent', 'good', 'acceptable', 'poor', 'very_poor')

    Returns:
        dict: Информация о уровне с ключами:
            - label: Название уровня
            - short_label: Краткое название с иконкой
            - description: Описание
            - color: Цвет для UI (success, info, warning, danger)
            - icon: Иконка (✓, ◐, ⚠, ✗)
            - recommendation: Рекомендация для пользователя
            - badge_class: CSS класс для бутстрапа

    Examples:
        >>> get_quality_info('excellent')
        {'label': 'Отлично', 'color': 'success', ...}

        >>> get_quality_info('poor')
        {'label': 'Плохо', 'color': 'danger', ...}
    """
    labels = getattr(settings, 'IMAGE_QUALITY_LABELS', {})
    default_info = {
        'label': 'Неизвестно',
        'short_label': 'Неизвестно',
        'description': 'Не удалось определить качество',
        'color': 'secondary',
        'icon': '?',
        'recommendation': 'Обновите изображение',
        'badge_class': 'badge-secondary',
    }
    return labels.get(quality_level, default_info)


def validate_product_image(image_file):
    """
    Валидация изображения товара.

    Проверяет что файл является валидным изображением и может быть открыт.
    Не отклоняет маленькие изображения - просто определяет их качество.

    Args:
        image_file: Django UploadedFile объект

    Returns:
        dict: Результат валидации с ключами:
            - valid (bool): Прошло ли валидацию
            - width (int): Ширина изображения
            - height (int): Высота изображения
            - quality_level (str): Уровень качества
            - needs_update (bool): Требует ли обновления
            - message (str): Сообщение для пользователя
            - error (str): Сообщение об ошибке (если valid=False)

    Raises:
        ValidationError: Если файл не является изображением
    """
    try:
        # Открываем изображение для получения размеров
        img = Image.open(image_file)
        width, height = img.size

        # Определяем качество
        quality_level, needs_update = get_image_quality_level(width, height)
        quality_info = get_quality_info(quality_level)

        # Подготавливаем сообщение для пользователя
        message = (
            f"Размер изображения: {width}×{height}px. "
            f"Качество: {quality_info['label']} - {quality_info['description']}."
        )

        if needs_update:
            message += f" {quality_info['recommendation']}"

        logger.info(f"Image validation: {width}x{height}px → {quality_level}")

        return {
            'valid': True,
            'width': width,
            'height': height,
            'quality_level': quality_level,
            'needs_update': needs_update,
            'message': message,
            'error': None,
        }

    except Exception as e:
        error_msg = f"Не удалось обработать изображение: {str(e)}"
        logger.error(f"Image validation error: {str(e)}", exc_info=True)

        return {
            'valid': False,
            'width': None,
            'height': None,
            'quality_level': None,
            'needs_update': False,
            'message': None,
            'error': error_msg,
        }


def get_quality_level_percentage(quality_level):
    """
    Получить процент от максимума для уровня качества.

    Используется для визуализации прогресс-баров в UI.

    Args:
        quality_level (str): Уровень качества

    Returns:
        float: Процент от максимума (0.0 - 1.0)
    """
    quality_levels = getattr(settings, 'IMAGE_QUALITY_LEVELS', {
        'excellent': 0.95,
        'good': 0.70,
        'acceptable': 0.40,
        'poor': 0.20,
    })

    if quality_level == 'very_poor':
        return 0.1  # Визуально покажет как очень мало

    return quality_levels.get(quality_level, 0.5)
