from rest_framework import viewsets, permissions, status
from rest_framework.decorators import action
from rest_framework.response import Response
from .models import QRConfig, Branch
from .serializers import QRConfigSerializer, BranchSerializer
from apps.core.utils import error_response
import logging

logger = logging.getLogger(__name__)


class IsAdminUser(permissions.BasePermission):
    """
    Permission class to check if user is admin.
    """
    def has_permission(self, request, view):
        return request.user and request.user.is_staff


class QRConfigViewSet(viewsets.ModelViewSet):
    """
    ViewSet for managing QR code configurations.
    Only admins can create, update, or delete QR configs.
    All users can retrieve the active QR config.
    """
    queryset = QRConfig.objects.all()
    serializer_class = QRConfigSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_permissions(self):
        """
        Allow any authenticated user to retrieve QR config,
        but only admins can create/update/delete.
        """
        if self.action in ['list', 'retrieve', 'active']:
            # All authenticated users can view
            return [permissions.IsAuthenticated()]
        else:
            # Only admins can create/update/delete
            return [IsAdminUser()]

    def list(self, request, *args, **kwargs):
        """List all QR configs (admin only)."""
        if not request.user.is_staff:
            return error_response(
                message="Only admins can view all QR configs.",
                code="PERMISSION_DENIED",
                status_code=status.HTTP_403_FORBIDDEN
            )
        return super().list(request, *args, **kwargs)

    def create(self, request, *args, **kwargs):
        """Create a new QR config (admin only)."""
        if not request.user.is_staff:
            return error_response(
                message="Only admins can create QR configs.",
                code="PERMISSION_DENIED",
                status_code=status.HTTP_403_FORBIDDEN
            )
        
        serializer = self.get_serializer(data=request.data, context={'request': request})
        if not serializer.is_valid():
            return error_response(
                message="Validation failed",
                code="VALIDATION_ERROR",
                fields=serializer.errors,
                status_code=status.HTTP_400_BAD_REQUEST
            )
        
        qr_config = serializer.save()
        logger.info(f"QR config created by admin {request.user.id}: {qr_config.id}")
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def update(self, request, *args, **kwargs):
        """Update QR config (admin only)."""
        if not request.user.is_staff:
            return error_response(
                message="Only admins can update QR configs.",
                code="PERMISSION_DENIED",
                status_code=status.HTTP_403_FORBIDDEN
            )
        return super().update(request, *args, **kwargs)

    def destroy(self, request, *args, **kwargs):
        """Delete QR config (admin only)."""
        if not request.user.is_staff:
            return error_response(
                message="Only admins can delete QR configs.",
                code="PERMISSION_DENIED",
                status_code=status.HTTP_403_FORBIDDEN
            )
        
        qr_config = self.get_object()
        logger.info(f"QR config deleted by admin {request.user.id}: {qr_config.id}")
        return super().destroy(request, *args, **kwargs)

    @action(detail=False, methods=['get'], permission_classes=[permissions.IsAuthenticated])
    def active(self, request):
        """
        Retrieve the currently active QR config.
        All authenticated users can access this.
        """
        try:
            qr_config = QRConfig.objects.filter(is_active=True).first()
            if not qr_config:
                return Response(
                    {
                        "success": False,
                        "message": "No active QR config found",
                        "data": None
                    },
                    status=status.HTTP_404_NOT_FOUND
                )
            
            serializer = self.get_serializer(qr_config, context={'request': request})
            return Response(
                {
                    "success": True,
                    "data": serializer.data
                },
                status=status.HTTP_200_OK
            )
        except Exception as e:
            logger.error(f"Error retrieving active QR config: {e}", exc_info=True)
            return error_response(
                message=str(e),
                code="RETRIEVAL_FAILED",
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class BranchViewSet(viewsets.ModelViewSet):
    """
    Public GET (list/retrieve) for all users; CUD restricted to admin.
    """
    queryset = Branch.objects.all()
    serializer_class = BranchSerializer

    def get_permissions(self):
        if self.action in ["list", "retrieve"]:
            return [permissions.AllowAny()]
        return [permissions.IsAuthenticated(), IsAdminUser()]
