from django.shortcuts import render
from elasticsearch import Elasticsearch
from elasticsearch.exceptions import NotFoundError, AuthenticationException
from django.http import JsonResponse,HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import redirect
from django.contrib.auth import authenticate, login
import requests
import random,json
import string
import smtplib
import hashlib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formataddr
from datetime import datetime
from dateutil.relativedelta import relativedelta
from decouple import config
from django.core.mail import send_mail
from django.utils.decorators import method_decorator
from django.views import View
from django.utils import timezone
from django.utils.timezone import now
from django.views.decorators.http import require_POST

import sys,os
sys.path.append(os.path.join(os.path.dirname(__file__)))

import LogUtils

logger = LogUtils.getRootLogger()

CLOUD_ID = "SCIC_ElasticSearch:dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvOjQ0MyRmYWQyOTUwYTllNDE0MTE2YjIwN2QzYTE0MzQyMzcyMSRjZDI5OTY4MTQ1ODA0MDU4OWU4ZmVmMWQ2NDViYzNjMw=="

ELASTIC_PASSWORD = "8oKIqy312EBsAPzWT64NUzji"

es = Elasticsearch(cloud_id=CLOUD_ID, basic_auth=("elastic", ELASTIC_PASSWORD))

# scic_admin_ind=config('admin_index')
organ_token_ind=config('org_token_index')
corporate_user_ind=config('user_auth_index')
organ_user_ind=config('org_auth_index')
org_name = "organization_level_token_count"
corporate_token_ind=config('token_index')
es_index_name=config('es_index_name')
remove_index=config('remove_index')
es_index_archive=config('es_index_archive')



print('organ_user_ind',organ_user_ind)



@method_decorator(csrf_exempt, name='dispatch')
class NotifyView(View):
    def post(self, request):
        try:
            # Parse the request data
            data = json.loads(request.body)
            message = data.get('message')
            username = data.get('username')
            user_id = data.get('user_id')
            companyCode = data.get('companyCode')
            print('username',username)
            print('user_id',user_id)
            print('companyCode',companyCode)


            # Check if all necessary data is provided
            if not message or not username or not user_id or not companyCode:
                return JsonResponse({'status': 'error', 'message': 'Missing data'}, status=400)

            # Check if the user_id, username, and companyCode exist in the corporate_user_ind index
            user_check_query = {
                "query": {
                    "bool": {
                        "must": [
                            {"term": {"user_id.keyword": user_id}},
                            {"term": {"username.keyword": username}},
                            {"term": {"companyCode.keyword": companyCode}}
                        ]
                    }
                }
            }

            # Search for user existence in corporate_user_ind
            user_check_response = es.search(index=organ_user_ind, body=user_check_query)

            # If no matching user is found, return an error response
            if user_check_response['hits']['total']['value'] == 0:
                return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)

            # Check if a notification already exists for the same user_id and username
            search_query = {
                "query": {
                    "bool": {
                        "must": [
                            {"term": {"user_id.keyword": user_id}},
                            {"term": {"username.keyword": username}}
                        ]
                    }
                }
            }

            # Search for existing notifications with the same user_id and username
            response = es.search(index="notifications", body=search_query)

            # If a matching notification exists, return a response indicating it's already raised
            if response['hits']['total']['value'] > 0:
                sta_req=[]
                for i in response['hits']['hits']:
                    sta_req.append(i['_source'].get('request', None))
                # notification_status = response['hits']['hits'][0]['_source'].get('request', None)
                # print('sta_req',sta_req)
                if 0 in sta_req or 1 in sta_req:
                    notification_status=0
                else:
                    notification_status=1
                # print('notification_status',notification_status)
                if notification_status == 0:
                    # If status is 0, return a response indicating request is already raised
                    return JsonResponse({'status': 'success', 'message': 'Request already raised, waiting for approval'}, status=201)
                elif notification_status == 1:
                    # If status is 1, allow submission of a new notification
                    doc = {
                        "user_id": user_id,
                        "username": username,
                        "message": message,
                        "created_at": now().strftime('%Y-%m-%dT%H:%M:%S'),
                        "read": False,  # Default to unread
                        "companyCode": companyCode,
                        "request":0,
                    }
                    es.index(index="notifications", document=doc)
                    return JsonResponse({'status': 'success', 'message': 'Your request has been submitted successfully!'}, status=201)
                else:
                    return JsonResponse({'status': 'error', 'message': 'Invalid notification status'}, status=400)
            else:
                doc = {
                    "user_id": user_id,
                    "username": username,
                    "message": message,
                    "created_at": now().strftime('%Y-%m-%dT%H:%M:%S'),
                    "read": False,  # Default to unread
                    "companyCode": companyCode,
                    "request":0,
                }
                es.index(index="notifications", document=doc)
                return JsonResponse({'status': 'success', 'message': 'Your request has been submitted successfully!'}, status=201)
            
        except Exception as e:
            return JsonResponse({'status': 'error', 'message': str(e)}, status=500)


class NotificationListView(View):
    def get(self, request):
        try:
            print('entered notifylist')

            # Check if the user is authenticated
            companyCode = request.GET.get('companyCode') 
            print('companyCode',companyCode)
            if not companyCode:
                return JsonResponse({'status': 'error', 'message': 'User ID is required'}, status=400)

            # Query Elasticsearch for notifications
            query = {
                "query": {
                    "term": {"companyCode.keyword": companyCode}
                },
                "sort": [{"created_at": {"order": "desc"}}],
                "size": 100  # Limit to 100 notifications; adjust as needed
            }

            # Assuming es is an Elasticsearch instance and it is properly configured
            response = es.search(index="notifications", body=query)

            # Process Elasticsearch results
            hits = response["hits"]["hits"]
            unread_data = [
                {
                    "id": hit["_id"],
                    "message": hit["_source"]["message"],
                    "created_at": hit["_source"]["created_at"],
                    "read": hit["_source"]["read"],
                    "user_id":hit["_source"]["user_id"],
                    "username":hit["_source"]["username"],
                    "request":hit["_source"].get("request", 0)

                }
                for hit in hits if not hit["_source"]["read"]
            ]

            read_data = [
                {
                    "id": hit["_id"],
                    "message": hit["_source"]["message"],
                    "created_at": hit["_source"]["created_at"],
                    "read": hit["_source"]["read"],
                    "user_id":hit["_source"]["user_id"],
                    "username":hit["_source"]["username"],
                    "request":hit["_source"].get("request", 0)

                }
                for hit in hits if hit["_source"]["read"]
            ]

            response_data = {
                "unread": unread_data,
                "read": read_data,
                "unread_count": len(unread_data)
            }

            return JsonResponse(response_data)

        except Exception as e:
            print('error in notify list', e)
            return JsonResponse({'status': 'error', 'message': str(e)}, status=500)

@method_decorator(csrf_exempt, name='dispatch')
class approve_notification(View):
    def post(self, request):
        try:
            # Parse the incoming JSON data
            data = json.loads(request.body)
            print('data',data)

            # Extract the relevant fields from the request data
            notification_id = data.get('notification_id')
            status_code = data.get('request_status')

            print('notification_id',notification_id)
            try:
            
                update_body = {
                    "doc": {
                        "request":status_code
                        
                    }
                }
    
                # Perform the update
                response = es.update(index='notifications', id=notification_id, body=update_body)
                return JsonResponse({'status': 'success', 'message': 'Notification approved successfully.'})
            except Exception as e:
                # If there's an error, return a failure response
                print('error exce',e)
                return JsonResponse({'status': 'error', 'message': str(e)}, status=400)
        except Exception as e:
            # If there's an error, return a failure response
            print('error inhere',e)

            return JsonResponse({'status': 'error', 'message': str(e)}, status=400)


@method_decorator(csrf_exempt, name='dispatch')
class MarkNotificationReadView(View):
    def post(self, request):
        try:
            # Parse the JSON body of the request
            data = json.loads(request.body.decode('utf-8'))  # Decode to handle potential encoding issues
            notification_id = data.get('id')

            # Validate notification ID
            if not notification_id:
                return JsonResponse({"status": "error", "message": "Notification ID is required"}, status=400)

            # Update the notification in Elasticsearch
            es.update(
                index="notifications",
                id=notification_id,
                body={"doc": {"read": True}}
            )

            return JsonResponse({"status": "success", "message": "Notification marked as read"})
        except json.JSONDecodeError:
            # Handle JSON decoding errors
            return JsonResponse({"status": "error", "message": "Invalid JSON body"}, status=400)
        except Exception as e:
            # Handle any other exceptions
            return JsonResponse({"status": "error", "message": str(e)}, status=500)

def corporate_dashboard(request):
    if 'name' in request.session:  # Check if the session contains the 'name'
        name = request.session.get('name')  # Get 'name' from session
        uid = request.session.get('unique_id')  # Get 'name' from session
        return render(request,'corporate_dashbord.html',{'user_name': name,'uniqueId':uid})
    else:
        return redirect('corporate_login')  # Redirect to login page if not logged in


# Protect index2 view - allow access only if user is authenticated
def corporate_user(request):
    if 'name' in request.session:  # Check if the session contains the 'name'
        name = request.session.get('name')  # Get 'name' from session
        uid = request.session.get('unique_id')  # Get 'name' from session

        return render(request, "corporate_user.html",{'user_name': name,'uniqueId':uid})
    else:
        return redirect('corporate_login')  # Redirect to login page if not logged in

def corporate_request(request):
    if 'name' in request.session:  # Check if the session contains the 'name'
        name = request.session.get('name')  # Get 'name' from session
        uid = request.session.get('unique_id')  # Get 'name' from session

        return render(request, "corporate_request.html",{'user_name': name,'uniqueId':uid})
    else:
        return redirect('corporate_login')  # Redirect to login page if not logged in

def corporate_status(request):
    if 'name' in request.session:  # Check if the session contains the 'name'
        name = request.session.get('name')  # Get 'name' from session
        uid = request.session.get('unique_id')  # Get 'name' from session

        return render(request, "corporate_status.html",{'user_name': name,'uniqueId':uid})
    else:
        return redirect('corporate_login')  # Redirect to login page if not logged in

# @csrf_exempt
# class SendNotificationView(View):
#     def post(self, request):
#         try:
#             name = request.session.get('name')
#             unique_id = request.session.get('unique_id')
            
#             if not name or not unique_id:
#                 return JsonResponse({'status': 'error', 'message': 'User not logged in or missing session data'}, status=400)

#             message = request.POST.get('message', 'New Request Notification')

#             url = 'http://127.0.0.1:8002/notify-corporatebot/'  # Replace with actual domain

#             payload = {
#                 'message': message,
#                 'username': name,
#                 'user_id': unique_id
#             }
#             print("Payload being sent:", payload)  # Debug payload

#             headers = {'Content-Type': 'application/json'}
#             response = requests.post(url, json=payload, headers=headers)

#             if response.status_code in (200, 201):
#                 return JsonResponse({'status': 'Notification sent'}, status=200)
#             else:
#                 return JsonResponse({
#                     'status': 'Failed to send notification',
#                     'response': response.json()
#                 }, status=response.status_code)
#         except Exception as e:
#             print("Error in SendNotificationView:", str(e))  # Debug error
#             return JsonResponse({'status': 'error', 'message': str(e)}, status=500)
        
@csrf_exempt  # Remove this in production if CSRF protection is enabled
def status_corporate(request):
    print('Request Method:', request.method)
    if request.method == "POST":
        data = json.loads(request.body)
        # Extract values from the parsed JSON
        username = data.get("username")
        companyCode = data.get("companyCode")
        
        # Handle the login form submission
        # username = request.POST.get("username")
        # companyCode=request.POST.get("companyCode")
        print('username', username)
        print('corporcom',companyCode)
        logger.info("username%s " % username)

        try:
            # Query Elasticsearch to find the user
            response = es.search(
                index='notifications',
                body={
                    "query": {
                        "bool": {
                            "must":[
                                {"term": {"username.keyword": username}},
                                {"term": {"companyCode.keyword": companyCode}},
                            ]
                        }
                    }
                }
            )
            print('response',response)
            
            userlist=[]
            # Check if any user matched the query
            if response['hits']['total']['value'] > 0:
                for hit in response['hits']['hits']:
                    source = hit['_source']
                    if source.get("request", 0) ==2:
                        request_sta="Approved"
                    elif source.get("request", 0) ==3:
                        request_sta="Declined"
                    else:
                        request_sta="Pending"
                        
                    formatted_doc = {
                        "name": source.get("username"),
                        "user_id": source.get("user_id"),
                        "message": source.get("message"),
                        "created_at": source.get("created_at"),
                        "request": request_sta
                        
                    }
                    userlist.append(formatted_doc)
                    
            return JsonResponse({"userlist": userlist})

                    
        except Exception as e:
            print('error',e)
            return HttpResponse(f"An error occurred: {e}")
    else:
        print('else satisfied')
        return HttpResponse("Invalid method")




@csrf_exempt

def corporate_login_view(request):
    if request.method == "POST":
        # Handle the login form submission
        username = request.POST["username"]
        password = request.POST["password"]
        companyCode=request.POST["companyCode"]
        print('username', username)
        print('password', password)
        logger.info("username%s " % username)

        try:
            # Query Elasticsearch to find the user
            response = es.search(
                index=corporate_user_ind,
                body={
                    "query": {
                        "bool": {
                            "must":[
                                {"term": {"username.keyword": username}},  # Exact match using 'term' query
                                {"term": {"companyCode.keyword": companyCode}},
                            ]
                        }
                    }
                }
            )

            # Check if any user matched the query
            if response['hits']['total']['value'] > 0:
                for hit in response['hits']['hits']:
                    source = hit['_source']
                    print('source',source)
                    if 'password' in source:
                        if source['password'] == password:
                            # Set session data for the logged-in user
                            request.session['name'] = username
                            request.session['unique_id'] = companyCode
                            if 'Riea_company' in source:
                                request.session['Riea_company'] = source['Riea_company']
                            else:
                                request.session['Riea_company'] = None
                            
                            logger.info(f"User {username} authenticated successfully. Redirecting to index.")
                            return redirect("corporate_dashboard")  # Redirect to index after successful login
                        else:
                            return render(request, "corporate_login.html", {"error": "Invalid credentials"})
                    else:
                        return render(request, "corporate_login.html", {"error": "Invalid credentials"})
            else:
                return render(request, "corporate_login.html", {"error": "Invalid credentials"})

        except Exception as e:
            return HttpResponse(f"An error occurred: {e}")

    # If the request is GET, render the login page
    return render(request, "corporate_login.html")

# Logout view to clear session data
@csrf_exempt
def logout_view(request):
    request.session.flush()  # Clears all session data
    return redirect('corporate_login')  # Redirect to login page after logout

@csrf_exempt
def forgot_password_view(request):
    if request.method == "POST":
        username = request.POST.get("username")
        companyCode = request.POST.get("companyCode")
        print('username',username)
        try:
            # Search for the user in Elasticsearch
            response = es.search(
                index=corporate_user_ind,
                body={
                    "query": {
                        "bool": {
                            "must":[
                                {"term": {"username.keyword": username}},  # Exact match using 'term' query
                                {"term": {"companyCode.keyword": companyCode}},
                            ]
                        }
                    }
                }
            )

            if response['hits']['total']['value'] > 0:
                user_data = response['hits']['hits'][0]['_source']
                user_email = user_data.get("mail")  # Attempt to retrieve the email
            
                if user_email:  # Check if email is present
                    print('user_email', user_email)
                    
                    # Send verification email
                    message = "Click the link below to reset your password:\n\n"
                    message += request.build_absolute_uri("/corporate-reset-password/")
                    print('message', message)
                    
                    send_mail(
                        subject="Password Reset Request",
                        message=message,
                        from_email="tna@scic.com",
                        recipient_list=[user_email],
                        fail_silently=False,
                    )
                    
                    return render(request, "corporate_forgot_password.html", {"message": "Password reset link sent to your email."})
                else:
                    # Handle missing email
                    return render(request, "corporate_forgot_password.html", {"error": "Email not found for this user."})
            else:
                return render(request, "corporate_forgot_password.html", {"error": "User not found."})

        except Exception as e:
            return HttpResponse(f"An error occurred: {e}")

    return render(request, "corporate_forgot_password.html")

@csrf_exempt
def reset_password_view(request):
    if request.method == "POST":
        username = request.POST.get("username")
        companyCode = request.POST.get("companyCode")
        new_password = request.POST.get("new_password")
        print('username',username)
        try:
            # Find the user by username
            response = es.search(
                index=corporate_user_ind,
                body={
                    "query": {
                        "bool": {
                            "must":[
                                {"term": {"username.keyword": username}},  # Exact match using 'term' query
                                {"term": {"companyCode.keyword": companyCode}},
                            ]
                        }
                    }
                }
            )


            if response['hits']['total']['value'] > 0:
                user_id = response['hits']['hits'][0]['_id']

                # Update the user's password
                es.update(
                    index=corporate_user_ind,
                    id=user_id,
                    body={
                        "doc": {
                            "password": new_password  # Be sure to hash this in a real application
                        }
                    }
                )
                return render(request, "corporate_reset_password.html", {"message": "Password has been reset successfully."})
            else:
                return HttpResponse("User not found.")

        except Exception as e:
            return HttpResponse(f"An error occurred: {e}")

    return render(request, "corporate_reset_password.html")



def post_to_elasticsearch(user_data):
    """
    Post data to Elasticsearch.

    :param url: str - The Elasticsearch endpoint.
    :param auth: tuple - A tuple containing the username and password for authentication.
    :param user_data: dict - The data to be posted.
    :return: dict - The response from Elasticsearch.
    """
    try:
        
        # Make the POST request
        url = f"https://scic-elasticsearch.es.us-central1.gcp.cloud.es.io:443/{organ_user_ind}/_doc"

        response = requests.post(url, auth=('elastic', '8oKIqy312EBsAPzWT64NUzji'), json=user_data)


        # Check the response status
        if response.status_code == 201:  # 201 Created
            print("Data posted successfully:", response.json())
            return response.json()
        else:
            print("Error posting data:", response.status_code, response.text)
            return None
    except Exception as e:
        print("An error occurred:", e)
        return None

# Generate a random 8-character alphanumeric string
def generate_random_string(length=8):
    characters = string.ascii_letters + string.digits  # Includes both letters and numbers
    return ''.join(random.choice(characters) for _ in range(length))

# username="chancebest"
# mailid= "karthikraj@qubespace.in"


def send_email(username,password,mailid,userid,companyCode,Riea_company):
    try:
        # Set SMTP server details
        smtp_server = "smtp.office365.com"
        smtp_port = 587
        email_username = "tna@scic.com"  # Replace with your email
        email_password = "G!vv38Os5#"  # Replace with your password
        
        user_data = {
        "username": f'{username}',
        "password": f'{password}',
        "mail":f'{mailid}',
        "user_id": f'{userid}',
        "companyCode":f'{companyCode}',
        "Riea_company":f'{Riea_company}'
        }
        
        post_to_elasticsearch(user_data)

        # Create a multipart email message
        msg = MIMEMultipart()
        msg['From'] = formataddr(("AlliBot2.0", email_username))  # Optional: Set a name for the sender
        msg['To'] = ", ".join([f'{mailid}'])  # Add multiple recipients
        msg['Subject'] = "Reg: AlliBot user credentials"

        # Email body
        body = f'''
        <html>
        <body>
            <p> User credentials</p>
            <p><strong>UserId:</strong> {userid}</p>
            <p><strong>Username:</strong> {username}</p>
            <p><strong>Password:</strong> {password}</p>
        </body>
        </html>
        '''
        msg.attach(MIMEText(body, "html"))  # Attach HTML body

        # Set up the SMTP client and send the email
        with smtplib.SMTP(smtp_server, smtp_port) as client:
            client.starttls()  # Upgrade to a secure connection
            client.login(email_username, email_password)  # Login
            client.send_message(msg)  # Send the email
            print("Email sent successfully.")

    except Exception as ex:
        print(f"Error sending email: {ex}")

def check_userid_exists(request):
    try:
        if request.method == "POST":
            unique_id = request.POST.get("userId")
            index_name = request.POST.get("indexname")
            companyCode = request.POST.get("companyCode")
    
            # print('unique_id',companyCode)
            response = es.search(
                index=index_name,
                body={
                    "query": {"term": {"companyCode.keyword": companyCode}},
                    "size": 5000,  # Increase the size to 100 or any other number
                },
            )
            # print('response',response)
            
            matched_user = response["hits"]["hits"]
            # print('matched_user')
            if not matched_user:
                # print('entered')
                # return False
                return JsonResponse({"exists":False})

            else:
            # Extract the assigned token values
                # print('else s')
                unique_idlist = []
                for hit in response["hits"]["hits"]:
                    document = hit["_source"]
                    # print('document',document)
                    if 'user_id' in document:
                        unique_idlist.append(document['user_id'])
                # return unique_id in unique_idlist
                return JsonResponse({"exists":unique_id in unique_idlist})

        else:
            # Return an error response when unique_id is not provided
            return JsonResponse({'error': 'companyCode is required.'}, status=400)
    except Exception as e:
        print('error',e)
        logger.info('check user id error%s'%e)

@csrf_exempt
def update_assigned_token(request):
    if request.method == "POST":
        
        index_name = request.POST.get("indexname")
        username = request.POST.get("username")
        userid = request.POST.get("userId")
        companyCode=request.POST.get("companyCode")
        token_count=request.POST.get("token_value")
        limits_token_flag=request.POST.get("limits_token")



        print('username',username)
        try:
            # Find the user by username
            response = es.search(
                index=index_name,
                body={
                    "query": {
                        "bool": {
                            "must": [
                                {"term": {"user_id.keyword": userid}},
                                {"term": {"username.keyword": username}},
                                {"term": {"companyCode.keyword": companyCode}},

                            ]
                        }
                    }
                }
            )

            if response['hits']['total']['value'] > 0:
                user_id = response['hits']['hits'][0]['_id']

                # Update the user's password
                es.update(
                    index=index_name,
                    id=user_id,
                    body={
                        "doc": {
                            "assigned_tokens": int(token_count),
                            "limits_token":limits_token_flag# Be sure to hash this in a real application
                        }
                    }
                )
                print('success update token')
                return JsonResponse({"messages": "success",'userid':userid})
            else:
                return HttpResponse("No documents found matching username '${username}'.")

        except Exception as e:
            return HttpResponse(f"An error occurred: {e}")

    return JsonResponse({"error": "Invalid request"}, status=400)


@csrf_exempt  # Use this if you're sending POST requests without CSRF tokens
def create_new_user(request):
    if request.method == "POST":
        # Extract data from POST request
        index_name = request.POST.get("indexname")
        username = request.POST.get("name")
        mail_id = request.POST.get("mail")
        tokens = request.POST.get("assignedtokens")
        userid = request.POST.get("userId")
        companyCode=request.POST.get("companyCode")
        Riea_company=request.session.get('Riea_company')


        print('userid',companyCode)
        document = {
            "username": username,
            "assigned_tokens": int(tokens),
            "mail": mail_id,
            "user_id":userid,
            "companyCode":companyCode,
            "limits_token":1,
            "Riea_company":Riea_company
        }

        # Add the document to the specified index
        response = es.index(index=index_name, body=document)
        password = generate_random_string()

        send_email(username,password,mail_id,userid,companyCode,Riea_company)

        return JsonResponse({"messages": "success",'userid':userid})

    # If not a POST request, return an empty response or error
    return JsonResponse({"error": "Invalid request"}, status=400)

@csrf_exempt  # Use this if you're sending POST requests without CSRF tokens
def check_user_exists(request):
    try:
        if request.method == "POST":
            addeduser = request.POST.get("username")
            ind_name = request.POST.get("indexname")
            companyCode = request.POST.get("companyCode")
            mail = request.POST.get("mail")


        # Search for all documents in the index
            response = es.search(
                index=ind_name,
                body={
                    "query": {"term": {"companyCode.keyword": companyCode}},
                    "size": 5000,  # Increase the size to 100 or any other number
                },
            )
            # Extract the assigned token values
            userName = []
            mail_add=[]
            for hit in response["hits"]["hits"]:
                document = hit["_source"]
                # print('document',document)

                # Replace 'assigned_tokens' with the actual field name in your documents
                assigned_token = document.get(
                    "username", 0
                )  # Returns 0 if the token doesn't exist
                mail_id=document.get(
                    "mail", 0
                )
                userName.append(assigned_token)
                mail_add.append(mail_id)
            print('mail_add',mail_add)
            if addeduser in userName:
                # print('userName',userName)
                # print('if',addeduser)
                return JsonResponse({"message":False,'status':'user'})
            elif mail in mail_add:
                return JsonResponse({"message":False,'status':'mail'})
            
            else:
                # print('else')
                # print('userName',userName)
                # print('else',addeduser)
                return JsonResponse({"message":True,'status':'success'})
            
    
    except NotFoundError as e:
        return JsonResponse({"error": "Not Found: " + str(e)}, status=404)
    except AuthenticationException as e:
        return JsonResponse({"error": "Authentication Error: " + str(e)}, status=401)
    except Exception as e:
        return JsonResponse({"error": str(e)}, status=500)



@csrf_exempt  # Use this if you're sending POST requests without CSRF tokens
def organization_overalltokens(request):
    try:
        if request.method == "POST":
            data = json.loads(request.body)
            # Extract values from the parsed JSON
            corporateName = data.get("username")
            ind_name = data.get("index")
            companyCode = data.get("companyCode")
            
            # print('corporateName',corporateName)
            # print('ind_name',ind_name)
            # print('companyCode',companyCode)

            # Perform the Elasticsearch search query
            response = es.search(
                index=ind_name,  # Replace with your actual index name
                body={
                    "query": {
                        "bool": {
                            "must":[
                                {"term": {"username.keyword": corporateName}},  # Exact match using 'term' query
                                {"term": {"companyCode.keyword": companyCode}},
                            ]
                        }
                    }
                }
            )
               
    
        
            # Extract the hits from the response
            org_tokens = response["hits"]["hits"]
            
            if not org_tokens:
                return JsonResponse(
                    {
                        "messages": {
                            "Overall_tokens": "Not Available",
                            "assigned_tokens": "Not Available",
                            "percentage": 0,
                        }
                    },
                    status=404,
                )
            
    
            else:
                for hit in org_tokens:
                    if 'assigned_tokens' in hit["_source"]:
                        overall_assign=hit["_source"]["assigned_tokens"]
                        
                # Search for all documents in the index
                # response = es.search(
                #     index=organ_token_ind,
                #     body={
                #         "query": {"match_all": {}},
                #         "size": 5000,  # Increase the size to 100 or any other number
                #     },
                # )
                
                response = es.search(
                    index=organ_token_ind,  # Replace with your actual index name
                    body={
                        "query": {
                            "bool": {
                                "must": [
                                    {"term": {"companyCode.keyword": companyCode}},
                                ]
                            }
                        }
                    },
                )
        
                # Extract the assigned token values
                assignedTok = []
                for hit in response["hits"]["hits"]:
                    document = hit["_source"]
                    # print('document',document)
    
                    # Replace 'assigned_tokens' with the actual field name in your documents
                    assigned_token = document.get(
                        "assigned_tokens", 0
                    )  # Returns 0 if the token doesn't exist
                    assignedTok.append(assigned_token)
                    
                # print('overall_assign',overall_assign)
                # print('assignedTok',assignedTok)
                
                info={
                        "overall_tokens": overall_assign,
                        "assigned_tokens": sum(assignedTok),
                        "percentage":round((sum(assignedTok)/overall_assign)*100),
                    }
                          
                # print('info',assignedTok)
                return JsonResponse({"messages": info})

    except NotFoundError as e:
        return JsonResponse({"error": "Not Found: " + str(e)}, status=404)
    except AuthenticationException as e:
        return JsonResponse({"error": "Authentication Error: " + str(e)}, status=401)
    except Exception as e:
        print('error',e)
        return JsonResponse({"error": str(e)}, status=500)


@csrf_exempt  # Use this if you're sending POST requests without CSRF tokens
def organization_tokens_percentage(request):
    try:
        if request.method == "POST":
            data = json.loads(request.body)
    
            # Extract values from the parsed JSON
            corporateName = data.get("username")
            ind_name = data.get("index")
            companyCode = data.get("companyCode")
            
            # print('corporateName',corporateName)
            # print('ind_name',ind_name)
            # print('companyCode',companyCode)
        
            org_tokens = es.search(
                index=ind_name,
                body={
                    "query": {
                        "bool": {
                            "must": [
                                {"term": {"username.keyword": corporateName}},
                                {"term": {"companyCode.keyword": companyCode}},
                            ]
                        }
                    }
                },
            )["hits"]["hits"]
    
            if not org_tokens:
                return JsonResponse({"messages": {"assigned_tokens": 0}}, status=404)
            else:
                # Process only the first document
                doc_source = org_tokens[0]["_source"]
                info = {
                    "assigned_tokens": doc_source.get("assigned_tokens", 0),
                }
                return JsonResponse({"messages": info})
    
    except NotFoundError as e:
        return JsonResponse({"error": "Not Found: " + str(e)}, status=404)
    except AuthenticationException as e:
        return JsonResponse({"error": "Authentication Error: " + str(e)}, status=401)
    except Exception as e:
        print('progress error',e)
        return JsonResponse({"error": str(e)}, status=500)


@csrf_exempt  # Use this if you're sending POST requests without CSRF tokens
def get_users_assigntoken(request):
    try:
        if request.method == "POST":
            # data = json.loads(request.body)
            ind_name = request.POST.get('index_name')
            companyCode = request.POST.get('companyCode')
            corporateName = request.POST.get('corp_index')
            compusername = request.POST.get('compName')
         
            # ind_name = data.get("index_name")
            # companyCode = data.get("companyCode")
            # corporindex = data.get("corporindex")
            print('corporateName',corporateName)
            response = es.search(
                index=corporateName,  # Replace with your actual index name
                body={
                    "query": {
                        "bool": {
                            "must":[
                                {"term": {"username.keyword": compusername}},  # Exact match using 'term' query
                                {"term": {"companyCode.keyword": companyCode}},
                            ]
                        }
                    }
                }
            )
               
    
        
            # Extract the hits from the response
            org_tokens = response["hits"]["hits"]
            print('org_tokens',org_tokens)
            
            if not org_tokens:
                overall_assign=0
            else:
                for hit in org_tokens:
                    if 'assigned_tokens' in hit["_source"]:
                        overall_assign=hit["_source"]["assigned_tokens"]
                        

            print('unique_id',companyCode)
            print('ind_name',ind_name)
            response = es.search(
                index=ind_name,
                body={
                    "query": {"term": {"companyCode.keyword": companyCode}},
                    "size": 5000,  # Increase the size to 100 or any other number
                },
            )       
            
            # print('response',response)
            # Extract the assigned token values
            assignedTok = []
            for hit in response["hits"]["hits"]:
                document = hit["_source"]
                # Replace 'assigned_tokens' with the actual field name in your documents
                assigned_token = document.get(
                    "assigned_tokens", 0
                )  # Returns 0 if the token doesn't exist
                assignedTok.append(assigned_token)
            
            userTok=[]
            for hit in response["hits"]["hits"]:
                document = hit["_source"]
                # Replace 'assigned_tokens' with the actual field name in your documents
                assigned_token = document.get(
                    "overall_tokens", 0
                )  # Returns 0 if the token doesn't exist
                userTok.append(assigned_token)
            # print('documents_tokens',documents_tokens)
            # print('overall assign',sum(documents_tokens))
            if assignedTok:
                perc=round((sum(userTok)/sum(assignedTok))*100)
            else:
                # print('else satis')
                perc=0
            if overall_assign:
                used_perc=round((sum(userTok)/overall_assign)*100)
            else:
                # print('else satis')
                used_perc=0
            
            return JsonResponse({"total":{'overallAssigned':sum(assignedTok),'mainAssigned':overall_assign,'overallUsed':sum(userTok),'token_percen':perc,'used_perc':used_perc}})
            
            # return JsonResponse({"total":{'overallAssigned':sum(assignedTok),'mainAssigned':overall_assign,'overallUsed':sum(userTok),'token_percen':perc}})
            # return JsonResponse({"total":{'overallAssigned':overall_assign,'overallUsed':sum(userTok),'token_percen':perc}})

    except NotFoundError as e:
        return JsonResponse({"error": "Not Found: " + str(e)}, status=404)
    except AuthenticationException as e:
        return JsonResponse({"error": "Authentication Error: " + str(e)}, status=401)
    except Exception as e:
        print('get users assign error',e)
        return JsonResponse({"error": str(e)}, status=500)


@csrf_exempt  # Use this if you're sending POST requests without CSRF tokens
def get_user_list(request):
    if request.method == "POST":
        # Extract data from POST request
        index_name = request.POST.get("index_name")
        companyCode = request.POST.get("companyCode")
        # print('index_name',index_name)
        # print('companyCode',companyCode)
        try:
            # Query to get all documents
            query = {"query": {"term": {"companyCode.keyword": companyCode}}}

            # Execute the search query
            response = es.search(
                index=index_name, body=query, size=1000
            )  # Adjust size for more results

            # Extract details and format them
            # print('response',response)
            output = []
            for hit in response["hits"]["hits"]:
                source = hit["_source"]
                # Extract necessary fields: username, mail, overall token, token used
                formatted_doc = {
                    "name": source.get("username"),
                    "user_id": source.get("user_id"),
                    "mail": source.get("mail"),
                    "org_tokens": source.get("overall_tokens", 0),
                    "tokens": source.get("assigned_tokens"),
                    
                }
                output.append(formatted_doc)

            # Return the formatted output
            # print('output',output)
            return JsonResponse({"userlist": output})

        except Exception as e:
            # Log the error or handle it as needed
            return JsonResponse({"error": str(e)}, status=500)

    return JsonResponse({"error": "Invalid request method."}, status=405)

@csrf_exempt  # Use this if you're sending POST requests without CSRF tokens
def get_removeduser(request):
    if request.method == "POST":
        # Extract data from POST request
        companyCode = request.POST.get("companyCode")
        # print('index_name',index_name)
        # print('companyCode',companyCode)
        
        try:
            # Query to get all documents
            query = {"query": {"term": {"companyCode.keyword": companyCode}}}

            # Execute the search query
            response = es.search(
                index=remove_index, body=query, size=1000
            )  # Adjust size for more results

            # Extract details and format them
            # print('response',response)
            output = []
            for hit in response["hits"]["hits"]:
                source = hit["_source"]
                
                # Extract necessary fields: username, mail, overall token, token used
                formatted_doc = {
                    "username": source.get("username"),
                    "userid": source.get("user_id"),
                    "mailid": source.get("mail"),
                    "usertok": source.get("overall_tokens", 0),
                    "assignetok": source.get("assigned_tokens"),
                    "removedDate":source.get("removedDate")
                    
                }
                output.append(formatted_doc)

            # Return the formatted output
            print('output',output)
            return JsonResponse({"userlist": output})

        except Exception as e:
            # Log the error or handle it as needed
            return JsonResponse({"error": str(e)}, status=500)

    return JsonResponse({"error": "Invalid request method."}, status=405)

# Function to get records for a specified month and year
def get_monthly_records(year, month, model_name,companyCode,field_name):
    
    year = int(year)
    month = int(month)
    # Initialize a dictionary to hold results for the specified month
    monthly_results = {}
    
    # Calculate the start and end dates for the month
    start_date = datetime(year, month, 1)
    end_date = (start_date + relativedelta(months=1)).replace(day=1)
    
    # Convert dates to epoch milliseconds
    start_epoch = int(start_date.timestamp() * 1000)
    end_epoch = int(end_date.timestamp() * 1000)
    
    # Define both index names
    es_index_name_1 = es_index_name  # Original index
    es_index_name_2 = es_index_archive  # The new index you want to fetch records from
    
    # Define a reusable function to fetch records from a given index
    def fetch_records(index_name):
        # Elasticsearch query for the specific month
        query = {
            "query": {
                "bool": {
                    "must": [
                        {"term": {f"{field_name}.keyword": model_name}},  # Exact match using 'term' query
                        {"term": {"companyCode.keyword": companyCode}},  # Exact match for companycode
                        {
                            "range": {
                                "created_at": {
                                    "gte": start_epoch,
                                    "lt": end_epoch  # use 'lt' for exclusive end date
                                }
                            }
                        }
                    ]
                }
            },
            "size":10000,
        }
    
        # Execute the search
        response = es.search(index=index_name, body=query)
        # print('indexname', index_name)
        # print('response', response)
    
        # Return the hits
        return response['hits']['hits']
    
    # Fetch records from both indices
    hits_1 = fetch_records(es_index_name_1)
    hits_2 = fetch_records(es_index_name_2)
    
    # Concatenate results
    all_hits = hits_1 + hits_2
    
    # Store concatenated results in the dictionary
    monthly_results[start_date.strftime("%B %Y")] = all_hits
    
    # Print the combined results
    # print('Monthly Results:', monthly_results)


    
    return monthly_results


@csrf_exempt  # Use this if you're sending POST requests without CSRF tokens
def chart_view(request):
    if request.method == "POST":
        # Extract data from POST request
        input_year = request.POST.get("year")
        input_month = request.POST.get("month")
        # indexname = request.POST.get("indexname")
        companyCode = request.POST.get("companyCode")
        
        # print('indexname',indexname)
        print('companyCode',companyCode)

        try:
            results = get_monthly_records(input_year, input_month, "gpt-4-turbo",companyCode,'modelname')

            model_turbolist = [0] * 31  # Initialize a list for 31 days
            for month, records in results.items():
                print(f"Records for {month}:", len(records))
                
                for record in records:
                    timestamp_ms = record['_source'].get('created_at')  
                    if timestamp_ms:
                        timestamp_s = timestamp_ms / 1000.0
                        date = datetime.fromtimestamp(timestamp_s)
                        day = date.day - 1  
                        
                        if 'human token' in record['_source']:
                            model_turbolist[day] += record['_source']['human token']
                        elif 'assistant token' in record['_source']:
                            model_turbolist[day] += record['_source']['assistant token']

            if input_month in [4, 6, 9, 11]:
                model_turbolist = model_turbolist[:30]
            elif input_month == 2:
                if (input_year % 4 == 0 and input_year % 100 != 0) or (input_year % 400 == 0):
                    model_turbolist = model_turbolist[:29]
                else:
                    model_turbolist = model_turbolist[:28]

            results = get_monthly_records(input_year, input_month, "gpt-3.5-turbo-1106",companyCode,'gpt35_modelname')

            model_gpt35list = [0] * 31  
            for month, records in results.items():
                print(f"Records for {month}:")
                
                for record in records:
                    # print('gpt 3.5 record',record)
                    timestamp_ms = record['_source'].get('created_at')  
                    if timestamp_ms:
                        timestamp_s = timestamp_ms / 1000.0
                        date = datetime.fromtimestamp(timestamp_s)
                        day = date.day - 1  
                        
                        if 'input_token_accu' in record['_source']:
                            print('input acc',record['_source']['input_token_accu'])
                            model_gpt35list[day] += record['_source']['input_token_accu']
                        if 'output_token_accu' in record['_source']:
                            print('output tok',record['_source']['output_token_accu'])
                            model_gpt35list[day] += record['_source']['output_token_accu']

            if input_month in [4, 6, 9, 11]:
                model_gpt35list = model_gpt35list[:30]
            elif input_month == 2:
                if (input_year % 4 == 0 and input_year % 100 != 0) or (input_year % 400 == 0):
                    model_gpt35list = model_gpt35list[:29]
                else:
                    model_gpt35list = model_gpt35list[:28]
            
            results = get_monthly_records(input_year, input_month, "gpt-4-0125-preview",companyCode,'modelname')

            model_previewlist = [0] * 31  
            for month, records in results.items():
                print(f"Records for {month}:")
                
                for record in records:
                    timestamp_ms = record['_source'].get('created_at')  
                    if timestamp_ms:
                        timestamp_s = timestamp_ms / 1000.0
                        date = datetime.fromtimestamp(timestamp_s)
                        day = date.day - 1  
                        
                        if 'human token' in record['_source']:
                            model_previewlist[day] += record['_source']['human token']
                        elif 'assistant token' in record['_source']:
                            model_previewlist[day] += record['_source']['assistant token']

            if input_month in [4, 6, 9, 11]:
                model_previewlist = model_previewlist[:30]
            elif input_month == 2:
                if (input_year % 4 == 0 and input_year % 100 != 0) or (input_year % 400 == 0):
                    model_previewlist = model_previewlist[:29]
                else:
                    model_previewlist = model_previewlist[:28]

            results = get_monthly_records(input_year, input_month, "gpt-4o",companyCode,'modelname')

            model_gpt4olist = [0] * 31  
            for month, records in results.items():
                print(f"Records for {month}:")
                
                for record in records:
                    timestamp_ms = record['_source'].get('created_at')  
                    if timestamp_ms:
                        timestamp_s = timestamp_ms / 1000.0
                        date = datetime.fromtimestamp(timestamp_s)
                        day = date.day - 1  
                        
                        if 'human token' in record['_source']:
                            model_gpt4olist[day] += record['_source']['human token']
                        elif 'assistant token' in record['_source']:
                            model_gpt4olist[day] += record['_source']['assistant token']

            if input_month in [4, 6, 9, 11]:
                model_gpt4olist = model_gpt4olist[:30]
            elif input_month == 2:
                if (input_year % 4 == 0 and input_year % 100 != 0) or (input_year % 400 == 0):
                    model_gpt4olist = model_gpt4olist[:29]
                else:
                    model_gpt4olist = model_gpt4olist[:28]

            context = {'model_gpt4turbo':  [None if x == 0 else x for x in model_turbolist], 'model_gpt35':  [None if x == 0 else x for x in model_gpt35list],
                       'model_preview':  [None if x == 0 else x for x in model_previewlist],'model_gpt4':  [None if x == 0 else x for x in model_gpt4olist],
                       'total_token': sum(model_turbolist+model_gpt35list+model_previewlist+model_gpt4olist)}
            # print('context', context)
            return JsonResponse(context)

        except Exception as e:
            # Create zero lists based on the input month
            if input_month in [4, 6, 9, 11]:
                days_in_month = 30
            elif input_month == 2:
                if (input_year % 4 == 0 and input_year % 100 != 0) or (input_year % 400 == 0):
                    days_in_month = 29  # Leap year
                else:
                    days_in_month = 28  # Non-leap year
            else:
                days_in_month = 31  # January, March, May, July, August, October, December

            # Initialize zero lists
            model_gpt4turbo = [0] * days_in_month
            model_gpt35 = [0] * days_in_month
            model_preview = [0] * days_in_month
            model_gpt4 = [0] * days_in_month

            context = {'model_gpt4turbo':  [None if x == 0 else x for x in model_gpt4turbo], 'model_gpt35':  [None if x == 0 else x for x in model_gpt35], 
                       'model_preview':  [None if x == 0 else x for x in model_preview],'model_gpt4':  [None if x == 0 else x for x in model_gpt4],
                       'total_token': 0}
            print('error', e)
            return JsonResponse({"error": str(e)}, status=500)

@csrf_exempt 
def remove_user(request):
    if request.method == "POST":
        username = request.POST.get("username")
        userId = request.POST.get("userId")
        indexname = request.POST.get("index")
        userdetailind = request.POST.get("userdetailind")
        companyCode = request.POST.get("companyCode")
        mailid = request.POST.get("mail")
        used_token = request.POST.get("used_tok")
        assign_token = request.POST.get("assign_tok")

        
        document = {
                'companyCode':companyCode,
                'username': username,
                'user_id': userId,
                'mail': mailid,
                'overall_tokens': used_token,
                'assigned_tokens': assign_token,
                'removedDate':datetime.now()
            }
        
            # Index the data in the 'removed_user' index
        response = es.index(index=remove_index, body=document)
        print('userdetailind',userdetailind)
        print('indexname',indexname)
        print('companyCode',companyCode)

        # Elasticsearch delete_by_query API call to remove the user by matching both username and organization_name
        response = es.delete_by_query(
            index=indexname,
            body={
                "query": {
                    "bool": {
                        "must": [
                            {"term": {"user_id.keyword": userId}},
                            {"term": {"username.keyword": username}},
                            {"term": {"companyCode.keyword": companyCode}},

                        ]
                    }
                }
            },
        )

        # Return success response after deletion
        delete_result = response["deleted"] if "deleted" in response else 0
        
        response1 = es.delete_by_query(
            index=userdetailind,
            body={
                "query": {
                    "bool": {
                        "must": [
                            {"term": {"user_id.keyword": userId}},
                            {"term": {"username.keyword": username}},
                            {"term": {"companyCode.keyword": companyCode}},

                        ]
                    }
                }
            },
        )
        delete_result1 = response1["deleted"] if "deleted" in response1 else 0

        # Return success response after deletion
        return JsonResponse(
            {"status": "User removed", "deleted_count": delete_result}, status=200
        )
