# -*- coding: utf-8 -*-
"""
Сервис для управления единицами измерения.

Отвечает за создание и управление справочником единиц измерения (UnitOfMeasure).
"""
import logging
from typing import List, Dict, Any

logger = logging.getLogger(__name__)


class UnitOfMeasureService:
    """
    Сервис для управления единицами измерения.
    
    Предоставляет методы для создания и управления базовыми единицами измерения,
    которые используются в системе для товаров и продаж.
    """
    
    # Базовый набор единиц измерения для новых тенантов
    DEFAULT_UNITS = [
        # Базовые единицы (из старых UNIT_CHOICES)
        {'code': 'шт', 'name': 'Штука', 'short_name': 'шт.', 'position': 1},
        {'code': 'м', 'name': 'Метр', 'short_name': 'м.', 'position': 2},
        {'code': 'г', 'name': 'Грамм', 'short_name': 'г.', 'position': 3},
        {'code': 'л', 'name': 'Литр', 'short_name': 'л.', 'position': 4},
        {'code': 'кг', 'name': 'Килограмм', 'short_name': 'кг.', 'position': 5},
        
        # Флористические единицы
        {'code': 'банч', 'name': 'Банч', 'short_name': 'банч', 'position': 10},
        {'code': 'ветка', 'name': 'Ветка', 'short_name': 'вет.', 'position': 11},
        {'code': 'пучок', 'name': 'Пучок', 'short_name': 'пуч.', 'position': 12},
        {'code': 'коробка', 'name': 'Коробка', 'short_name': 'кор.', 'position': 13},
    ]
    
    @classmethod
    def create_default_units(cls) -> List:
        """
        Создает базовый набор единиц измерения для тенанта.
        
        Использует get_or_create, поэтому безопасно вызывать повторно.
        
        Returns:
            List[UnitOfMeasure]: Список созданных/существующих единиц измерения
        """
        from products.models import UnitOfMeasure
        
        created_units = []
        
        for unit_data in cls.DEFAULT_UNITS:
            unit, created = UnitOfMeasure.objects.get_or_create(
                code=unit_data['code'],
                defaults={
                    'name': unit_data['name'],
                    'short_name': unit_data['short_name'],
                    'position': unit_data['position'],
                    'is_active': True,
                }
            )
            created_units.append(unit)
            
            if created:
                logger.debug(f"Создана единица измерения: {unit.code} - {unit.name}")
        
        logger.info(f"Инициализация единиц измерения завершена: {len(created_units)} единиц")
        return created_units
    
    @classmethod
    def reset_default_units(cls) -> List:
        """
        Удаляет все единицы измерения и создаёт их заново.
        
        ВНИМАНИЕ: Используйте только при инициализации тенанта или в тестах!
        Удаление единиц может нарушить связи с существующими товарами.
        
        Returns:
            List[UnitOfMeasure]: Список созданных единиц измерения
        """
        from products.models import UnitOfMeasure
        
        logger.warning("Удаление всех единиц измерения...")
        UnitOfMeasure.objects.all().delete()
        
        return cls.create_default_units()
    
    @classmethod
    def get_or_create_unit(cls, code: str, name: str, short_name: str, 
                          position: int = 0) -> tuple:
        """
        Получает или создаёт единицу измерения.
        
        Args:
            code: Уникальный код единицы
            name: Полное название
            short_name: Короткое название для UI
            position: Позиция для сортировки
            
        Returns:
            tuple: (UnitOfMeasure, created) - единица и флаг создания
        """
        from products.models import UnitOfMeasure
        
        unit, created = UnitOfMeasure.objects.get_or_create(
            code=code,
            defaults={
                'name': name,
                'short_name': short_name,
                'position': position,
                'is_active': True,
            }
        )
        
        if created:
            logger.info(f"Создана единица измерения: {code} - {name}")
        
        return unit, created
    
    @classmethod
    def get_unit_by_code(cls, code: str):
        """
        Получает единицу измерения по коду.
        
        Args:
            code: Код единицы измерения
            
        Returns:
            UnitOfMeasure или None, если не найдена
        """
        from products.models import UnitOfMeasure
        
        try:
            return UnitOfMeasure.objects.get(code=code, is_active=True)
        except UnitOfMeasure.DoesNotExist:
            logger.warning(f"Единица измерения с кодом '{code}' не найдена")
            return None
    
    @classmethod
    def get_active_units(cls) -> List:
        """
        Возвращает все активные единицы измерения.
        
        Returns:
            List[UnitOfMeasure]: Список активных единиц, отсортированных по position
        """
        from products.models import UnitOfMeasure
        
        return list(UnitOfMeasure.objects.filter(is_active=True).order_by('position', 'code'))
