from django.shortcuts import render
from rest_framework import status, permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.authtoken.models import Token
from django.contrib.auth import authenticate
from django.utils import timezone
from datetime import timedelta
import uuid
import logging
from users.models.users import User
from users.serializers.users_serializer import (
    ChangePasswordSerializer,
    UserSerializer,
    RegistrationSerializer,

)
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from django.core.mail import send_mail, EmailMessage
from django.template.loader import render_to_string
from django.conf import settings
from django.db.models import Q
from common.pagination.custom_pagination import CustomPageNumberPagination


logger = logging.getLogger(__name__)


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

    @swagger_auto_schema(
        operation_description="Register a new admin user",
        request_body=RegistrationSerializer,
        responses={
            201: openapi.Response(
                description="User registered successfully",
                examples={
                    'application/json': {
                        'message': 'User registered successfully. Please check your email to verify your account.'
                    }
                }
            ),
            400: "Bad Request - Invalid data"
        }
    )
    def post(self, request):
        serializer = RegistrationSerializer(data=request.data)
        if serializer.is_valid():
            # Create user with email verified and active by default
            validated_data = serializer.validated_data
            validated_data.pop('password_confirm')

            user = User.objects.create_user(
                email=validated_data['email'],
                password=validated_data['password'],
                full_name=validated_data.get('full_name', ''),
                role=validated_data.get('role', 'admin'),
                is_active=True,
                email_verified=True
            )



            return Response({
                "message": "Admin User registered successfully."
            }, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class AdminCreateClientView(APIView):
    # permission_classes = [permissions.IsAuthenticated]

    @swagger_auto_schema(
        operation_description="Admin creates a new user (admin only)",
        request_body=RegistrationSerializer,
        responses={
            201: openapi.Response(
                description="User created successfully",
                examples={
                    'application/json': {
                        'message': 'User created successfully.',
                        'user': {
                            'id': 'user-id',
                            'email': 'user@example.com',
                            'first_name': 'John',
                            'last_name': 'Doe',
                            'role': 'client',
                            'is_active': True,
                            'date_joined': '2023-01-01T00:00:00Z',
                            'email_verified': True
                        }
                    }
                }
            ),
            400: "Bad Request - Invalid data",
            403: "Forbidden - Not an admin user"
        }
    )
    def post(self, request):
        # Check if user is admin
        # if request.user.role != 'admin':
        #     return Response({
        #         "error": "Only admin users can create new users."
        #     }, status=status.HTTP_403_FORBIDDEN)

        serializer = RegistrationSerializer(data=request.data)
        if serializer.is_valid():
            # Create user with email verified and active by default
            validated_data = serializer.validated_data
            validated_data.pop('password_confirm')

            user = User.objects.create_user(
                email=validated_data['email'],
                password=validated_data['password'],
                first_name=validated_data.get('first_name', ''),
                last_name=validated_data.get('last_name', ''),
                role=validated_data.get('role', 'client'),
                is_active=True,
                email_verified=True
            )

            return Response({
                "message": "Client user created successfully.",
                "user": UserSerializer(user).data
            }, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class UserProfileView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    @swagger_auto_schema(
        responses={
            200: UserSerializer
        }
    )
    def get(self, request):
        user = request.user
        user_data = UserSerializer(user).data
        
        # Check user role and fetch additional details
        if user.role == 'client':
            try:
                # Get customer details using the related_name 'customers'
                customer = user.customers.first()  # Using related_name from your model
                if customer:
                    customer_data = {
                        # PIC Details
                        'full_name': customer.full_name,
                        'designation': customer.designation,
                        'email': customer.email,
                        'country': customer.country,
                        'phone_number': customer.phone_number,
                        'notice_address': customer.notice_address,
                        'contact_details': customer.contact_details,
                        
                        # Company Details
                        'company_name': customer.company_name,
                        'company_id': customer.company_id,
                        'company_reg_no': customer.company_reg_no,
                        'technology': customer.technology,
                        'company_address': customer.company_address,
                        'asset_number': customer.asset_number,
                        
                        # Senior Management Information
                        'senior_name': customer.senior_name,
                        'senior_phone_no': customer.senior_phone_no,
                        'senior_email': customer.senior_email,
                        'senior_notes': customer.senior_notes
                    }
                    user_data['customer_details'] = customer_data
            except Exception as e:
                user_data['error'] = str(e)
        
        elif user.role == 'admin':
            try:
                # Get employee details using the related_name 'employees'
                employee = user.employees.first()  # Using related_name from your model
                if employee:
                    employee_data = {
                        'first_name': employee.first_name,
                        'last_name': employee.last_name,
                        'role': employee.role,
                        'email': employee.email,
                        'address': employee.address,
                        'designation': employee.designation,
                        'phone_number': employee.phone_number
                    }
                    user_data['employee_details'] = employee_data
            except Exception as e:
                user_data['error'] = str(e)
        
        return Response(user_data)

    def patch(self, request):
        """Partially update the authenticated user's profile (requires token)."""
        serializer = UserSerializer(request.user, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class AdminChangePasswordView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = ChangePasswordSerializer
    @swagger_auto_schema(request_body=ChangePasswordSerializer)
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)

        user_id = serializer.validated_data['user_id']
        password = serializer.validated_data['password']
        print("Changing password for user:", user_id)

        try:
            user = User.objects.get(id=user_id)
            user.set_password(password)
            user.save()
            return Response({"detail": "Password changed successfully."}, status=status.HTTP_200_OK)
        except User.DoesNotExist:
            return Response({"detail": "User not found."}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response({"detail": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class LogoutView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    def post(self, request):
        # Delete the user's token to logout
        try:
            # request.user.auth_token.delete()
            return Response({"message": "Successfully logged out."}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class UserDeleteView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    @swagger_auto_schema(
        responses={
            200: openapi.Response(
                description="User deleted successfully",
                examples={
                    'application/json': {
                        'message': 'User deleted successfully.'
                    }
                }
            ),
            404: "User not found",
            500: "Internal Server Error"
        }
    )
    def delete(self, request, user_id):
        try:
            user = User.objects.get(id=user_id)
            # Soft delete by setting is_active to False
            user.is_active = False
            user.save()
            return Response({"message": "User deleted successfully."}, status=status.HTTP_200_OK)
        except User.DoesNotExist:
            return Response({"error": "User not found."}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class UserDetailView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    @swagger_auto_schema(
        operation_description="Get user details by user ID",
        manual_parameters=[
            openapi.Parameter(
                'user_id',
                openapi.IN_PATH,
                description="ID of the user to retrieve",
                type=openapi.TYPE_STRING,
                required=True
            )
        ],
        responses={
            200: UserSerializer,
            404: "User not found",
            500: "Internal Server Error"
        }
    )
    def get(self, request, user_id):
        try:
            user = User.objects.get(id=user_id)
            serializer = UserSerializer(user)
            return Response(serializer.data)
        except User.DoesNotExist:
            return Response(
                {"error": "User not found."},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            return Response(
                {"error": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
        
class UserListView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    pagination_class = CustomPageNumberPagination

    @swagger_auto_schema(
        operation_description="List all users with pagination, search, and ordering",
        manual_parameters=[
            openapi.Parameter(
                'search',
                openapi.IN_QUERY,
                description="Search in email, full_name, phone_number",
                type=openapi.TYPE_STRING,
                required=False
            ),
            openapi.Parameter(
                'page',
                openapi.IN_QUERY,
                description="Page number",
                type=openapi.TYPE_INTEGER,
                required=False
            ),
            openapi.Parameter(
                'count',
                openapi.IN_QUERY,
                description="Items per page",
                type=openapi.TYPE_INTEGER,
                required=False
            )
        ],
        responses={
            200: UserSerializer(many=True),
            500: "Internal Server Error"
        }
    )
    def get(self, request):
        try:
            # Get all users ordered by created_at descending (newest first)
            users = User.objects.all().order_by('-id')
            
            # Apply search if provided
            search = request.query_params.get('search', None)
            country = request.query_params.get('country', None)
            if search:
                users = users.filter(
                    Q(email__icontains=search) |
                    Q(full_name__icontains=search) 
                )
            if country:
                users = users.filter(country=country)
            
            # Apply pagination
            paginator = self.pagination_class()
            page = paginator.paginate_queryset(users, request)
            
            if page is not None:
                serializer = UserSerializer(page, many=True)
                return paginator.get_paginated_response(serializer.data)
            
            # Fallback if no pagination
            serializer = UserSerializer(users, many=True)
            return Response(serializer.data)
            
        except Exception as e:
            return Response(
                {"error": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
        

class ChangePasswordView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    @swagger_auto_schema(
        operation_description="Change user password with old password verification",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['old_password', 'new_password'],
            properties={
                'old_password': openapi.Schema(
                    type=openapi.TYPE_STRING,
                    description='Current password'
                ),
                'new_password': openapi.Schema(
                    type=openapi.TYPE_STRING,
                    description='New password'
                ),
                'confirm_password': openapi.Schema(
                    type=openapi.TYPE_STRING,
                    description='Confirm new password'
                ),
            },
        ),
        responses={
            200: openapi.Response(
                description="Password changed successfully",
                examples={
                    'application/json': {
                        'message': 'Password changed successfully.'
                    }
                }
            ),
            400: "Bad Request - Validation errors",
            401: "Unauthorized - Invalid old password"
        }
    )
    def post(self, request):
        try:
            old_password = request.data.get('old_password')
            new_password = request.data.get('new_password')
            confirm_password = request.data.get('confirm_password')

            # Validate required fields
            if not old_password:
                return Response(
                    {"error": "Old password is required."},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            if not new_password:
                return Response(
                    {"error": "New password is required."},
                    status=status.HTTP_400_BAD_REQUEST
                )

            # Check if passwords match (if confirm_password provided)
            if confirm_password and new_password != confirm_password:
                return Response(
                    {"error": "New passwords do not match."},
                    status=status.HTTP_400_BAD_REQUEST
                )

            # Verify old password
            user = request.user
            if not user.check_password(old_password):
                return Response(
                    {"error": "Invalid old password."},
                    status=status.HTTP_401_UNAUTHORIZED
                )

            # Check if new password is different from old password
            if user.check_password(new_password):
                return Response(
                    {"error": "New password must be different from the current password."},
                    status=status.HTTP_400_BAD_REQUEST
                )

            # Set new password
            user.set_password(new_password)
            user.save()

            return Response(
                {"message": "Password changed successfully."},
                status=status.HTTP_200_OK
            )

        except Exception as e:
            return Response(
                {"error": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )