from rest_framework.permissions import IsAuthenticated
from django_filters import rest_framework as filters
from django.contrib.auth.models import User, Group, PermissionManager
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.tokens import RefreshToken
from .models import (
    ImplementerDetails,
    TblUserOrganizationAuth,
    UserProfile
)
from .serializers import (
    OrganizationDetailsSerializer,
    AuthUserPermissionsSerializer,
    AuthGroupSerializer
)
from rest_framework import status
from masters.models import UserClient, UserRecruiterMapping
import json
from django.db import transaction
from masters.utils import send_user_created_mail

class ImplementerDetailsViewSet(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated,)
    queryset = ImplementerDetails.objects.all().order_by("id")
    serializer_class = OrganizationDetailsSerializer
    filterset_fields = {"id": ["exact"]}
    filter_backends = [filters.DjangoFilterBackend]

class HomeView(APIView):
    permission_classes = (IsAuthenticated,)

    def get(self, request):
        c_user = request.user
        PermissionManager()
        print("user: ", request.user)
        user_permissions = c_user.get_group_permissions()
        return Response(user_permissions)

class LogoutView(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request):
        try:
            refresh_token = request.data["refresh_token"]
            token = RefreshToken(refresh_token)
            token.blacklist()
            return Response(status=status.HTTP_205_RESET_CONTENT)
        except Exception as e:
            return Response(status=status.HTTP_400_BAD_REQUEST)

class AuthUserView(viewsets.ModelViewSet):
    # permission_classes = (IsAuthenticated,)
    queryset = User.objects.all()
    serializer_class = AuthUserPermissionsSerializer
    filterset_fields = {
        "username": ["exact"],
        "auth_user_organization__organization": ["exact"],
    }

    def get_queryset(self):
        queryset = User.objects.all()

        role = self.request.query_params.get("role")

        if role == "Recruiter":
            queryset = queryset.filter(groups__name="Recruiter")

        return queryset.distinct()

    def create(self, request):
        organization_id = request.data.get("organization")
        password = request.data.get("password")
        # mobile_number = request.data.get("mobile_number")
        # request.data["is_active"] = True
        user_serializer = AuthUserPermissionsSerializer(data=request.data)
        if user_serializer.is_valid():
            with transaction.atomic():
                user = User.objects.create(
                    username=user_serializer.validated_data["username"],
                    first_name=user_serializer.validated_data.get("first_name", ""),
                    last_name=user_serializer.validated_data.get("last_name", ""),
                    email=user_serializer.validated_data.get("email", ""),
                    is_active=True,
                )
        else:
            # Debug the missing or invalid fields
            print("Validation errors:", user_serializer.errors)
            return Response(user_serializer.errors, status=400)
        user.set_password(request.data["password"])
        user.save()

        full_name = f"{user.first_name} {user.last_name}".strip()

        send_user_created_mail(
            email=user.email,
            username=user.username,
            password=password,
            full_name=full_name,
        )

        profile, created = UserProfile.objects.get_or_create(user=user)

        groups_raw = request.data.get("groups", "[]")
        groups_data = json.loads(groups_raw) if isinstance(groups_raw, str) else groups_raw

        for group_data in groups_data:
            if isinstance(group_data, str):
                group_data = json.loads(group_data)

            group_pk = Group.objects.get(id=group_data["id"])
            user.groups.add(group_pk)

        if organization_id:
            TblUserOrganizationAuth.objects.create(
                user_id=user.id,
                organization_id=organization_id,
                # mobile_number=mobile_number
            )
        clients_raw = request.data.get("client_mappings", "[]")
        clients = json.loads(clients_raw) if isinstance(clients_raw, str) else clients_raw

        for item in clients:
            if isinstance(item, str):
                item = json.loads(item)

            UserClient.objects.create(user=user, client_id=item["client"])

        
        recruiters_raw = request.data.get("recruiters", "[]")
        recruiters = json.loads(recruiters_raw) if isinstance(recruiters_raw, str) else recruiters_raw

        for r in recruiters:
            if isinstance(r, str):
                r = json.loads(r)

            UserRecruiterMapping.objects.create(
                user=user,
                recruiter_id=r["recruiter"]
            )

        profile_image = request.FILES.get("profile_image")
        if profile_image:
            profile.profile_image = profile_image
            profile.save()

        serializer = self.get_serializer(user)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def update(self, request, pk=None, *args, **kwargs):
        user = User.objects.get(id=pk)

        # Update password only logic
        if "password" in request.data:
            user.set_password(request.data["password"])
            user.save()
            return Response({"message": "Password changed successfully."}, status=200)

        organization_id = request.data.get("organization")
        raw_is_active = request.data.get("is_active", user.is_active)

        if isinstance(raw_is_active, str):
            is_active = raw_is_active.lower() == "true"
        else:
            is_active = raw_is_active

        # Update basic fields
        user.username = request.data.get("username", user.username)
        user.first_name = request.data.get("first_name", user.first_name)
        user.last_name = request.data.get("last_name", user.last_name)
        user.email = request.data.get("email", user.email)
        user.is_active = is_active
        user.save()

        groups_raw = request.data.get("groups", [])

        if isinstance(groups_raw, str):
            groups_data = json.loads(groups_raw)
        else:
            groups_data = groups_raw

        user.groups.clear()

        for group_data in groups_data:
            if isinstance(group_data, str):
                group_data = json.loads(group_data)

            group_pk = Group.objects.get(id=group_data["id"])
            user.groups.add(group_pk)

        # Update organization mapping
        if organization_id:
            TblUserOrganizationAuth.objects.filter(user_id=user.id).delete()
            TblUserOrganizationAuth.objects.create(
                user_id=user.id,
                organization_id=organization_id,
            )
        clients_raw = request.data.get("client_mappings", [])

        if isinstance(clients_raw, str):
            clients = json.loads(clients_raw)
        else:
            clients = clients_raw

        UserClient.objects.filter(user=user).delete()

        for item in clients:
            if isinstance(item, str):
                item = json.loads(item)

            UserClient.objects.create(
                user=user,
                client_id=item["client"]
            )

        recruiters_raw = request.data.get("recruiters", [])

        if isinstance(recruiters_raw, str):
            recruiters = json.loads(recruiters_raw)
        else:
            recruiters = recruiters_raw

        UserRecruiterMapping.objects.filter(user=user).delete()

        for r in recruiters:
            if isinstance(r, str):
                r = json.loads(r)

            UserRecruiterMapping.objects.create(
                user=user,
                recruiter_id=r["recruiter"]
            )

        profile_image = request.FILES.get("profile_image")
        if profile_image:
            profile, created = UserProfile.objects.get_or_create(user=user)
            profile.profile_image = profile_image
            profile.save()

        display_column_preference = request.data.get("display_column_preference")
        if display_column_preference is not None:
            profile, created = UserProfile.objects.get_or_create(user=user)
            existing_preferences = profile.display_column_preference or {}
            existing_preferences.update(display_column_preference)
            profile.display_column_preference = existing_preferences
            profile.save()

        serializer = self.get_serializer(user)
        return Response(serializer.data, status=200)
    
    def destroy(self, request, *args, **kwargs):
        user = self.get_object()

        if request.user.id == user.id:
            return Response(
                {"error": "You cannot delete your own account."},
                status=status.HTTP_403_FORBIDDEN
            )

        TblUserOrganizationAuth.objects.filter(user_id=user.id).delete()
        user.delete()

        return Response(status=status.HTTP_204_NO_CONTENT)

class AuthGroupView(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated,)
    queryset = Group.objects.all().order_by("-id")
    # queryset = User.objects.all()
    serializer_class = AuthGroupSerializer