from django.contrib import admin, messages
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse

from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated

from .forms import BulkTagForm, ImportTagsForm
from .models import Product, Tag
from .pagination import ProductPagination
from .serializers import ProductSerializer
from .services import get_existing_sighting_tag_count, get_new_sighting_tag_ids, import_sighting_tags


@admin.display(description="Add tags")
def bulk_add_tags(request):
    if request.method == "POST":
        form = BulkTagForm(request.POST)
        if form.is_valid():
            raw = form.cleaned_data["tag_ids"]
            note = form.cleaned_data["note"]
            ids = [t.strip() for t in raw.replace("\n", ",").split(",") if t.strip()]
            created = 0
            for tag_id in ids:
                _, was_created = Tag.objects.get_or_create(
                    tag_id=tag_id, defaults={"note": note}
                )
                if was_created:
                    created += 1
            msg = f"{created} tag(s) created, {len(ids) - created} already existed."
            messages.success(request, msg)
            return HttpResponseRedirect(reverse("admin:products_tag_changelist"))
    else:
        form = BulkTagForm()

    context = {
        **admin.site.each_context(request),
        "form": form,
        "title": "Add tags",
        "opts": Tag._meta,
    }
    return render(request, "admin/products/tag/bulk_form.html", context)


@admin.display(description="Import from sightings")
def import_from_sightings(request):
    new_tag_ids = get_new_sighting_tag_ids()
    existing_count = get_existing_sighting_tag_count()

    if request.method == "POST":
        form = ImportTagsForm(request.POST)
        if form.is_valid():
            note = form.cleaned_data["note"]
            created, skipped = import_sighting_tags(note)
            messages.success(
                request,
                f"{created} tag(s) imported from sightings, {skipped} already existed.",
            )
            return HttpResponseRedirect(reverse("admin:products_tag_changelist"))
    else:
        form = ImportTagsForm()

    context = {
        **admin.site.each_context(request),
        "form": form,
        "title": "Import from sightings",
        "opts": Tag._meta,
        "new_tag_ids": new_tag_ids,
        "new_count": len(new_tag_ids),
        "existing_count": existing_count,
    }
    return render(request, "admin/products/tag/import_form.html", context)


class ProductViewSet(viewsets.ReadOnlyModelViewSet):
    """
    API endpoint providing product listings with pagination.
    """

    queryset = Product.objects.select_related(
        "location__type", "location__parent"
    ).prefetch_related("tags")
    serializer_class = ProductSerializer
    permission_classes = [IsAuthenticated]
    pagination_class = ProductPagination
    search_fields = ["name", "part_number", "description"]
    ordering_fields = ["name", "part_number", "created_at", "updated_at"]
    ordering = ["name"]
