"""
CRUD представления для тегов товаров (ProductTag).
"""
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView, CreateView, DetailView, UpdateView, DeleteView
from django.urls import reverse_lazy
from django.db.models import Q, Count
from django.db import IntegrityError

from ..models import ProductTag
from ..forms import ProductTagForm


class ProductTagListView(LoginRequiredMixin, ListView):
    """Список всех тегов с поиском и фильтрацией"""
    model = ProductTag
    template_name = 'products/tag_list.html'
    context_object_name = 'tags'
    paginate_by = 20

    def get_queryset(self):
        queryset = super().get_queryset()

        # Аннотируем количество товаров и комплектов для каждого тега
        queryset = queryset.annotate(
            products_count=Count('products', distinct=True),
            kits_count=Count('kits', distinct=True)
        )

        # Поиск по названию и slug
        search_query = self.request.GET.get('search')
        if search_query:
            queryset = queryset.filter(
                Q(name__icontains=search_query) |
                Q(slug__icontains=search_query)
            )

        # Фильтр по статусу активности
        is_active = self.request.GET.get('is_active')
        if is_active == '1':
            queryset = queryset.filter(is_active=True)
        elif is_active == '0':
            queryset = queryset.filter(is_active=False)

        return queryset.order_by('name')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['search_query'] = self.request.GET.get('search', '')
        context['is_active_filter'] = self.request.GET.get('is_active', '')
        return context


class ProductTagDetailView(LoginRequiredMixin, DetailView):
    """Детальная информация о теге с привязанными товарами и комплектами"""
    model = ProductTag
    template_name = 'products/tag_detail.html'
    context_object_name = 'tag'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        tag = self.get_object()

        # Получаем товары и комплекты с этим тегом
        # Если тег неактивный, показываем ВСЕ товары/комплекты (для возможности очистки)
        # Если тег активный, показываем только активные товары/комплекты
        if tag.is_active:
            context['products'] = tag.products.filter(status='active').order_by('name')[:20]
            context['kits'] = tag.kits.filter(status='active').order_by('name')[:20]
        else:
            context['products'] = tag.products.all().order_by('name')[:20]
            context['kits'] = tag.kits.all().order_by('name')[:20]

        context['total_products'] = tag.products.count()
        context['total_kits'] = tag.kits.count()

        return context


class ProductTagCreateView(LoginRequiredMixin, CreateView):
    """Создание нового тега"""
    model = ProductTag
    form_class = ProductTagForm
    template_name = 'products/tag_form.html'
    success_url = reverse_lazy('products:tag-list')

    def form_valid(self, form):
        try:
            response = super().form_valid(form)
            messages.success(self.request, f'Тег "{self.object.name}" успешно создан.')
            return response

        except IntegrityError as e:
            # Обработка нарушения уникальности
            error_msg = str(e).lower()
            if 'unique_active_tag_name' in error_msg or ('name' in error_msg and 'duplicate' in error_msg):
                messages.error(
                    self.request,
                    f'Ошибка: активный тег с названием "{form.instance.name}" уже существует. '
                    'Пожалуйста, используйте другое название или переименуйте существующий тег.'
                )
            elif 'slug' in error_msg or 'unique' in error_msg:
                messages.error(
                    self.request,
                    'Ошибка: тег с таким названием уже существует. '
                    'Пожалуйста, используйте другое название.'
                )
            else:
                messages.error(
                    self.request,
                    'Ошибка при сохранении тега. Пожалуйста, проверьте введённые данные.'
                )
            return self.form_invalid(form)


class ProductTagUpdateView(LoginRequiredMixin, UpdateView):
    """Редактирование существующего тега"""
    model = ProductTag
    form_class = ProductTagForm
    template_name = 'products/tag_form.html'
    success_url = reverse_lazy('products:tag-list')

    def form_valid(self, form):
        try:
            response = super().form_valid(form)
            messages.success(self.request, f'Тег "{self.object.name}" успешно обновлен.')
            return response

        except IntegrityError as e:
            # Обработка нарушения уникальности
            error_msg = str(e).lower()
            if 'unique_active_tag_name' in error_msg or ('name' in error_msg and 'duplicate' in error_msg):
                messages.error(
                    self.request,
                    f'Ошибка: активный тег с названием "{form.instance.name}" уже существует. '
                    'Пожалуйста, используйте другое название или переименуйте существующий тег.'
                )
            elif 'slug' in error_msg or 'unique' in error_msg:
                messages.error(
                    self.request,
                    'Ошибка: тег с таким названием уже существует. '
                    'Пожалуйста, используйте другое название.'
                )
            else:
                messages.error(
                    self.request,
                    'Ошибка при сохранении тега. Пожалуйста, проверьте введённые данные.'
                )
            return self.form_invalid(form)


class ProductTagDeleteView(LoginRequiredMixin, DeleteView):
    """Удаление тега с подтверждением"""
    model = ProductTag
    template_name = 'products/tag_confirm_delete.html'
    success_url = reverse_lazy('products:tag-list')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        tag = self.get_object()

        # Передаем информацию о связанных объектах для предупреждения
        context['products_count'] = tag.products.count()
        context['kits_count'] = tag.kits.count()

        return context

    def delete(self, request, *args, **kwargs):
        tag = self.get_object()
        tag_name = tag.name
        response = super().delete(request, *args, **kwargs)
        messages.success(request, f'Тег "{tag_name}" успешно удален.')
        return response
