"""
REST API views for Themis.
"""
from django.utils import timezone
from rest_framework import permissions, status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

from themis.models import UserAPIKey, UserNotification, UserProfile
from themis.notifications import get_unread_count

from .serializers import (
    UserAPIKeyCreateSerializer,
    UserAPIKeyListSerializer,
    UserNotificationSerializer,
    UserProfileSerializer,
)


class IsOwnerOrAdmin(permissions.BasePermission):
    """Only allow owners or admins to access the object."""

    def has_object_permission(self, request, view, obj):
        if hasattr(obj, "user"):
            return obj.user == request.user or request.user.is_staff
        return request.user.is_staff


class UserProfileViewSet(viewsets.ModelViewSet):
    """API endpoint for user profiles."""

    queryset = UserProfile.objects.select_related("user").all()
    serializer_class = UserProfileSerializer
    permission_classes = [permissions.IsAuthenticated, IsOwnerOrAdmin]

    def get_queryset(self):
        """Users can only see their own profile unless admin."""
        qs = super().get_queryset()
        if not self.request.user.is_staff:
            return qs.filter(user=self.request.user)
        return qs


class UserAPIKeyViewSet(viewsets.ModelViewSet):
    """API endpoint for API key management."""

    permission_classes = [permissions.IsAuthenticated, IsOwnerOrAdmin]

    def get_queryset(self):
        """Users can only see their own keys."""
        return UserAPIKey.objects.filter(user=self.request.user).order_by(
            "service_name"
        )

    def get_serializer_class(self):
        """Use create serializer for POST, list serializer for everything else."""
        if self.action == "create":
            return UserAPIKeyCreateSerializer
        return UserAPIKeyListSerializer


class UserNotificationViewSet(viewsets.ModelViewSet):
    """
    API endpoint for notification management.

    Supports listing, retrieving, and state changes (read/dismiss).
    Notifications are created via ``notify_user()`` — not via API POST.
    """

    serializer_class = UserNotificationSerializer
    permission_classes = [permissions.IsAuthenticated]
    http_method_names = ["get", "patch", "delete", "head", "options"]

    def get_queryset(self):
        """Users can only see their own notifications."""
        qs = UserNotification.objects.filter(user=self.request.user)

        # Filter by read/unread status
        is_read = self.request.query_params.get("is_read")
        if is_read is not None:
            qs = qs.filter(is_read=is_read.lower() == "true")

        # Filter by dismissed status
        is_dismissed = self.request.query_params.get("is_dismissed")
        if is_dismissed is not None:
            qs = qs.filter(is_dismissed=is_dismissed.lower() == "true")

        # Filter by level
        level = self.request.query_params.get("level")
        if level:
            qs = qs.filter(level=level)

        # Filter by source app
        source_app = self.request.query_params.get("source_app")
        if source_app:
            qs = qs.filter(source_app=source_app)

        return qs

    @action(detail=True, methods=["patch"])
    def mark_read(self, request, pk=None):
        """Mark a single notification as read."""
        notification = self.get_object()
        notification.is_read = True
        notification.read_at = timezone.now()
        notification.save(update_fields=["is_read", "read_at", "updated_at"])
        serializer = self.get_serializer(notification)
        return Response(serializer.data)

    @action(detail=False, methods=["patch"], url_path="mark-all-read")
    def mark_all_read(self, request):
        """Mark all unread notifications as read."""
        count = UserNotification.objects.filter(
            user=request.user,
            is_read=False,
        ).update(is_read=True, read_at=timezone.now())
        return Response({"marked_read": count})

    @action(detail=True, methods=["patch"])
    def dismiss(self, request, pk=None):
        """Dismiss a single notification."""
        notification = self.get_object()
        notification.is_dismissed = True
        notification.dismissed_at = timezone.now()
        notification.save(
            update_fields=["is_dismissed", "dismissed_at", "updated_at"]
        )
        serializer = self.get_serializer(notification)
        return Response(serializer.data)

    @action(detail=False, methods=["get"])
    def count(self, request):
        """Return unread notification count."""
        return Response({"count": get_unread_count(request.user)})
