from django.utils import timezone
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from apps.engagement.models import Coupon, Favorite, Notification, RecentlyViewed
from apps.engagement.serializers import (
    CouponSerializer,
    FavoriteCreateSerializer,
    FavoriteSerializer,
    NotificationSerializer,
    NotificationSettingsSerializer,
    RecentlyViewedCreateSerializer,
    RecentlyViewedSerializer,
)
from apps.stores.models import Store


class FavoriteViewSet(viewsets.ViewSet):
    """ViewSet for user favorites."""

    permission_classes = [IsAuthenticated]

    def list(self, request):
        """GET /favorites/ — list user favorites."""
        favs = Favorite.objects.filter(user=request.user).select_related("store")
        serializer = FavoriteSerializer(favs, many=True)
        return Response(serializer.data)

    def create(self, request):
        """POST /favorites/ — add a store to favorites."""
        serializer = FavoriteCreateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        store_id = serializer.validated_data["store_id"]

        try:
            store = Store.objects.get(pk=store_id)
        except Store.DoesNotExist:
            return Response({"detail": "Store not found."}, status=status.HTTP_404_NOT_FOUND)

        fav, created = Favorite.objects.get_or_create(user=request.user, store=store)
        if not created:
            return Response({"detail": "Already in favorites."}, status=status.HTTP_200_OK)
        return Response(FavoriteSerializer(fav).data, status=status.HTTP_201_CREATED)

    def destroy(self, request, pk=None):
        """DELETE /favorites/{store_id}/ — remove from favorites."""
        deleted, _ = Favorite.objects.filter(user=request.user, store_id=pk).delete()
        if not deleted:
            return Response({"detail": "Not found in favorites."}, status=status.HTTP_404_NOT_FOUND)
        return Response(status=status.HTTP_204_NO_CONTENT)


class RecentlyViewedViewSet(viewsets.ViewSet):
    """ViewSet for recently viewed stores."""

    permission_classes = [IsAuthenticated]

    def list(self, request):
        """GET /recently-viewed/ — list recently viewed stores."""
        items = RecentlyViewed.objects.filter(user=request.user).select_related("store")[:50]
        serializer = RecentlyViewedSerializer(items, many=True)
        return Response(serializer.data)

    def create(self, request):
        """POST /recently-viewed/ — record a store view."""
        serializer = RecentlyViewedCreateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        store_id = serializer.validated_data["store_id"]

        try:
            store = Store.objects.get(pk=store_id)
        except Store.DoesNotExist:
            return Response({"detail": "Store not found."}, status=status.HTTP_404_NOT_FOUND)

        obj, _ = RecentlyViewed.objects.update_or_create(
            user=request.user, store=store, defaults={"viewed_at": timezone.now()}
        )
        return Response(RecentlyViewedSerializer(obj).data, status=status.HTTP_201_CREATED)


class CouponViewSet(viewsets.ViewSet):
    """ViewSet for coupons."""

    permission_classes = [IsAuthenticated]

    def list(self, request):
        """GET /coupons/ — list available coupons."""
        coupons = Coupon.objects.filter(is_active=True, valid_until__gte=timezone.now())
        serializer = CouponSerializer(coupons, many=True)
        return Response(serializer.data)


class NotificationViewSet(viewsets.ViewSet):
    """ViewSet for user notifications."""

    permission_classes = [IsAuthenticated]

    def list(self, request):
        """GET /notifications/ — list user notifications."""
        notifications = Notification.objects.filter(user=request.user)
        serializer = NotificationSerializer(notifications, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=["patch"], url_path="read")
    def mark_read(self, request, pk=None):
        """PATCH /notifications/{id}/read/ — mark as read."""
        try:
            notification = Notification.objects.get(pk=pk, user=request.user)
        except Notification.DoesNotExist:
            return Response({"detail": "Not found."}, status=status.HTTP_404_NOT_FOUND)
        notification.is_read = True
        notification.save(update_fields=["is_read"])
        return Response(NotificationSerializer(notification).data)

    @action(detail=False, methods=["patch"], url_path="settings")
    def settings(self, request):
        """PATCH /notifications/settings/ — toggle notifications."""
        serializer = NotificationSettingsSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        request.user.notifications_enabled = serializer.validated_data["notifications_enabled"]
        request.user.save(update_fields=["notifications_enabled"])
        return Response({"notifications_enabled": request.user.notifications_enabled})
