"""
Сервис для получения URL изображений разных размеров.
Используется в шаблонах и представлениях для удобного доступа к разным версиям.
"""
import os
import logging
from django.conf import settings
from django.core.files.storage import default_storage

logger = logging.getLogger(__name__)


class ImageService:
    """
    Сервис для работы с изображениями разных размеров.
    Динамически строит URL на основе пути к оригинальному файлу.

    МУЛЬТИТЕНАНТНОСТЬ:
    На диске файлы хранятся как: tenants/{tenant_id}/products/{entity_id}/{photo_id}/{size}.ext
    В БД сохраняется путь БЕЗ tenant_id: products/{entity_id}/{photo_id}/{size}.ext
    TenantAwareFileSystemStorage автоматически добавляет/удаляет tenant_id при работе с файлами.
    ImageService работает с путями из БД и генерирует URL, при необходимости системе видны файлы только своего тенанта.
    """

    # Константы для маппинга форматов и расширений файлов
    FORMAT_EXTENSIONS = {
        'JPEG': 'jpg',
        'WEBP': 'webp',
        'PNG': 'png',
    }

    @staticmethod
    def _get_config():
        """Получить конфигурацию из settings"""
        return getattr(settings, 'IMAGE_PROCESSING_CONFIG', {})

    @staticmethod
    def _get_format_config(size_key):
        """Получить конфигурацию формата для заданного типа изображения"""
        config = ImageService._get_config()
        formats = config.get('formats', {})
        return formats.get(size_key, {'format': 'JPEG', 'quality': 90})

    @staticmethod
    def _get_file_extension(image_format):
        """Получить расширение файла для заданного формата"""
        return ImageService.FORMAT_EXTENSIONS.get(image_format, 'jpg')

    @staticmethod
    def _normalize_size_name(size_key):
        """Преобразовать 'thumbnail' в 'thumb' для имени файла"""
        return 'thumb' if size_key == 'thumbnail' else size_key

    @staticmethod
    def get_url(original_image_path, size='medium'):
        """
        Получает URL изображения нужного размера.

        Структура хранения: base_path/entity_id/photo_id/size.ext
        Пример: products/123/456/medium.webp

        Args:
            original_image_path: Путь к оригинальному файлу (из models.image)
                                 Пример: products/123/456/original.jpg
            size: Размер ('original', 'large', 'medium', 'thumbnail')
                 По умолчанию 'medium'

        Returns:
            str: URL изображения нужного размера, или оригинал если размер не найден
        """
        if not original_image_path:
            return ''

        try:
            path_str = str(original_image_path)
            parts = path_str.split('/')

            if len(parts) < 3:
                return default_storage.url(path_str)

            # Если изображение во временной папке (еще не обработано)
            # Возвращаем оригинал, так как других размеров еще нет
            if 'temp' in parts:
                return default_storage.url(path_str)

            # Если запрашивается оригинал, возвращаем его напрямую
            if size == 'original':
                return default_storage.url(path_str)

            # Извлекаем base_path, entity_id, photo_id из пути
            base_path = parts[0]  # products, kits, categories
            entity_id = parts[1]  # ID сущности
            photo_id = parts[2]   # ID фото

            # Определяем расширение из конфигурации
            format_config = ImageService._get_format_config(size)
            image_format = format_config.get('format', 'JPEG')
            extension = ImageService._get_file_extension(image_format)

            # Преобразуем thumbnail в thumb
            final_size_name = ImageService._normalize_size_name(size)

            # Создаем путь и используем storage.url() для корректной работы с tenant-aware storage
            file_path = f"{base_path}/{entity_id}/{photo_id}/{final_size_name}.{extension}"

            # Используем default_storage.url() для корректной работы с TenantAwareFileSystemStorage
            # Это гарантирует что URL будет содержать tenant_id если необходимо
            # Проверяем существование файла - если не найден, возвращаем оригинал как fallback
            if default_storage.exists(file_path):
                url = default_storage.url(file_path)
                logger.debug(f"[ImageService] Returning {size} URL: {file_path} -> {url}")
                return url
            else:
                # Файл нужного размера не найден - возвращаем оригинал как fallback
                # (файл может быть загружен до внедрения системы обработки или обработка не завершена)
                logger.warning(f"[ImageService] {size} file not found: {file_path}, using original as fallback")
                return default_storage.url(str(original_image_path))

        except Exception as e:
            # В случае ошибки возвращаем оригинал
            logger.warning(f"[ImageService] Error getting {size} URL: {e}, using original as fallback")
            try:
                return default_storage.url(str(original_image_path))
            except Exception:
                return ''

    @staticmethod
    def get_thumbnail_url(original_image_path):
        """Получить URL миниатюры (150x150)"""
        return ImageService.get_url(original_image_path, 'thumbnail')

    @staticmethod
    def get_medium_url(original_image_path):
        """Получить URL среднего размера (400x400)"""
        return ImageService.get_url(original_image_path, 'medium')

    @staticmethod
    def get_large_url(original_image_path):
        """Получить URL большого размера (800x800)"""
        return ImageService.get_url(original_image_path, 'large')

    @staticmethod
    def get_original_url(original_image_path):
        """Получить URL оригинального изображения"""
        return ImageService.get_url(original_image_path, 'original')

    @staticmethod
    def get_all_urls(original_image_path):
        """
        Получить все версии изображения.

        Returns:
            dict: {'original': url, 'thumbnail': url, 'medium': url, 'large': url}
        """
        return {
            'original': ImageService.get_original_url(original_image_path),
            'thumbnail': ImageService.get_thumbnail_url(original_image_path),
            'medium': ImageService.get_medium_url(original_image_path),
            'large': ImageService.get_large_url(original_image_path),
        }
