from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import authenticate, login as auth_login, logout
from .models import CustomUser, JobPosting,Message,FileDownload,MessageStatus
from skyonnadmin.models import ClientDetails,SubcompanyDetails,Locations,AddContact,InternalTeam
from django.contrib import messages
from django.http import JsonResponse
from django.db.models import Q

from django.contrib.auth.models import User
from django.http import HttpResponseRedirect
import os
from django.core.files.storage import FileSystemStorage
import json
from django.core.serializers.json import DjangoJSONEncoder
import uuid
from django.utils.timezone import now,localtime
import pytz

ist_timezone = pytz.timezone('Asia/Kolkata')

def home(request):
    return render(request, 'user/home.html')


def create_user(request):
    if request.method == 'POST':
        # Handle signup form submission
        first_name = request.POST.get('first_name')
        last_name = request.POST.get('last_name')
        phone = request.POST.get('phone')
        phone2 = request.POST.get('phone_2')
        company_email = request.POST.get('company_email')
        personal_email = request.POST.get('personal_email')
        address = request.POST.get('address')
        work_location = request.POST.get('work_location')
        role = request.POST.get('role')
        password = request.POST.get('password')
        picture = request.FILES.get('picture')

        # Create user_id based on role
        role_prefix = role[0].upper()
        user_count = CustomUser.objects.filter(role=role).count() + 1
        user_id = f"{role_prefix}{first_name[:3].upper()}{user_count:03}"

        # Create the CustomUser object
        user = CustomUser.objects.create(
            first_name=first_name,
            last_name=last_name,
            phone=phone,
            phone2=phone2,
            company_email=company_email,
            personal_email=personal_email,
            address=address,
            work_location=work_location,
            role=role,
            user_id=user_id
        )
        user.set_password(password)
        user.picture = picture
        user.save()
        user.backend = 'user.backend.PhoneAuthenticationBackend'
        auth_login(request, user)

        return redirect('dashboard', user_id=user.user_id)
    else:
        return render(request, 'user/home.html')


# def user_login(request):
#     if request.method == 'POST':
#         phone = request.POST.get('phone')
#         password = request.POST.get('password')
#
#         user = authenticate(request, phone=phone, password=password)
#         # print(phone, password, user)
#         if user is not None:
#             auth_login(request, user)
#             user = CustomUser.objects.filter(phone=phone).first()
#             if user:
#                 # print(user.user_id)
#                 return redirect('dashboard', user_id=user.user_id)
#             else:
#                 messages.error(request, 'No user found for the provided phone number.')
#         else:
#             messages.error(request, 'Invalid phone number or password.')
#
#     return render(request, 'user/home.html')


def user_login(request):
    if request.method == 'POST':
        phone = request.POST.get('phone')
        password = request.POST.get('password')

        if not phone and 'phone' in request.POST:
            return JsonResponse({'error': 'Please fill the phone number field.'}, status=400)
        if not password and 'password' in request.POST:  # Validate password if it's present
            return JsonResponse({'error': 'Please fill the password field.'}, status=400)

        user = InternalTeam.objects.filter(Login=phone).first()
        if user is None:
            return JsonResponse({'error': 'Incorrect Email.'}, status=404)

        if password:
            match = InternalTeam.objects.filter(Login=phone,Password=password).first()
            if not match:
                return JsonResponse({'error': 'Incorrect password.'}, status=401)

            return JsonResponse(
                {'success': 'Login successful', 'redirect_url': f'/user/dashboard/{user.user_id}'})

        return JsonResponse({'success': 'Phone number is valid.'}, status=200)

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


def dashboard(request, user_id):
    # Retrieve the manager object using manager_id
    user = get_object_or_404(InternalTeam, user_id=user_id)
    print('user_id:',user_id)

    # Get the manager's first name
    first_name = user.FirstName.capitalize()
    last_name = user.LastName.capitalize()
    full_name = f"{first_name}'s"

    return render(request, 'user/dashboard.html', {'first_name': full_name, 'user_id': user_id})

# def dashboard(request, user_id):
#         # Retrieve the manager object using manager_id
#         user = get_object_or_404(CustomUser, user_id=user_id)
#         print('user_id:', user_id)
#
#         # Get the manager's first name
#         first_name = user.FirstName.capitalize()
#         full_name = f"{first_name}'s"
#         print(full_name)
#
#         if user.role == 'manager':
#            print("hiii")
#            return render(request, 'user/test.html', {'first_name': full_name, 'user_id': user_id})
#
#         if user.role == 'recruiter':
#            return render(request, 'recruiter/recruiter_dashboard.html', {'first_name': full_name, 'user_id': user_id})


def new_job_posting(request):
    locations = Locations.objects.all()
    clients = ClientDetails.objects.all()
    return render(request, 'user/new_job_posting.html', {'clients': clients,'locations':locations})


def add_recruiter(request):
    user_id = request.GET.get('user_id', None)
    print(user_id)
    context = {'user_id': user_id}
    return render(request, 'user/add_recruiter.html', context)


def logout_view(request):
    logout(request)
    return redirect('home')


# def save_job_posting(request):
#     if request.method == 'POST':
#         client = request.POST.get('Client')
#         spoc = request.POST.get('SPOC')
#         start_date = request.POST.get('StartDate')
#         budget_max = request.POST.get('BudgetMax')
#         budget_min = request.POST.get('BudgetMin')
#         job_description = request.POST.get('JobDescription')
#         special_instructions = request.POST.get('SpecialInstructions')
#         job_id = request.POST.get('JobID')
#         spoc_2 = request.POST.get('SPOC2')
#         close_date = request.POST.get('CloseDate')
#         locations = request.POST.getlist('Location')  # Use getlist to handle multiple selections
#         no_of_posting = request.POST.get('NoOfPosting')
#         job_type = request.POST.get('Type')
#         header = request.POST.get('Header')
#         experience_in_years = request.POST.get('Experience_in_Yrs')
#
#         job_posting = JobPosting(
#             client=client,
#             spoc=spoc,
#             budget_min=budget_min,
#             start_date=start_date,
#             budget_max=budget_max,
#             job_description=job_description,
#             special_instructions=special_instructions,
#             job_id=job_id,
#             spoc_2=spoc_2,
#             close_date=close_date,
#             no_of_posting=no_of_posting,
#             job_type=job_type,
#             header=header,
#             experience_in_years=experience_in_years
#         )
#         job_posting.set_locations(locations)  # Save the locations as a comma-separated string
#         job_posting.save()
#         return JsonResponse({'status': 'success', 'message': 'Job posting saved successfully.'})
#
#     return redirect('error_url')
#

def save_job_posting(request):
    if request.method == 'POST':
        # Extract data from the form
        Client = request.POST.get('Client', '')
        JobID = request.POST.get('JobID', '')
        Location = request.POST.get('Location', '')
        SPOC = request.POST.get('SPOC', '')
        SPOC2 = request.POST.get('SPOC2', '')
        StartDate = request.POST.get('StartDate', '')
        CloseDate = request.POST.get('CloseDate', '')
        BudgetMin = request.POST.get('BudgetMin', '')
        timePeriod = request.POST.get('timePeriod', '')
        minAmount = request.POST.get('minAmount', '')
        maxAmount = request.POST.get('maxAmount', '')
        Header = request.POST.get('Header', '')
        JobDescription = request.POST.get('JobDescription', '')
        Experience_in_Yrs = request.POST.get('Experience', '')
        NoOfPosting = request.POST.get('NoOfPosting', '')
        Qualification = request.POST.get('Qualification', '').upper()
        SpecialInstructions = request.POST.get('SpecialInstructions', '')

        JD = None
        slice_JD = None
        if request.FILES.get('JD'):
            myfile = request.FILES['JD']
            file_extension = os.path.splitext(myfile.name)[1]  # Get the file extension
            filename = f"{JobID}{file_extension}"  # Create the new filename using job_id
            fs = FileSystemStorage()
            filename = fs.save(filename, myfile)
            JD = fs.url(filename)  # Get the URL to the file
            slice_JD = JD[7:]

        jobposting = JobPosting(
            Client=Client,
            JobID=JobID,
            Location=Location,
            SPOC=SPOC,
            SPOC2=SPOC2,
            StartDate=StartDate,
            CloseDate=CloseDate,
            BudgetMin=BudgetMin,
            timePeriod=timePeriod,
            minAmount=minAmount,
            maxAmount=maxAmount,
            Qualification=Qualification,
            Header=Header,
            JobDescription=JobDescription,
            Experience_in_Yrs=Experience_in_Yrs,
            NoOfPosting=NoOfPosting,
            SpecialInstructions=SpecialInstructions,
            JD=JD,
            slice_JD=slice_JD
        )
        jobposting.save()
        print(jobposting)

        admin_id = request.GET.get('admin_id', None)
        print(admin_id)

        return JsonResponse({'status': 'success', 'message': 'Job_posting saved successfully.'})

    else:
        return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=400)



def create_recruiter(request):
    if request.method == 'POST':
        # Handle signup form submission
        # print(request.post)
        first_name = request.POST.get('first_name')
        last_name = request.POST.get('last_name')
        phone = request.POST.get('phone')
        phone2 = request.POST.get('phone_2')
        company_email = request.POST.get('company_email')
        personal_email = request.POST.get('personal_email')
        address = request.POST.get('address')
        work_location = request.POST.get('work_location')
        role = "recruiter"  # request.POST.get('role')
        password = request.POST.get('password')
        picture = request.FILES.get('picture')
        manager_assigned = request.POST.get('manager_assigned', None)
        print(manager_assigned, 1)
        # Create user_id based on role
        role_prefix = role[0].upper()
        user_count = CustomUser.objects.filter(role=role).count() + 1
        user_id = f"{role_prefix}{first_name[:3].upper()}{user_count:03}"

        # Create the CustomUser object
        user = CustomUser.objects.create(
            first_name=first_name,
            last_name=last_name,
            phone=phone,
            phone2=phone2,
            company_email=company_email,
            personal_email=personal_email,
            address=address,
            work_location=work_location,
            role=role,
            user_id=user_id,
            manager_assigned=manager_assigned
        )
        user.set_password(password)
        user.picture = picture
        user.save()
        return redirect('dashboard', user_id=manager_assigned)
        # return JsonResponse({'success': True, 'message': 'Recruiter added successfully!'})

    else:
        messages.success(request, 'Data saved successfully.')

        # Instead of redirecting, render the same form page again
        return render(request, 'user/add_recruiter.html')


# def send_message(request, recipient_id):
#     recipient = get_object_or_404(User, pk=recipient_id)
#
#     if request.method == 'POST':
#         # Retrieve form data
#         subject = request.POST.get('subject')
#         body = request.POST.get('body')
#         # attachment = request.FILES.get('attachment')  # Retrieve file if uploaded
#
#         attachment = None
#         if request.FILES.get('attachment'):
#             myfile = request.FILES['attachment']
#             file_name = os.path.splitext(myfile.name)[0]  # Get the file extension
#             filename = file_name  # Create the new filename using job_id
#             fs = FileSystemStorage()
#             filename = fs.save(filename, myfile)
#             attachment = fs.url(filename)  # Get the URL to the file
#             print(attachment)
#
#
#         # Create a new message object
#         message = Message.objects.create(
#             sender=request.user,  # Current logged-in user
#             recipient=recipient,  # Recipient
#             subject=subject,      # Subject
#             body=body,            # Body of the message
#             attachment=attachment
#         )
#
#         return JsonResponse({
#             'status': 'success',
#             'message': 'Message sent successfully.',
#             'message_id': message.id,   # Optional: send back message ID or any other info
#             'attachment_url': attachment,  # Send file URL if uploaded
#         })
#
#     # If GET request, show the message composition page
#     return render(request, 'send_message.html', {'recipient': recipient})

def mark_as_read(request, message_id):
    message = get_object_or_404(Message, pk=message_id, recipient=request.user)
    message.is_read = True
    message.save()
    return redirect('messages')


def get_locations(request):
    if request.method == 'GET':
        client = request.GET.get('Client')
        jobposting_locations = JobPosting.objects.filter(Client=client).values_list('Location').distinct()
        client_locations = ClientDetails.objects.filter(parent_company=client).values_list('location_Id').distinct()
        subclient_locations = SubcompanyDetails.objects.filter(parent_company=client).values_list('location_id').distinct()

        locations = set(jobposting_locations) | set(client_locations) | set(subclient_locations)

        location_list = list(locations)
        return JsonResponse(location_list, safe=False)
    else:
        return JsonResponse({'error': 'Invalid request method'}, status=400)


def get_client_details(request):
    if request.method == 'GET':
        client = request.GET.get('client')
        try:
            # Retrieve a single ClientDetails object
            client_obj = ClientDetails.objects.get(parent_company=client)
            client_data = {
                'parent_company': client_obj.parent_company,
                'GST_No': client_obj.GST_No,
                'Location_Id': client_obj.location_Id,
                'Address_1': client_obj.address_1,
                'Address_2': client_obj.address_2,
                'City': client_obj.City,
                'State': client_obj.state,
                'Pincode': client_obj.Pincode,
                'Country': client_obj.country
            }
            return JsonResponse(client_data)
        except ClientDetails.DoesNotExist:
            return JsonResponse({'error': 'Client not found'}, status=404)
    else:
        return JsonResponse({'error': 'Invalid request method'}, status=400)

def new_login(request):
    if request.method == 'POST':
        Login_id = request.POST.get('phone')
        password = request.POST.get('password')

        print(Login_id, password)

        user = InternalTeam.objects.filter(Login=Login_id,Password=password).first()
        print(user)
        if user is not None:

            print(user.user_id)
            return redirect('dashboard', user_id=user.user_id)

        else:
            messages.error(request, 'Invalid phone number or password.')

    return render(request, 'user/home.html')

def new_job_posting(request):
    clients = ClientDetails.objects.all()
    user_id = request.GET.get('user_id', None)
    print('opened newJobPosting:',user_id)
    user = get_object_or_404(InternalTeam,user_id=user_id)
    print(user.Level)

    restricted =bool(int((user.Level)[6:]) < 5)

    if restricted==True:
        return render(request, 'user/new_job_posting.html', {'user': user, 'clients': clients, 'user_id': user_id, 'restricted': True})
    else:
        return render(request, 'user/new_job_posting.html', {'user': user,'clients': clients,'user_id': user_id, 'restricted': False})


def get_contacts(request):
    if request.method == 'GET':
        client = request.GET.get('Client')
        print(client)
        SPOC_Details = AddContact.objects.filter(Company=client).values('FirstName','LastName')

        SPOC_Details_list = list(SPOC_Details)
        return JsonResponse(SPOC_Details_list, safe=False)
    else:
        return JsonResponse({'error': 'Invalid request'})

def validate_field(request):
    if request.method == 'GET':
        email = request.GET.get('Email')
        phone_number = request.GET.get('Phone_number')
        response = {
            'exists': False
        }
        if email and AddContact.objects.filter(Email=email).exists():
            response['exists'] = True
        elif phone_number and AddContact.objects.filter(Phone_number=phone_number).exists():
            response['exists'] = True
        return JsonResponse(response)


def all_job_postings(request):
    user_id = request.GET.get('user_id', None)
    print('opened allJobPosting:', user_id)
    clients = ClientDetails.objects.all()
    user = get_object_or_404(InternalTeam, user_id=user_id)
    print(user.Level)

    restricted = bool(int((user.Level)[6:]) < 5)

    if restricted == True:
        job_postings = JobPosting.objects.all()
        return render(request, 'user/all_job_postings.html',
                      {'user': user, 'clients': clients, 'user_id': user_id, 'restricted': True,'job_postings': job_postings})
    else:
        query = request.GET.get('query', '')  # Get the query parameter if it exists

        if query:
            job_postings = (JobPosting.objects.filter(job_id__icontains=query) |
                            JobPosting.objects.filter(spoc__icontains=query) |
                            JobPosting.objects.filter(client__icontains=query ))
        else:
            job_postings = JobPosting.objects.all()

        return render(request, 'user/all_job_postings.html',
            {'user': user, 'clients': clients, 'user_id': user_id, 'restricted': False,'job_postings': job_postings})


def get_jobPosting(request):
    if request.method == 'GET':
        jobId = request.GET.get('JobId')
        try:
            # Retrieve a single ClientDetails object
            job_obj = JobPosting.objects.get(JobID=jobId)
            job_data = {
                'Client': job_obj.Client,
                'JobID': job_obj.JobID,
                'Location': job_obj.Location,
                'SPOC': job_obj.SPOC,
                'SPOC2': job_obj.SPOC2,
                'NoOfPosting': job_obj.NoOfPosting,
                'StartDate': job_obj.StartDate,
                'CloseDate': job_obj.CloseDate,
                'Experience_in_Yrs': job_obj.Experience_in_Yrs,
                'BudgetMin': job_obj.BudgetMin,
                'Qualification': job_obj.Qualification,
                'Header': job_obj.Header,
                'JobDescription': job_obj.JobDescription,
                'SpecialInstructions': job_obj.SpecialInstructions
            }
            return JsonResponse(job_data)
        except JobPosting.DoesNotExist:
            return JsonResponse({'error': 'Job Posting not found'}, status=404)
    else:
        return JsonResponse({'error': 'Invalid request method'}, status=400)



def messages(request):
    user_id = request.GET.get('user_id','')
    current_user_id = InternalTeam.objects.filter(user_id=user_id).values_list('Email1', flat=True).first()
    teams = InternalTeam.objects.exclude(Email1=current_user_id)
    return render(request,'user/messages.html',{'user_id': user_id,'current_user_id': current_user_id, 'teams':teams})

def generate_unique_message_id(firstname):
    """Generates a unique message_id by checking its existence in the database."""
    prefix = firstname[:3].upper()
    while True:
        unique_id = str(uuid.uuid4().int)[:4]  # Generate a random 4-digit number
        message_id = prefix + unique_id
        if not Message.objects.filter(message_id=message_id).exists():
            print(message_id,'created message_id')
            return message_id

def send_message(request):
    if request.method == 'POST':
        try:
            current_user = request.GET.get('user_id', None)
            current_user_id = InternalTeam.objects.filter(user_id=current_user).values_list('Email1', flat=True).first()

            recipients = request.POST.get('toField').split(',')  # Multiple emails separated by commas
            print(recipients)
            subject = request.POST.get('subject')
            body = request.POST.get('message')
            attachment = request.FILES.get('attachment')  # Using .get() to avoid KeyError

            attachment_url = None
            if attachment:
                myfile = request.FILES['attachment']
                file_name, file_extension = os.path.splitext(myfile.name)
                fs = FileSystemStorage()

                # Save the file with a unique filename
                filename = fs.save(file_name, attachment)
                attachment_url = fs.url(filename)

            sender = current_user_id
            sender_id = get_object_or_404(InternalTeam, Email1=sender)

            sender_fullname = sender_id.FullName
            firstname = InternalTeam.objects.filter(user_id=current_user).values_list('FirstName', flat=True).first()

            message_id = generate_unique_message_id(firstname)

            recipient_fullnames = []
            recipient_emails = []
            for recipient_email in recipients:  # Split by comma
                recipient_id = get_object_or_404(InternalTeam, Email1=recipient_email)
                print(recipient_id)

                recipient_emails.append(recipient_id)
                recipient_fullnames.append(recipient_id.FullName)

            recipient_details = [{'email': r.Email1, 'fullname': r.FullName} for r in recipient_emails]

            message = Message(
                    sender=sender_id,
                    subject=subject,
                    body=body,
                    is_read=False,
                    sender_fullname=sender_fullname,
                    recipient_fullname=", ".join(recipient_fullnames),
                    message_id=message_id,
                    attachment=attachment
            )
            message.save()
            message.recipient.set(recipient_emails)

            return JsonResponse({
                'status': 'success',
                'message': 'Message sent successfully.',
                'details': {
                    'subject': subject,
                    'recipients': recipient_details,
                    'sender_fullname': sender_fullname,
                    'recipient_fullname': ",".join(recipient_fullnames),
                    'body': body,
                    'sent_at': message.sent_at.strftime('%Y-%m-%d %H:%M:%S'),
                    'message_id': message.message_id,
                    'attachment': attachment_url
                }
            })
        except Exception as e:
            print("Error occurred:", str(e))  # Print error to console for debugging
            return JsonResponse({'status': 'error', 'message': 'Failed to send message'}, status=500)

    else:
        return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=400)

def unread_message_count(request):
    user_id = request.GET.get('user_id')
    print(user_id)
    user = get_object_or_404(InternalTeam, user_id=user_id)
    unread_count = Message.objects.filter(recipient=user, is_read=False).count()
    return JsonResponse({'unread_count': unread_count})

def render_messages(request):
    current_user = request.GET.get('user_id', None)
    current_user_id = get_object_or_404(InternalTeam, user_id=current_user)

    # Fetch all messages for the user
    inbox_messages = Message.objects.filter(
        Q(recipient=current_user_id),
        is_trashed=False
    ).order_by('-sent_at')

    # Dictionary to group messages by the main message
    grouped_messages = {}

    for message in inbox_messages:
        # Find the main message for grouping
        main_message = message
        while main_message.reply_to:
            main_message = main_message.reply_to

        # Check if the main message already has a group
        if main_message.id not in grouped_messages:
            grouped_messages[main_message.id] = {
                'main_message': main_message,
                'replies': [],
            }

        # Add the current message to the main message's replies
        if message != main_message:
            grouped_messages[main_message.id]['replies'].append(message)

    # Prepare the response
    messages_data = []
    for group in grouped_messages.values():
        main_message = group['main_message']

        # Sort replies by sent_at
        sorted_replies = sorted(group['replies'], key=lambda x: x.sent_at)

        # Function to get attachment details
        def get_attachment_data(attachment):
            if not attachment:
                return []
            try:
                fs = FileSystemStorage()
                attachment_url = fs.url(attachment.name)
                file_path = fs.path(attachment.name)
                file_size = os.path.getsize(file_path)
                return [{
                    'filename': attachment.name.split('/')[-1],
                    'url': attachment_url,
                    'size': file_size
                }]
            except Exception as e:
                print(f"Error retrieving attachment: {e}")
                return []

        def get_first_downloaded(message_id):
            file_download = FileDownload.objects.filter(message_id=message_id).first()
            if file_download:
                return localtime(file_download.first_downloaded).strftime('%m/%d/%Y, %I:%M:%S %p')
            return None

        def get_last_downloaded(message_id):
            file_download = FileDownload.objects.filter(message_id=message_id).first()
            if file_download:
                return localtime(file_download.last_downloaded).strftime('%m/%d/%Y, %I:%M:%S %p')
            return None

        def get_message_status(message, user):
            status = MessageStatus.objects.filter(message=message, user=user).first()
            if status:
                return status.is_read, localtime(status.seen_time).strftime('%m/%d/%Y, %I:%M:%S %p') if status.seen_time else "00:00:00"
            return False, "00:00:00"

        replies_data = [{
            'sender_fullname': reply.sender.FullName,
            'body': reply.body,
            'sent_at': localtime(reply.sent_at).strftime('%m/%d/%Y, %I:%M:%S %p'),
            'message_id': reply.message_id,
            'parent_message_id': reply.reply_to.message_id if reply.reply_to else None,
            'main_message_id': main_message.message_id,  # Ensures main message ID is always available
            'is_read': get_message_status(reply, current_user_id)[0],
            'seen_time': get_message_status(reply, current_user_id)[1],
            'attachment': get_attachment_data(reply.attachment),
            'first_downloaded': get_first_downloaded(reply.message_id),
            'last_downloaded': get_last_downloaded(reply.message_id),
        } for reply in sorted_replies]

        latest_message = sorted_replies[-1] if sorted_replies else main_message

        messages_data.append({
            'sender_fullname': main_message.sender.FullName,
            'sender_id': main_message.sender_id,
            'recipient_fullnames': [recipient.FullName for recipient in main_message.recipient.all()],
            'recipient_emails': [recipient.Email1 for recipient in main_message.recipient.all()],
            'subject': main_message.subject,
            'body': main_message.body,
            'sent_at': localtime(main_message.sent_at).strftime('%m/%d/%Y, %I:%M:%S %p'),
            'message_id': main_message.message_id,
            'parent_message_id': main_message.reply_to.message_id if main_message.reply_to else None,
            'main_message_id': main_message.message_id,  # Ensures the root message ID is stored
            'is_read': get_message_status(main_message, current_user_id)[0],
            'seen_time': get_message_status(main_message, current_user_id)[1],
            'attachment': get_attachment_data(main_message.attachment),
            'replies': replies_data,
            'latest_message': {
                'sender_fullname': latest_message.sender.FullName,
                'subject': latest_message.subject,
                'body': latest_message.body,
                'sent_at': localtime(latest_message.sent_at).strftime('%m/%d/%Y, %I:%M:%S %p'),
                'message_id': latest_message.message_id,
                'is_read': get_message_status(latest_message, current_user_id)[0],
                'seen_time': get_message_status(latest_message, current_user_id)[1],
                'attachment': get_attachment_data(latest_message.attachment),
                'first_downloaded': get_first_downloaded(latest_message.message_id),
                'last_downloaded': get_last_downloaded(latest_message.message_id),
            }
        })

    return JsonResponse({'inbox_messages': messages_data})
def render_sent_messages(request):
    current_user = request.GET.get('user_id', None)
    current_user_id = get_object_or_404(InternalTeam, user_id=current_user)

    # Fetch all messages for the user
    sent_messages = Message.objects.filter(
        Q(sender=current_user_id),
        is_trashed=False
    ).order_by('-sent_at')

    # Dictionary to group messages by the main message
    grouped_messages = {}

    for message in sent_messages:
        # Find the main message for grouping
        main_message = message
        while main_message.reply_to:
            main_message = main_message.reply_to

        # Check if the main message already has a group
        if main_message.id not in grouped_messages:
            grouped_messages[main_message.id] = {
                'main_message': main_message,
                'replies': [],
            }

        # Add the current message to the main message's replies
        if message != main_message:
            grouped_messages[main_message.id]['replies'].append(message)

    # Prepare the response
    messages_data = []
    for group in grouped_messages.values():
        main_message = group['main_message']

        # Sort replies by sent_at
        sorted_replies = sorted(group['replies'], key=lambda x: x.sent_at)

        # Integrate get_attachment_data
        def get_attachment_data(attachment):
            if not attachment:
                return []
            try:
                fs = FileSystemStorage()
                attachment_url = fs.url(attachment.name)
                file_path = fs.path(attachment.name)
                file_size = os.path.getsize(file_path)
                return [{
                    'filename': attachment.name.split('/')[-1],
                    'url': attachment_url,
                    'size': file_size
                }]
            except Exception as e:
                print(f"Error retrieving attachment: {e}")
                return []

        def get_first_downloaded(message_id):
            file_download = FileDownload.objects.filter(message_id=message_id).first()
            if file_download:
                return localtime(file_download.first_downloaded).strftime('%m/%d/%Y, %I:%M:%S %p')
            return None

        def get_last_downloaded(message_id):
            file_download = FileDownload.objects.filter(message_id=message_id).first()
            if file_download:
                return localtime(file_download.last_downloaded).strftime('%m/%d/%Y, %I:%M:%S %p')
            return None

        replies_data = [{
            'sender_fullname': reply.sender.FullName,
            'body': reply.body,
            'sent_at': localtime(reply.sent_at).strftime('%m/%d/%Y, %I:%M:%S %p'),
            'message_id': reply.message_id,
            'is_read': reply.is_read,
            'attachment': get_attachment_data(reply.attachment),
            'first_downloaded': get_first_downloaded(reply.message_id),
            'last_downloaded': get_last_downloaded(reply.message_id),
        } for reply in sorted_replies]

        latest_message = sorted_replies[-1] if sorted_replies else main_message

        messages_data.append({
            'sender_fullname': main_message.sender.FullName,
            'sender_id': main_message.sender_id,
            'recipient_fullnames': [recipient.FullName for recipient in main_message.recipient.all()],
            'recipient_emails': [recipient.Email1 for recipient in main_message.recipient.all()],
            'subject': main_message.subject,
            'body': main_message.body,
            'sent_at': localtime(main_message.sent_at).strftime('%m/%d/%Y, %I:%M:%S %p'),
            'message_id': main_message.message_id,
            'is_read': main_message.is_read,
            'attachment': get_attachment_data(main_message.attachment),
            'replies': replies_data,
            'latest_message': {
                'sender_fullname': latest_message.sender.FullName,
                'recipient_fullnames': [recipient.FullName for recipient in latest_message.recipient.all()],
                'subject': latest_message.subject,
                'body': latest_message.body,
                'sent_at': localtime(latest_message.sent_at).strftime('%m/%d/%Y, %I:%M:%S %p'),
                'message_id': latest_message.message_id,
                'is_read': latest_message.is_read,
                'attachment': get_attachment_data(latest_message.attachment),
                'first_downloaded': get_first_downloaded(latest_message.message_id),
                'last_downloaded': get_last_downloaded(latest_message.message_id),
            }
        })

    return JsonResponse({'sent_messages': messages_data})

def update_message_read_status(request, message_id):
    current_user_id = request.GET.get('user_id', None)
    current_user = get_object_or_404(InternalTeam, user_id=current_user_id)

    if request.method == 'POST':
        message = get_object_or_404(Message, message_id=message_id)

        # Ensure the current user is a recipient of the message
        if current_user not in message.recipient.all():
            return JsonResponse({'success': False, 'error': 'User is not a recipient of this message.'}, status=400)

        # Fetch or create the read status for the current user
        status, created = MessageStatus.objects.get_or_create(
            message=message,
            user=current_user,
            defaults={
                'is_read': False,  # Initially set is_read as False
                'seen_time': None  # Initially set seen_time as None
            }
        )
        # If the message is being read for the first time, update the read status
        if not status.is_read:
            status.is_read = True
            status.seen_time = now()
            status.save()

        return JsonResponse({
            'success': True,
            'message': f'Message {message_id} updated successfully',
            'is_read': status.is_read,
            'seen_time': localtime(status.seen_time).strftime('%m/%d/%Y, %I:%M:%S %p') if status.seen_time else "00:00:00"
        })

    return JsonResponse({'success': False, 'error': 'Invalid request method'}, status=400)


def get_message_status(request, message_id):
    message = get_object_or_404(Message, message_id=message_id)
    current_user = request.GET.get('user_id')
    current_user_id = get_object_or_404(InternalTeam,user_id=current_user)

    recipient_status = []
    for recipient in message.recipient.all():
        seen_entry = MessageStatus.objects.filter(message=message, user=recipient).first()
        seen_time = localtime(seen_entry.seen_time).strftime('%m/%d/%Y, %I:%M %p') if seen_entry else "not seen"

        recipient_status.append({
            'email': recipient.Email1,
            'seen_time': seen_time
        })
        print(recipient_status)

    return JsonResponse({'status': recipient_status})
def render_trash_messages(request):
    current_user = request.GET.get('user_id', None)
    current_user_id = get_object_or_404(InternalTeam, user_id=current_user)

    # Filter trash messages for the current user
    trash_messages = Message.objects.filter(Q(sender=current_user_id),is_trashed=True).order_by('-sent_at')
    print(trash_messages,'trash_messages')

    # Prepare message data for response
    messages_data = [
        {
            'sender_fullname': message.sender.FullName,  # Adjust to your model field
            'sender_id': message.sender_id,
            'recipient_fullname': message.recipient.FullName,  # Adjust to your model field
            'recipient_id': message.recipient_id,
            'subject': message.subject,
            'body': message.body,
            'sent_at': localtime(message.sent_at).strftime('%m/%d/%Y, %I:%M:%S %p'),  # Adjust as needed
            'message_id': message.message_id,
            'message_type': 'inbox' if message.recipient == current_user_id else 'sent',
            'is_trashed': message.is_trashed
        }
        for message in trash_messages
    ]
    return JsonResponse({'trash_messages': messages_data})

def send_reply(request):
    if request.method == 'POST':
        current_user = request.GET.get('user_id')
        parent_message_id = request.POST.get('message_id')  # The ID of the message being replied to

        recipients = request.POST.get('toField', '').split(',')
        subject = request.POST.get('subject', '')
        body = request.POST.get('message', '')
        attachment = request.FILES.get('attachment')

        # Get sender info
        sender = InternalTeam.objects.filter(user_id=current_user).values_list('Email1', flat=True).first()
        sender_id = get_object_or_404(InternalTeam, Email1=sender)
        sender_fullname = sender_id.FullName

        # Fetch the parent message and get the sender of the parent message
        parent_message = get_object_or_404(Message, message_id=parent_message_id)
        parent_recipients = parent_message.recipient.exclude(user_id=current_user)

        attachment_url = None
        if attachment:
            myfile = request.FILES['attachment']
            file_name, file_extension = os.path.splitext(myfile.name)
            fs = FileSystemStorage()

            # Save the file with a unique filename
            filename = fs.save(file_name, attachment)
            attachment_url = fs.url(filename)

        # Generate a random UUID and use its first 4 digits
        firstname = InternalTeam.objects.filter(user_id=current_user).values_list('FirstName', flat=True).first()

        message_id = generate_unique_message_id(firstname)

        recipient_fullnames = []
        recipient_emails = []
        for recipient_email in recipients:  # Split by comma
            recipient_id = get_object_or_404(InternalTeam, Email1=recipient_email)

            recipient_emails.append(recipient_id)
            recipient_fullnames.append(recipient_id.FullName)

        recipient_details = [{'email': r.Email1, 'fullname': r.FullName} for r in recipient_emails]

        # Create the reply message to the sender of the parent message
        reply = Message(
            sender=sender_id,
            # recipient=None,  # Initially set to None, since we're not assigning directly
            subject=subject,
            body=body,
            is_read=False,
            sender_fullname=sender_fullname,
            recipient_fullname=", ".join(recipient_fullnames),
            message_id=message_id,
            reply_to_id=parent_message,
            attachment=attachment
        )
        reply.save()
        print(reply)

        # # Use .set() to assign the recipient to the reply
        # all_recipients = list(parent_recipients) + [parent_message.sender]
        # print(all_recipients,'all_recipients')
        reply.recipient.set(recipient_emails)

        # Return a success response with the reply message ID
        return JsonResponse({'status': 'success','reply_message_id': reply.message_id})

    else:
        return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=400)


def fetch_replies(request, message_id):
    if request.method == 'GET':
        try:
            original_message = Message.objects.get(message_id=message_id)

            replies = Message.objects.filter(reply_to=original_message).prefetch_related('recipient').order_by('sent_at')

            def get_attachment_data(reply):
                if not reply.attachment:
                    return None
                try:
                    fs = FileSystemStorage()
                    attachment_url = fs.url(reply.attachment.name)
                    file_path = fs.path(reply.attachment.name)
                    file_size = os.path.getsize(file_path)
                    return {
                        'filename': reply.attachment.name.split('/')[-1],
                        'url': attachment_url,
                        'size': file_size
                    }
                except Exception as e:
                    print(f"Error retrieving attachment for message {reply.message_id}: {e}")
                    return None

            def get_first_downloaded(message_id):
                file_download = FileDownload.objects.filter(message_id=message_id).first()
                if file_download:
                    return localtime(file_download.first_downloaded).strftime('%m/%d/%Y, %I:%M:%S %p')
                return None

            def get_last_downloaded(message_id):
                file_download = FileDownload.objects.filter(message_id=message_id).first()
                if file_download:
                    return localtime(file_download.last_downloaded).strftime('%m/%d/%Y, %I:%M:%S %p')
                return None

            def serialize_reply(reply):
                return {
                    'message_id': reply.message_id,
                    'subject': reply.subject,
                    'sender_id': reply.sender_id,
                    'sender_fullname': reply.sender_fullname,
                    'recipient_id': [recipient.Email1 for recipient in reply.recipient.all()],
                    'recipient_fullname': reply.recipient_fullname,
                    'body': reply.body,
                    'sent_at': reply.sent_at.isoformat(),
                    'parent_message_id': reply.reply_to_id,
                    'attachment': get_attachment_data(reply),
                    'first_downloaded': get_first_downloaded(reply.message_id),
                    'last_downloaded': get_last_downloaded(reply.message_id),
                    'replies': [serialize_reply(r) for r in Message.objects.filter(reply_to=reply).order_by('sent_at')]
                }

            replies_data = [serialize_reply(reply) for reply in replies]

            return JsonResponse({'status': 'success', 'replies': replies_data})
        except Message.DoesNotExist:
            return JsonResponse({'status': 'error', 'message': 'Original message not found'}, status=404)
    else:
        return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=400)

def track_download(request, message_id):
    if request.method == 'GET':
        current_user = request.GET.get('user_id', None)
        current_user_id = get_object_or_404(InternalTeam, user_id=current_user)
        ist_timezone = pytz.timezone('Asia/Kolkata')
        message = get_object_or_404(Message, message_id=message_id)

        # Prevent the sender from downloading their own message
        if current_user_id == message.sender:
            return JsonResponse({'status': 'error', 'message': 'Sender cannot download the message attachment.'}, status=400)

        # Ensure the current user is a recipient of the message
        if current_user_id not in message.recipient.all():
            return JsonResponse({'status': 'error', 'message': 'User is not a recipient of this message.'}, status=400)

        recipient = current_user_id

        # Track downloads for the original message and its replies
        download_records = []
        for msg in [message] + list(Message.objects.filter(reply_to=message)):
            download, created = FileDownload.objects.get_or_create(
                message=msg,
                user=recipient,
                defaults={
                    'first_downloaded': localtime(now(), ist_timezone),
                    'last_downloaded': localtime(now(), ist_timezone)
                }
            )

            # Update the last_downloaded timestamp
            if not created:
                download.last_downloaded = now()
                download.save()

            download_records.append({
                'message_id': msg.message_id,
                'first_downloaded': localtime(download.first_downloaded, ist_timezone).strftime('%m/%d/%Y, %I:%M:%S %p'),
                'last_downloaded': localtime(download.last_downloaded, ist_timezone).strftime('%m/%d/%Y, %I:%M:%S %p'),
            })

        return JsonResponse({'status': 'success', 'downloads': download_records})
    else:
        return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=400)


def fetch_download_timestamps(request, message_id):
    if request.method == 'GET':
        current_user = request.GET.get('user_id', None)
        current_user_id = get_object_or_404(InternalTeam, user_id=current_user).Email1
        message = get_object_or_404(Message, message_id=message_id)
        ist_timezone = pytz.timezone('Asia/Kolkata')

        # Separate main message and reply messages
        main_message_downloads = []
        reply_message_downloads = {}

        # Fetch main message download timestamps
        main_message_records = FileDownload.objects.filter(message=message)
        for record in main_message_records:
            recipient_id = record.user.Email1
            main_message_downloads.append({
                'message_id': message_id,
                'sender_id': message.sender_id,
                'recipient_id': recipient_id,
                'first_downloaded': localtime(record.first_downloaded, ist_timezone).strftime('%m/%d/%Y, %I:%M:%S %p') if record.first_downloaded else None,
                'last_downloaded': localtime(record.last_downloaded, ist_timezone).strftime('%m/%d/%Y, %I:%M:%S %p') if record.last_downloaded else None
            })

        # Fetch reply message download timestamps
        reply_messages = Message.objects.filter(reply_to=message)

        for reply in reply_messages:
            download_records = FileDownload.objects.filter(message=reply)
            print(download_records)
            reply_message_downloads[reply.message_id] = []

            for record in download_records:
                recipient_id = record.user.Email1
                reply_message_downloads[reply.message_id].append({
                    'message_id': reply.message_id,
                    'sender_id': reply.sender_id,
                    'recipient_id': recipient_id,
                    'first_downloaded': localtime(record.first_downloaded, ist_timezone).strftime(
                        '%m/%d/%Y, %I:%M:%S %p') if record.first_downloaded else None,
                    'last_downloaded': localtime(record.last_downloaded, ist_timezone).strftime(
                        '%m/%d/%Y, %I:%M:%S %p') if record.last_downloaded else None
                })

        print(reply_message_downloads)

        return JsonResponse({
            'main_message_downloads': main_message_downloads,
            'reply_message_downloads': reply_message_downloads,
            'current_user_id': current_user_id
        })
    else:
        return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=400)


def get_main_message_id(request,message_id):
  if request.method == 'GET':
    current_message = get_object_or_404(Message, message_id=message_id)
    print(current_message, 'current_message')

    # Traverse the chain of parent messages to find the main message
    while current_message.reply_to:
        current_message = get_object_or_404(Message, message_id=current_message.reply_to)

    return JsonResponse({'main_message_id': current_message.message_id})
  else:
      return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=400)


# def unread_message_count(request):
#     if request.method == 'GET':
#         user_id = request.GET.get('user_id')
#         print(user_id)
#
#         user = get_object_or_404(InternalTeam, user_id=user_id)
#
#         # Get all messages that are unread in Message model
#         unread = Message.objects.filter(recipient=user, is_read=False).values_list('message_id', flat=True)
#         messages_in_status = MessageStatus.objects.filter(message_id__in=unread, user=user).values_list('message_id', flat=True)
#
#         unread_not_in_status = set(unread) - set(messages_in_status)
#         print(unread_not_in_status, 'Unread messages')
#         unread_count = len(unread_not_in_status)
#
#         return JsonResponse({
#             'unread_count': unread_count,
#             'unread_messages': list(unread_not_in_status) # Convert set to list for JSON response
#         })
#     return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=400)