from rest_framework import viewsets, permissions, status, views, decorators
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from rest_framework.decorators import api_view, permission_classes
from django.contrib.auth import authenticate, update_session_auth_hash
from .models import Source, ApiKey, Submission, SubmissionFile
from .serializers import SourceSerializer, ApiKeySerializer, SubmissionSerializer, UserSerializer

class LoginView(views.APIView):
    permission_classes = [permissions.AllowAny]

    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = authenticate(username=username, password=password)
        if user:
            token, _ = Token.objects.get_or_create(user=user)
            return Response({
                'token': token.key,
                'user': UserSerializer(user).data
            })
        return Response({'error': 'Invalid Credentials'}, status=status.HTTP_401_UNAUTHORIZED)

class UserView(views.APIView):
    def get(self, request):
        return Response(UserSerializer(request.user).data)

class SourceViewSet(viewsets.ModelViewSet):
    serializer_class = SourceSerializer

    def get_queryset(self):
        return Source.objects.filter(owner=self.request.user)

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

class ApiKeyViewSet(viewsets.ModelViewSet):
    serializer_class = ApiKeySerializer

    def get_queryset(self):
        return ApiKey.objects.filter(source__owner=self.request.user)

    def perform_create(self, serializer):
        # Ensure the source belongs to the user
        source = serializer.validated_data['source']
        if source.owner != self.request.user:
            raise permissions.exceptions.PermissionDenied("You do not own this source.")
        serializer.save()

class SubmissionViewSet(viewsets.ModelViewSet):
    serializer_class = SubmissionSerializer

    def get_queryset(self):
        return Submission.objects.filter(source__owner=self.request.user).order_by('-created_at')

    def perform_create(self, serializer):
        # Usually submissions come via the public /submit endpoint, but this allows manual creation if needed
        source = serializer.validated_data['source']
        if source.owner != self.request.user:
            raise permissions.exceptions.PermissionDenied("You do not own this source.")
        serializer.save()

    @decorators.action(detail=False, methods=['post'])
    def bulk_delete(self, request):
        ids = request.data.get('ids', [])
        if not ids:
            return Response({'error': 'No IDs provided'}, status=status.HTTP_400_BAD_REQUEST)
        
        # Only delete submissions belonging to the user
        deleted_count, _ = Submission.objects.filter(
            id__in=ids, 
            source__owner=self.request.user
        ).delete()
        
        return Response({'success': True, 'deleted_count': deleted_count})

class ChangePasswordView(views.APIView):
    def post(self, request):
        old_password = request.data.get('old_password')
        new_password = request.data.get('new_password')
        user = request.user
        
        if not user.check_password(old_password):
            return Response({'error': 'Current password is incorrect'}, status=status.HTTP_400_BAD_REQUEST)
        
        user.set_password(new_password)
        user.save()
        update_session_auth_hash(request, user)  # Keep the user logged in
        return Response({'success': 'Password changed successfully'})

@api_view(['POST', 'OPTIONS'])
@permission_classes([permissions.AllowAny])
def public_submit(request):
    if request.method == 'OPTIONS':
        return Response(status=status.HTTP_200_OK)

    api_key_str = request.headers.get('Authorization', '').replace('Bearer ', '').replace('Token ', '')
    if not api_key_str:
        api_key_str = request.headers.get('X-API-KEY')
    if not api_key_str:
        api_key_str = request.data.get('api_key')
    
    if not api_key_str:
        return Response({'error': 'API Key required (Authorization header or api_key in body)'}, status=status.HTTP_401_UNAUTHORIZED)

    try:
        api_key = ApiKey.objects.get(key=api_key_str, is_active=True)
    except ApiKey.DoesNotExist:
        return Response({'error': 'Invalid or inactive API Key'}, status=status.HTTP_401_UNAUTHORIZED)

    source = api_key.source
    data = request.data
    medium = data.get('medium', 'Unknown')
    
    # Extract context
    context = data.get('context', {})
    if isinstance(context, str):
        try:
            import json
            context = json.loads(context)
        except:
            pass

    if not isinstance(context, dict):
        context = {k: v for k, v in data.items() if k not in ['medium', 'api_key', 'source']}
    
    submission = Submission.objects.create(
        source=source,
        medium=medium,
        context=context
    )

    # Process files from multipart
    for field_name, file_objs in request.FILES.lists():
        for file_obj in file_objs:
            SubmissionFile.objects.create(
                submission=submission,
                file=file_obj,
                filename=file_obj.name
            )

    # Automatically detect and save Base64 images inside context
    import base64 as b64
    import uuid
    from django.core.files.base import ContentFile
    
    for key, value in context.items():
        if isinstance(value, str) and value.startswith('AAABAA') or (isinstance(value, str) and len(value) > 1000 and (';base64,' in value or value.strip().startswith('iVBORw0KG'))):
            try:
                # Basic detection of common image headers in base64
                header, data = value, value
                if ';base64,' in value:
                    header, data = value.split(';base64,')
                
                ext = 'png'
                if 'image/jpeg' in header: ext = 'jpg'
                elif 'image/gif' in header: ext = 'gif'
                
                file_data = b64.b64decode(data)
                file_name = f"{key}_{uuid.uuid4().hex[:8]}.{ext}"
                
                SubmissionFile.objects.create(
                    submission=submission,
                    file=ContentFile(file_data, name=file_name),
                    filename=file_name
                )
            except:
                pass
    
    return Response({
        'success': True,
        'message': 'Submission received successfully',
        'id': submission.id,
        'files_count': submission.files.count()
    }, status=status.HTTP_201_CREATED)
