from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from rest_framework import status

from .services import (
    search_products,
    get_search_suggestions,
    log_search_query,
)

from .serializers import (
    SearchProductSerializer,
)


class ProductSearchAPIView(APIView):
    """
    Main product search API.

    Example:

        GET /api/search/?q=tv

        GET /api/search/?q=electronic%20devices

        GET /api/search/?q=samsung%20tv
    """

    permission_classes = [AllowAny]

    def get(self, request):

        query = request.GET.get("q", "").strip()

        if not query:
            return Response(
                {
                    "success": False,
                    "message": "Search query is required.",
                    "query": "",
                    "results": [],
                },
                status=status.HTTP_400_BAD_REQUEST,
            )

        # Optional limit
        try:
            limit = int(request.GET.get("limit", 50))
        except (TypeError, ValueError):
            limit = 50

        limit = min(max(limit, 1), 100)

        # --------------------------------------------------
        # SEARCH
        # --------------------------------------------------

        result = search_products(
            query=query,
            limit=limit,
        )

        products = result["products"]

        serializer = SearchProductSerializer(
            products,
            many=True,
            context={"request": request},
        )

        # --------------------------------------------------
        # LOG SEARCH
        # --------------------------------------------------

        try:
            log_search_query(
                query=result["query"],
                normalized_query=result["normalized_query"],
                result_count=result["total"],
            )
        except Exception:
            # Search analytics should never break search itself.
            pass

        # --------------------------------------------------
        # CATEGORY INFORMATION
        # --------------------------------------------------

        category_data = None

        if result["category"]:

            category = result["category"]

            category_data = {
                "id": category.id,
                "name": category.name,
            }

        # --------------------------------------------------
        # RESPONSE
        # --------------------------------------------------

        return Response(
            {
                "success": True,

                "query": result["query"],

                "normalized_query": (
                    result["normalized_query"]
                ),

                "intent": result["intent"],

                "resolved_category": category_data,

                "total": result["total"],

                "results": serializer.data,
            },
            status=status.HTTP_200_OK,
        )


class SearchSuggestionAPIView(APIView):
    """
    Autocomplete API.

    Example:

        GET /api/search/suggestions/?q=chi
    """

    permission_classes = [AllowAny]

    def get(self, request):

        query = request.GET.get("q", "").strip()

        if not query:
            return Response(
                {
                    "success": True,
                    "suggestions": [],
                }
            )

        try:
            limit = int(request.GET.get("limit", 10))
        except (TypeError, ValueError):
            limit = 10

        limit = min(max(limit, 1), 20)

        suggestions = get_search_suggestions(
            query=query,
            limit=limit,
        )

        return Response(
            {
                "success": True,
                "query": query,
                "suggestions": suggestions,
            },
            status=status.HTTP_200_OK,
        )