from rest_framework import viewsets, generics, filters, status
from rest_framework.decorators import action, api_view, permission_classes
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework_simplejwt.tokens import RefreshToken
from django_filters.rest_framework import DjangoFilterBackend
import cloudinary.uploader

from users.models import User
from notices.models import Notice
from events.models import Event
from programs.models import Program
from faculty.models import Faculty
from gallery.models import GalleryImage
from admissions.models import AdmissionInquiry
from contact.models import ContactMessage

from .permissions import IsAdminOrSuperAdmin, IsSuperAdmin, IsAdminOrSuperAdminOrReadOnly
from .serializers import (                          # ✅ all from core.serializers
    LoginSerializer,
    UserSerializer,
    CreateUserSerializer,
    NoticeSerializer,
    EventSerializer,
    ProgramSerializer,
    FacultySerializer,
    GalleryImageSerializer,
    AdmissionInquirySerializer,
    AdmissionStatusSerializer,                      # ✅ was wrongly imported from admissions
    ContactMessageSerializer,
    ContactStatusSerializer,
    DashboardStatsSerializer,
)
from admissions.serializers import AdmissionStatusUpdateSerializer  # ✅ this one lives in admissions


# ✅ Base class — import this in all your app views
class BaseListCreateView(generics.ListCreateAPIView):
    def get_filter_backends(self):
        if self.request.method == "GET":
            return [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
        return []


class LoginView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        ser = LoginSerializer(data=request.data)
        ser.is_valid(raise_exception=True)
        user = ser.validated_data["user"]
        refresh = RefreshToken.for_user(user)
        return Response({
            "access": str(refresh.access_token),
            "refresh": str(refresh),
            "user": UserSerializer(user).data,
        })


class LogoutView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            token = RefreshToken(request.data["refresh"])
            token.blacklist()
        except Exception:
            pass
        return Response({"detail": "Logged out successfully."})


class MeView(generics.RetrieveUpdateAPIView):
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]

    def get_object(self):
        return self.request.user


class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    permission_classes = [IsSuperAdmin]
    filter_backends = [filters.SearchFilter]
    search_fields = ["email", "full_name", "role"]

    def get_serializer_class(self):
        if self.action == "create":
            return CreateUserSerializer
        return UserSerializer

    @action(detail=True, methods=["post"], url_path="toggle-active")
    def toggle_active(self, request, pk=None):
        user = self.get_object()
        user.is_active = not user.is_active
        user.save()
        return Response({"is_active": user.is_active})


class DashboardView(APIView):
    permission_classes = [IsAdminOrSuperAdmin]

    def get(self, request):
        data = {
            "notices": Notice.objects.count(),
            "events": Event.objects.count(),
            "programs": Program.objects.count(),
            "faculty": Faculty.objects.count(),
            "gallery": GalleryImage.objects.count(),
            "pending_admissions": AdmissionInquiry.objects.filter(status="pending").count(),
            "unread_contacts": ContactMessage.objects.filter(status="unread").count(),
        }
        ser = DashboardStatsSerializer(data)
        return Response(ser.data)


class NoticeViewSet(viewsets.ModelViewSet):
    queryset = Notice.objects.all()
    serializer_class = NoticeSerializer
    permission_classes = [IsAdminOrSuperAdminOrReadOnly]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["category", "is_new"]
    search_fields = ["title", "excerpt"]
    ordering_fields = ["date", "created_at"]


class EventViewSet(viewsets.ModelViewSet):
    queryset = Event.objects.all()
    serializer_class = EventSerializer
    permission_classes = [IsAdminOrSuperAdminOrReadOnly]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["is_past"]
    search_fields = ["title", "location", "description"]
    ordering_fields = ["date"]


class ProgramViewSet(viewsets.ModelViewSet):
    queryset = Program.objects.all()
    serializer_class = ProgramSerializer
    permission_classes = [IsAdminOrSuperAdminOrReadOnly]
    filter_backends = [filters.SearchFilter]
    search_fields = ["name", "department"]


class FacultyViewSet(viewsets.ModelViewSet):
    queryset = Faculty.objects.all()
    serializer_class = FacultySerializer
    permission_classes = [IsAdminOrSuperAdminOrReadOnly]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    filterset_fields = ["department"]
    search_fields = ["full_name", "designation", "department", "specialization"]


class GalleryViewSet(viewsets.ModelViewSet):
    queryset = GalleryImage.objects.all()
    serializer_class = GalleryImageSerializer
    permission_classes = [IsAdminOrSuperAdminOrReadOnly]
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["category"]


class AdmissionInquiryViewSet(viewsets.ModelViewSet):
    queryset = AdmissionInquiry.objects.all()
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["status", "program"]
    search_fields = ["full_name", "email"]
    ordering_fields = ["created_at"]

    def get_permissions(self):
        if self.action == "create":
            return [AllowAny()]
        return [IsAdminOrSuperAdmin()]

    def get_serializer_class(self):
        if self.action in ("update", "partial_update") and "status" in self.request.data:
            return AdmissionStatusSerializer               
        return AdmissionInquirySerializer

    @action(detail=True, methods=["patch"], url_path="update-status")
    def update_status(self, request, pk=None):
        inquiry = self.get_object()
        ser = AdmissionStatusUpdateSerializer(          
            inquiry, data=request.data, partial=True, context={"request": request}
        )
        ser.is_valid(raise_exception=True)
        ser.save()
        return Response(AdmissionInquirySerializer(inquiry).data)


class ContactMessageViewSet(viewsets.ModelViewSet):
    queryset = ContactMessage.objects.all()
    serializer_class = ContactMessageSerializer
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    filterset_fields = ["status"]
    search_fields = ["full_name", "email", "subject"]

    def get_permissions(self):
        if self.action == "create":
            return [AllowAny()]
        return [IsAdminOrSuperAdmin()]

    def get_authenticators(self):
        if self.action == "create":
            return []
        return super().get_authenticators()

    def get_serializer_class(self):
        if self.action in ("update", "partial_update"):
            return ContactStatusSerializer
        return ContactMessageSerializer

    @action(detail=True, methods=["patch"], url_path="mark-read")
    def mark_read(self, request, pk=None):
        msg = self.get_object()
        msg.status = "read"
        msg.save()
        return Response(ContactMessageSerializer(msg).data)


@api_view(["POST"])
@permission_classes([IsAdminOrSuperAdmin])
def upload_image(request):
    file = request.FILES.get("file")
    if not file:
        return Response({"error": "No file provided"}, status=400)
    result = cloudinary.uploader.upload(file, folder="college", resource_type="image")
    return Response({"url": result["secure_url"]})