from rest_framework.views import APIView
from rest_framework import status
from rest_framework.response import Response
from .models import UserMaster ,DepartmentPermissions, UserLogins # Import your custom model
from .serializers import UserSerializer
from .utils import api_response
from django.db import connection
from django.contrib.auth.hashers import make_password,check_password
from django.utils.timezone import now
from django.db.models import Q
import uuid
from datetime import datetime
from django.db import connection

def fetch_department_permissions(user_id):
    with connection.cursor() as cursor:
        # Write the raw SQL query
        cursor.execute("""
            SELECT dp.DepartmentId AS DepartmentId, d.Department AS Department
            FROM DepartmentPermissions dp
            JOIN Departments d ON dp.DepartmentId = d.Id
            WHERE dp.UserId = %s
            AND dp.IsDeleted = 0
        """, [user_id])

        # Fetch all results
        rows = cursor.fetchall()

    # Process results (optional)
    results = [{'DepartmentId': row[0], 'Department': row[1]} for row in rows]
    return results
def generate_auth_token():
    return str(uuid.uuid4())

class LoginAPIView(APIView):
    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = UserMaster.objects.filter(Q(Username__exact=username) | Q(Email__exact=username)).first()
        if not user:
            return api_response(
                status_code=status.HTTP_401_UNAUTHORIZED,
                status="error",
                message="User does not exist."
            )
        hashed_password = make_password(password)
        is_valid = check_password(password, user.Password)
        if is_valid:
            if user.IsDeleted:
                return api_response(
                    status_code=status.HTTP_403_FORBIDDEN,
                    status="error",
                    message="User account is inactive."
                )
            accessible_departments = fetch_department_permissions(user.Id)
            departments_data = []
            for permission in accessible_departments:
                department_info = {
                    'department_id': permission['DepartmentId'],
                    'department_name': permission['Department']
                }
                departments_data.append(department_info)
            user.LastLogin = datetime.now()
            user.save()
            # Step 5: Serialize and return user details
            serializer = UserSerializer(user)
            # token, created = Token.objects.get_or_create(user=serializer.data['UserName'])
            log = UserLogins.objects.create(
                UserId=serializer.data['Id'],
                LoginTime=datetime.now(),
                AuthToken=generate_auth_token(),
            )
            return api_response(
                status_code=status.HTTP_200_OK,
                status="success",
                message="Login successful",
                data={
                    'loginid':log.Id,
                    'token':log.AuthToken,
                    'user': serializer.data,
                    'accessible_departments': departments_data  # Add the accessible departments to the response
                }
            )
        else:
            return api_response(
                status_code=status.HTTP_401_UNAUTHORIZED,
                status="error",
                message="Invalid credentials."
            )


class LogoutAPIView(APIView):
    def post(self, request):
        user_id = request.data.get('user_id')
        login_id = request.data.get('login_id')
        # Validate input
        if not user_id or not login_id:
            return api_response(
                status_code=status.HTTP_400_BAD_REQUEST,
                status="error",
                message="User Id and Login Id are required"
            )

        try:
            # Find the login record to update LogoutTime
            login_record = UserLogins.objects.filter(Id=login_id, UserId=user_id,AuthToken=request.headers.get('x-auth-token')).first()

            if not login_record:
                return api_response(
                    status_code=status.HTTP_404_NOT_FOUND,
                    status="error",
                    message="No matching login record found"
                )

            # Update the LogoutTime
            login_record.LogoutTime = datetime.now()
            login_record.IsActive = 0
            login_record.save()

            return api_response(
                status_code=status.HTTP_200_OK,
                status="success",
                message="Logged out successfully"
            )

        except Exception as e:
            return api_response(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                status="error",
                message=f"An error occurred: {str(e)}"
            )


class ValidateAuthToken(APIView):
    def post(self, request):
        auth_token = request.data.get('auth_token')  # Expecting the token in the request body
        if not auth_token:
            return Response(
                {
                    'status_code': 400,
                    'status': 'error',
                    'message': 'Missing AuthToken',
                    'details': 'Please provide a valid AuthToken.'
                },
                status=status.HTTP_400_BAD_REQUEST
            )

        # Check if token exists in UserLogins and if it's active
        user_login = UserLogins.objects.filter(AuthToken=auth_token, IsActive=1).first()

        try:
            user = UserMaster.objects.filter(Id=user_login.UserId, IsDeleted=0).first()
        except UserMaster.DoesNotExist:
            if not user_login:
                return Response(
                    {
                        "status": "error",
                        "status_code": status.HTTP_401_UNAUTHORIZED,
                        "message": "Invalid or expired auth token.",
                    },
                    status=status.HTTP_401_UNAUTHORIZED,
                )

        if not user_login:
            return Response(
                {
                    'status_code': 404,
                    'status': 'error',
                    'message': 'Invalid or expired AuthToken',
                    'details': 'The provided AuthToken is either invalid or expired.'
                },
                status=status.HTTP_404_NOT_FOUND
            )

        # If token is valid and active
        return Response(
            {
                'status_code': 200,
                'status': 'success',
                'message': 'AuthToken is valid and active.',
                'user_id': user_login.UserId,
                'email': user.Email,
                'name': f'{user.FirstName} {user.LastName}',
                'role': user.Role,
                'is_test_user': user.IsTestAccount,

            },
            status=status.HTTP_200_OK
        )


class UserMasterView(APIView):
    def post(self, request):
        # Retrieve user_id from the request body
        user_id = request.data.get('user_id', None)

        if user_id:
            # Fetch the specific user details based on user_id
            try:
                user = UserMaster.objects.get(Id=user_id, IsDeleted=False)
                serializer = UserSerializer(user)
                response_data = {
                    "status_code": status.HTTP_200_OK,
                    "status": "success",
                    "message": "User details fetched successfully.",
                    "data": serializer.data
                }
                return Response(response_data, status=status.HTTP_200_OK)
            except UserMaster.DoesNotExist:
                response_data = {
                    "status_code": status.HTTP_404_NOT_FOUND,
                    "status": "error",
                    "message": f"User with id {user_id} not found.",
                    "data": []
                }
                return Response(response_data, status=status.HTTP_404_NOT_FOUND)
        else:
            # Fetch all users
            users = UserMaster.objects.filter(IsDeleted=False)
            serializer = UserSerializer(users, many=True)
            response_data = {
                "status_code": status.HTTP_200_OK,
                "status": "success",
                "message": "All user details fetched successfully.",
                "data": serializer.data
            }
            return Response(response_data, status=status.HTTP_200_OK)

class GetUserDetailsView(APIView):
    def post(self, request):
        try:
            auth_token = request.data.get("auth_token")
            if not auth_token:
                return Response(
                    {
                        "status": "error",
                        "status_code": status.HTTP_400_BAD_REQUEST,
                        "message": "Auth token is required.",
                    },
                    status=status.HTTP_400_BAD_REQUEST,
                )

            # Fetch User ID from UserLogins using auth_token
            user_login = UserLogins.objects.filter(AuthToken=auth_token, IsActive=1).first()
            if not user_login:
                return Response(
                    {
                        "status": "error",
                        "status_code": status.HTTP_401_UNAUTHORIZED,
                        "message": "Invalid or expired auth token.",
                    },
                    status=status.HTTP_401_UNAUTHORIZED,
                )

            # Fetch user details from UserMaster
            user = UserMaster.objects.filter(Id=user_login.UserId, IsDeleted=0).first()
            if not user:
                return Response(
                    {
                        "status": "error",
                        "status_code": status.HTTP_404_NOT_FOUND,
                        "message": "User not found.",
                    },
                    status=status.HTTP_404_NOT_FOUND,
                )

            # Combine first name and last name
            full_name = f"{user.FirstName} {user.LastName}".strip()

            return Response(
                {
                    "status": "success",
                    "status_code": status.HTTP_200_OK,
                    "message": "User details fetched successfully.",
                    "data": {
                        "FullName": full_name,
                        "Email": user.Email,
                    },
                },
                status=status.HTTP_200_OK,
            )

        except Exception as e:
            return Response(
                {
                    "status": "error",
                    "status_code": status.HTTP_500_INTERNAL_SERVER_ERROR,
                    "message": "An error occurred while fetching user details.",
                    "error": str(e),
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )
