from django.shortcuts import render,redirect
from .models import *
from django.contrib import messages
from django.db.models import Q
from django.views import View
from django.contrib.auth import authenticate, login,update_session_auth_hash,logout
import json,base64,os
from django.core.files.base import ContentFile
from django.http import JsonResponse,HttpResponse
from django.contrib.auth.decorators import login_required
from datetime import datetime
from django.conf import settings
from .forms import *
from PIL import Image
from django.core.mail import send_mail,EmailMessage
from django.contrib.auth.models import Group
from django.utils.http import urlsafe_base64_decode,urlsafe_base64_encode
from django.utils.encoding import smart_str,force_bytes
from django.contrib.auth.tokens import PasswordResetTokenGenerator
import pypandoc
import subprocess
import pdfkit
from docx import Document
import docx2pdf
import openai
from PyPDF2 import PdfReader
from decouple import config
from docx import Document
import uuid
import fitz  # PyMuPDF
from pytesseract import pytesseract
from PIL import Image
import io
from django.utils import timezone
from datetime import timedelta
from django.utils.timesince import timesince
from django.core import serializers

@login_required
def home(request):
    data = sign_documents.objects.filter(user=request.user).order_by('-id')
    documents_send_to_me = Recipients_sign_documents.objects.filter(recipient=request.user.email).order_by('-id')
    sign_json_data = []
    for i in data:
        print()
        document_name = None
        if i.main_document and i.main_document.name:
            document_name = i.main_document.name
        
        sign_json_data.append({
            'id': i.id,
            'document': document_name,
            'sign_at': i.created_at.strftime("%Y-%m-%d, %H:%M"),
        })
    json_data = json.dumps(sign_json_data,indent=4, sort_keys=True, default=str)
    sendme_json_data = []
    for i in documents_send_to_me:
        document_name = None
        time = None
        if i.main_document and i.main_document.main_document:
            document_name = i.main_document.main_document.name
        if i.sign_at:
            time = i.sign_at.strftime("%Y-%m-%d %H:%M")
        sendme_json_data.append({
            'id': i.id,
            'document': document_name,
            'send_from': i.user.get_full_name,
            'sent_at': i.created_at.strftime("%Y-%m-%d %H:%M"),
            'is_sign': i.is_sign,
            'sign_at': time,
            'link':i.link,
        })
    json_data = json.dumps(sign_json_data,indent=4, sort_keys=True, default=str)
    sendme_json_data = json.dumps(sendme_json_data,indent=4, sort_keys=True, default=str)
    context = {'title':'Home','data':data,'documents_send_to_me':documents_send_to_me,'json_data':json_data,
               'sendme_json_data':sendme_json_data}
    if request.method == 'POST':
        print('call')
        body = json.loads(request.body)  # Parse the JSON body
        doc_name = body.get('document_name')
        email = body.get('email')
        sent_date = body.get('sent_date')
        sign_date = body.get('sign_date')
        print(doc_name, email, sent_date, sign_date)
        sent_date = timezone.make_aware(datetime.strptime(sent_date, "%Y-%m-%d")) if sent_date else None
        sign_date = timezone.make_aware(datetime.strptime(sign_date, "%Y-%m-%d")) if sign_date else None
        # print(doc_name, email, sent_date, sign_date)
        filter_query = Q()
    
    # Add conditions to the filter query based on provided inputs
        if doc_name:
            filter_query |= Q(main_document__main_document__name__icontains=doc_name)
        if email:
            filter_query |= Q(user__email__icontains=email)
        if sent_date:
            filter_query |= Q(created_at__date=sent_date.date())  # Using .date() for date comparison
        if sign_date:
            filter_query |= Q(sign_at__date=sign_date.date())
    
    # Apply the filter
        documents_send_to_me = documents_send_to_me.filter(filter_query)
        print(documents_send_to_me.count())
        data = []
        for i in documents_send_to_me:
            document_name = None
            time = None
            if i.main_document and i.main_document.main_document:
                document_name = i.main_document.main_document.name
            if i.sign_at:
                time = i.sign_at.strftime("%Y-%m-%d %H:%M")
            data.append({
                "id":i.id,
                "document_name":document_name,
                "sent_from":i.user.get_full_name,
                "sent_at": i.created_at.strftime("%Y-%m-%d %H:%M"),
                "is_sign": i.is_sign,
                "sign_at": time,
                "link":i.link,
            })
        print(data)
        return JsonResponse({"data":data,"results":documents_send_to_me.count()})
    return render(request, 'myapp/home.html', context=context)

def register(request):
    if request.method == 'POST':
        
        email = request.POST.get('email')
        first_name = request.POST.get('first_name')
        
        last_name = request.POST.get('last_name')
        password1 = request.POST.get('password1')
        password2 = request.POST.get('password2')
        query = User_Profile.objects.filter(Q(email=email))
        if query.exists():
            messages.error(request, "Email Already Exists !", extra_tags="alert alert-warning alert-dismissible show")
            return redirect('register')
        if password1 == password2:
            
            user = User_Profile.objects.create_user(email=email,username=email,first_name=first_name,last_name=last_name,password=password1)
            admin_group = Group.objects.get(name='Admin')
            user.groups.add(admin_group)
            return redirect('login')
        else:
            messages.error(request, "Password and Confirm Password not matched", extra_tags="alert alert-warning alert-dismissible show")
            return redirect('register')  # Redirect to your home page or wherever you want
    
    return render(request, 'myapp/register.html')

class Add_user(View):
    def get(self,request):
        form = Add_User_Form()
        context = {'title':'Add User','form':form}
        return render(request, 'myapp/add_user.html', context=context)
    
    def post(self,request):
        form = Add_User_Form(request.POST,request.FILES)
        image = request.FILES.get('image')
        print(image)
        if form.is_valid():
            user = form.save()
            user.organisation = request.user.organisation
            
            user_group = Group.objects.get(name="regular user")
            user.groups.add(user_group)
            if image:
                user.profile_pic = image
            user.save()
            messages.success(request,f'User {user.first_name} {user.last_name} created successfully !!',extra_tags="alert alert-success alert-dismissible shows")
            return redirect('add_user')
        else:
            messages.warning(request,f'Something went wrong please check below',extra_tags="alert alert-warning alert-dismissible shows")
            context = {'title':'Add User','form':form}
            return render(request, 'myapp/add_user.html', context=context)

class LoginView(View):
    def get(self, request):
        
        return render(request, 'myapp/login.html')
    
    def post(self, request):
        email = request.POST.get('email')
        print(email)
        password = request.POST.get('password1')
            # print(password)
        user = authenticate(email=email,password=password)
        print(user)
        next_url = request.GET.get('next')
        if user is not None:
            login(request,user)
            if next_url:
                return redirect(next_url)
            else:
                return redirect('home') 
        else:
            messages.error(request, "Email or password is incorrect", extra_tags="alert alert-warning alert-dismissible show")
            return redirect('login')



class Profileview(View):
    def get(self,request):
        title = "My Profile"
        user = User_Profile.objects.get(id=request.user.id)
        context = {'title':title,'user':user}
        return render(request, 'myapp/profile.html',context=context)

class ProfileUpdateview(View):
    def get(self,request):
        title = "Profile"
        instance = User_Profile.objects.get(id=request.user.id)
        form = Update_Profile_Form(instance=instance)
        context = {'title':title,'form':form}
        return render(request, 'myapp/update_profile.html',context=context)
    
    def post(self,request):
        instance = User_Profile.objects.get(id=request.user.id)
        form = Update_Profile_Form(request.POST,request.FILES, instance=instance)
        image = request.FILES.get('image')
        if form.is_valid():
            form.save()
            if image:
                instance.profile_pic = image
                instance.save()
            messages.success(request,'Profile Updated Successfully !!',extra_tags='alert alert-success')
            return redirect('profile')
        else:
            messages.warning(request,'Something went wrong, Please check below',extra_tags='alert alert-warning')
            title = "Update Profile"
            instance = User_Profile.objects.get(id=request.user.id)
            context = {'title':title,'form':form}
            return render(request, 'myapp/update_profile.html',context=context)
            
@login_required
def changepassword(request):
    if request.method == 'POST':
        form = ChangePasswordForm(request.user, request.POST)
        
        if form.is_valid():
            user = form.save(commit=True)
            update_session_auth_hash(request, user)

            messages.success(request, 'Password changed successfully', extra_tags='alert alert-success')
            return redirect('change_password')
        else:
            messages.error(request, 'New password & confirm new password are not matched !!', extra_tags='alert alert-warning')
            title = "Change Password"
            context = {'form':form, 'title':title}
            return render(request, 'myapp/change_password.html', context=context)
    else:
        form = ChangePasswordForm(request.user)
        title = "Change Password"
        context = {'form':form, 'title':title}
        return render(request, 'myapp/change_password.html', context=context)

@login_required
def user_logout(request):
    logout(request)
    return redirect('login')
                 
        
class Signatureiew(View):
    def get(self,request):
        title = "Signatures"
        signatures = Signature.objects.filter(user=request.user)
        context = {'title':title,'signatures':signatures}
        return render(request, 'myapp/signature.html',context=context)


class AddSignatureiew(View):
    def get(self,request):
        title = "Signature"
        context = {'title':title}
        return render(request, 'myapp/add_signature.html',context=context)  

    def post(self,request):
        print('call')
        data = json.loads(request.body)
        print(data)
        image_data = data['image']
        
        format, imgstr = image_data.split(';base64,')
        ext = format.split('/')[-1]
        file = ContentFile(base64.b64decode(imgstr), name='signature.' + ext)
        obj = Signature(user=request.user,signature=file)
        obj.save()
        return JsonResponse({"success":True})

class UploadSignatureiew(View):
    def get(self,request):
        title = "Signature"
        context = {'title':title}
        return render(request, 'myapp/upload_signature.html',context=context)  

    def post(self,request):
        print('call')
        file = request.FILES.get('file')
        print(file)
        obj = Signature(user=request.user,signature=file)
        obj.save()
        if request.headers.get('X-Is-Ajax') == 'true':
            return JsonResponse({"success":True})
        messages.success(request, 'Signature uploaded successfully !!', extra_tags="alert alert-success")
        return redirect("upload_signature")

@login_required
def UploadStampiew(request):
    if request.method == 'POST' and request.FILES['file']:
        print('call')
        file = request.FILES.get('file')
        print(file)
        obj = Stamp(user=request.user,stamp=file)
        obj.save()
        return JsonResponse({"success":True})
    return JsonResponse({"success":False,"error":"Invalid request"})

@login_required    
def delete_sign(request,id):
    sign = Signature.objects.get(id=id)
    sign.delete()
    messages.success(request, f'Sign Deleted Successfully', extra_tags='alert alert-warning')
    return redirect('signature')

@login_required
def delete_sign_cancel(request):
    return redirect('signature')  

@login_required
def add_document(request):
    title = "Add document"
    if request.method == 'POST':
        file = request.FILES.get('file')
        check = request.POST.get('check')
        
        subject = request.POST.get('subject')
        message = request.POST.get('message')
        print(request.POST)

        names = []
        emails = []
        for key in request.POST:
            
            if key.startswith('email_'):
                emails.append(request.POST[key])
            elif key.startswith('name_'):
                names.append(request.POST[key])
        print(emails)
        print(names)
        recipients = []
        list_of_dicts = [{'email': email, 'name': name} for email, name in zip(emails, names)]
        if file:
            if (file.name.endswith('.jpg')) or (file.name.endswith('.png')):
                obj = Documents(document=file,user=request.user)
                obj.save()
                input_path = obj.document.path
                # Generate the new filename with the current date and time
                current_datetime = datetime.now().strftime("%Y%m%d_%H%M%S")
                original_filename = file.name
                file_extension = os.path.splitext(original_filename)[1]
                new_filename = f"{current_datetime}_{os.path.splitext(original_filename)[0]}{file_extension}"
                folder_path = os.path.join(settings.MEDIA_ROOT, 'documents')
                # Construct the new file path
                new_file_path = os.path.join(folder_path, new_filename)

            # Rename the file
                os.rename(input_path, new_file_path)

                image = Image.open(new_file_path)
                iml = image.convert('RGB')
                
                path = os.path.join(folder_path, new_filename.split('.')[0] + '.pdf')
                
                iml.save(path)
                obj.document = f"documents/{new_filename.split('.')[0]}.pdf"
                obj.save()
                os.remove(new_file_path)
                
            elif file.name.endswith('.docx') or file.name.endswith('.doc'):
                os.environ['HOME'] = '/var/www/.libreoffice'
                os.environ['XDG_CACHE_HOME'] = '/var/www/.libreoffice/.cache'
                os.environ['XDG_CONFIG_HOME'] = '/var/www/.libreoffice/.config'
                os.environ['XDG_DATA_HOME'] = '/var/www/.libreoffice/.local/share'
                os.environ['JAVA_HOME'] = '/usr/lib/jvm/java-11-openjdk-amd64'  # Or the appropriate JRE path
                # Ensure the directory exists
                

                obj = Documents(document=file,name=file.name,user=request.user)
                obj.save()
                input_path = obj.document.path
                print(input_path)
                        # Generate the new filename with the current date and time
                current_datetime = datetime.now().strftime("%Y%m%d_%H%M%S")
                original_filename = file.name
                file_extension = os.path.splitext(original_filename)[1]
                new_filename = f"{current_datetime}_{os.path.splitext(original_filename)[0]}{file_extension}"
                folder_path = os.path.join(settings.MEDIA_ROOT, 'documents')
                # Construct the new file path
                new_file_path = os.path.join(folder_path, new_filename)

            # Rename the file
                os.rename(input_path, new_file_path)
                
                
                
                outdir = r"/var/www/html/dev/media/documents"
                commandStrings = ['libreoffice', '--headless', '--convert-to', 'pdf:writer_pdf_Export', new_file_path, '--outdir',outdir]
                result = subprocess.run(commandStrings,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      env=os.environ.copy() )
                print(result.stdout.decode())
                print(result.stderr.decode())
                if result == 0:
                     print('pdf conversion completed')
                else:
                    print(f"error is {result}")
                os.remove(new_file_path)
                
                obj.document = f"documents/{new_filename.split('.')[0]}.pdf"
                obj.save()
                
                
            else:
                obj = Documents(document=file,name=file.name,user=request.user)
                obj.save()
                input_path = obj.document.path
                print(input_path)
                        # Generate the new filename with the current date and time
                current_datetime = datetime.now().strftime("%Y%m%d_%H%M%S")
                original_filename = file.name
                file_extension = os.path.splitext(original_filename)[1]
                new_filename = f"{current_datetime}_{os.path.splitext(original_filename)[0]}{file_extension}"
                folder_path = os.path.join(settings.MEDIA_ROOT, 'documents')
                # Construct the new file path
                new_file_path = os.path.join(folder_path, new_filename)

            # Rename the file
                os.rename(input_path, new_file_path)
                obj.document = f"documents/{new_filename}"
                obj.save()
            if check:
                return redirect('sign_document')
            else:
                recipients.append({'emails':list_of_dicts,'subject':subject,'message':message})
                list_string = json.dumps(recipients)
                list_bytes = list_string.encode('utf-8')
                encoded_bytes = base64.urlsafe_b64encode(list_bytes)
                encoded_string = encoded_bytes.decode('utf-8')
                return redirect('make_envelope',encoded_list=encoded_string)   
        messages.warning(request, "Please select a file to upload.",extra_tags="alert alert-warning alert-dismissible fade show") 
        return redirect('home')
    return redirect('home')

def convert():
    outdir = "/var/www/html/dev"
    commandStrings = ['libreoffice', '--headless', '--convert-to', 'pdf', 'Lavender_Bay_Boatshed_Website_Testing.docx', '--outdir',outdir]
    result = subprocess.call(commandStrings)
    if result == 0:
        print('pdf conversion completed')
    else:
        print(f"error is {result}")



@login_required
def make_envelope(request,encoded_list):
    
    print(encoded_list)
    decoded_bytes = base64.urlsafe_b64decode(encoded_list)
    decoded_string = decoded_bytes.decode('utf-8')

    # Step 5: Convert the JSON string back to a list
    decoded_list = json.loads(decoded_string)
    print(decoded_list)
    title = "Prepare Document"
    document = Documents.objects.filter(user=request.user)
    if document:
        document = document.last()
        print(document)
    
    
    if request.method == 'POST':
        print('call')
        user = User_Profile.objects.get(id=request.user.id)
        name = f"{user.first_name} {user.last_name}"
        if 'pdf' not in request.FILES:
                return JsonResponse({'status': 'error', 'message': 'No PDF file uploaded.'}, status=400)

        pdf_file = request.FILES['pdf']
        doc_id = request.POST.get('doc_id')
        sign_positions = request.POST.get('images')
        dynamic_value = request.POST.get('dynamic_value')
        print(dynamic_value)
        positions = json.loads(sign_positions)
        print(positions)
        document = Documents.objects.get(id=doc_id)
        user = request.user

        # Save the PDF to a file
        pdf_name = f'prepare document_{user.id}_{datetime.now().strftime("%Y%m%d%H%M%S")}.pdf'
        pdf_path = os.path.join(settings.MEDIA_ROOT, 'prepare_documents', pdf_name)

        with open(pdf_path, 'wb') as f:
            for chunk in pdf_file.chunks():
                f.write(chunk)

        # Save the PDF path in the database
        signed_doc = prepare_documents.objects.create(main_document=document,user=user, document=f'prepare_documents/{pdf_name}',name=pdf_name)
        signed_doc.sign_positions = positions
        signed_doc.save()
        
        recipients = decoded_list
        for i in recipients[0]['emails']:
            Recipients_sign_documents.objects.create(main_document=signed_doc,user=user,recipient=i['email'])
        emails = send_email(recipients,name,user.email,request.user.id,signed_doc.id)
            
        return JsonResponse({'status': 'success', 'pdf_path': signed_doc.document.url})
    context = {'title':title,'document':document}
    return render(request, 'myapp/make_envelope.html',context=context)    
        
        

def send_email(recipients: list, name,user_email, user_id, doc_id):
    uid = urlsafe_base64_encode(force_bytes(user_id))
    doc_id_encoded = urlsafe_base64_encode(force_bytes(doc_id))
    

    for i in recipients[0]['emails']:
        email = i['email']
        subject = "Complete with DigiSign"
        from_email = f"{name} via Digisign <{settings.EMAIL_HOST_USER}>"

        if User_Profile.objects.filter(email=email).exists():
            user = User_Profile.objects.get(email=email)
            token = PasswordResetTokenGenerator().make_token(user)
            user_id_encoded = urlsafe_base64_encode(force_bytes(user.id))
            link = f'https://dev.arushhr.com/sign-document/{uid}/{user_id_encoded}/{token}/{doc_id_encoded}/'
            recipient = Recipients_sign_documents.objects.filter(recipient=email).last()
            recipient.link = link
            recipient.save()
            message = f"{name} send you document for sign"
            obj = Notification(user=user.email,message=message,link=link)
            obj.save()
        else:
            # Generate a custom token for non-registered users
            custom_token = str(uuid.uuid4())
            link = f'https://dev.arushhr.com/new-user/{uid}/{custom_token}/{doc_id_encoded}/'
            message = f"{name} send you document for sign"
            obj = Notification(user=email,message=message)
            obj.save()
        message = f'DigiSign: {link}'
        recipient_list = [email]
        email = EmailMessage(subject, message, from_email, recipient_list, reply_to=[user_email])
        email.send(fail_silently=False)

def new_user(request,admin_id,token,doc_id):
    id=smart_str(urlsafe_base64_decode(admin_id))
    if request.method == 'POST':
        
        email = request.POST.get('email')
        first_name = request.POST.get('first_name')
        
        last_name = request.POST.get('last_name')
        password1 = request.POST.get('password1')
        password2 = request.POST.get('password2')
        query = User_Profile.objects.filter(Q(email=email))
        if query.exists():
            messages.error(request, "Email Already Exists !", extra_tags="alert alert-warning alert-dismissible show")
            return redirect('register')
        if password1 == password2:
            
            user = User_Profile.objects.create_user(email=email,username=email,first_name=first_name,last_name=last_name,password=password1)
            admin = User_Profile.objects.get(id=id)
            user.organisation = admin.organisation
            user.save()
            user_group = Group.objects.get(name='regular user')
            user.groups.add(user_group)
            user_obj = authenticate(email=email,password=password1)
            if user_obj is not None:
                login(request, user_obj)
                token = PasswordResetTokenGenerator().make_token(user_obj)
                encoded_id = urlsafe_base64_encode(force_bytes(user.id))
                link = f'http://127.0.0.1:8000/sign-document/{admin_id}/{encoded_id}/{token}/{doc_id}/'
                recipient = Recipients_sign_documents.objects.filter(recipient=user.email).last()
                recipient.link = link
                recipient.save()
                obj = Notification.objects.filter(user=user_obj.email).last()
                obj.link = link
                obj.save()
                return redirect(link)
        else:
            messages.error(request, "Password and Confirm Password not matched", extra_tags="alert alert-warning alert-dismissible show")
            return redirect('register')  # Redirect to your home page or wherever you want
    
    return render(request, 'myapp/new_user.html')

def document_open_email(name,user_id):
    
    email = User_Profile.objects.get(id=user_id).email
    subject = "Document open notification"
    message = f'{name} open your document for sign'
    from_email = settings.EMAIL_HOST_USER
    recipient_list = [email]

    send_mail(subject, message, from_email, recipient_list)

def document_sign_email(name,user_id):
    
    email = User_Profile.objects.get(id=user_id).email
    subject = "Document sign notification"
    message = f'{name} sign on your document'
    from_email = settings.EMAIL_HOST_USER
    recipient_list = [email]

    send_mail(subject, message, from_email, recipient_list)


@login_required
def recipient_sign(request,admin_id,user_id,token,doc_id):
    id=smart_str(urlsafe_base64_decode(admin_id))
    doc_id=smart_str(urlsafe_base64_decode(doc_id))
    print(doc_id)
    admin = User_Profile.objects.get(id=id)
    user = User_Profile.objects.filter(id=request.user.id)
    if user:
        user = user.first()
        document_open_email(f'{user.first_name} {user.last_name}',admin.id)
    title = "Recipient Signature"
    document = prepare_documents.objects.get(id=doc_id)
    print(type(document.sign_positions))
    json_data = json.dumps(document.sign_positions)
    signatures = Signature.objects.filter(user=request.user)
    signatures_json = serializers.serialize('json', signatures)
    stamps = Stamp.objects.filter(user=request.user)
    stamp_json = serializers.serialize('json', stamps)
    context = {'title':title,'document':document,'json_data':json_data,'signatures':signatures,
               'signatures_json':signatures_json,'stamps':stamps,'stamp_json':stamp_json}
    if request.method == 'POST':
        print('call')
        if 'pdf' not in request.FILES:
                return JsonResponse({'status': 'error', 'message': 'No PDF file uploaded.'}, status=400)

        pdf_file = request.FILES['pdf']
        
        # Save the PDF to a file
        pdf_name = f'signed_{admin.id}_{datetime.now().strftime("%Y%m%d%H%M%S")}.pdf'
        pdf_path = os.path.join(settings.MEDIA_ROOT, 'recipient_sign_documents', pdf_name)

        with open(pdf_path, 'wb') as f:
            for chunk in pdf_file.chunks():
                f.write(chunk)

        # Save the PDF path in the database
        signed_doc = Recipients_sign_documents.objects.filter(main_document__id=doc_id,recipient=user.email).first()
        signed_doc.document = f'recipient_sign_documents/{pdf_name}'
        signed_doc.name = pdf_name
        signed_doc.is_sign = True
        time_now = datetime.now()
        signed_doc.sign_at = time_now
        signed_doc.save()
        
        name = f'{user.first_name} {user.last_name}'
        document_sign_email(name,admin.id)
        message = f"Your document has beed sign by {name}"
        link = f"https://dev.arushhr.com/download-recipient_document/{signed_doc.id}"
        obj = Notification(user=admin.email,message=message,link=link)
        obj.save()
        return JsonResponse({'status': 'success', 'id': signed_doc.id})
    return render(request, 'myapp/recipient_sign.html', context=context)

@login_required
def recipient_sign_success(request,id):
    title = 'Recipient signature success'
    context = {'title':title,'id':id}
    return render(request, 'myapp/recipient_sign_success.html',context=context)  

class sent_agreements(View):
    def get(self,request):
        title = 'Agreements Sent'
        context = {'title':title}
        return render(request, 'myapp/sent_agreements.html',context=context)    
    
@login_required   
def Agreements(request):
    
    title = 'Sent Agreements'
    data = Recipients_sign_documents.objects.filter(user=request.user).order_by('-id')
    json_data = []

    for i in data:
        document_name = None
        if i.main_document and i.main_document.main_document:
            document_name = i.main_document.main_document.name
        
        json_data.append({
            'id': i.id,
            'document': document_name,
            'recipient': i.recipient,
            'sent_at': i.created_at,
            'is_sign': i.is_sign,
            'sign_at': i.sign_at,
        })
    json_data = json.dumps(json_data,indent=4, sort_keys=True, default=str)
    context = {'title': title, 'data': data,'json_data':json_data}
    if request.method == 'POST':
        print('call')
        body = json.loads(request.body)  # Parse the JSON body
        doc_name = body.get('document_name')
        email = body.get('email')
        sent_date = body.get('sent_date')
        sign_date = body.get('sign_date')
        print(doc_name, email, sent_date, sign_date)
        sent_date = timezone.make_aware(datetime.strptime(sent_date, "%Y-%m-%d")) if sent_date else None
        sign_date = timezone.make_aware(datetime.strptime(sign_date, "%Y-%m-%d")) if sign_date else None
        # print(doc_name, email, sent_date, sign_date)
        filter_query = Q()
    
    # Add conditions to the filter query based on provided inputs
        if doc_name:
            filter_query |= Q(main_document__main_document__name__icontains=doc_name)
        if email:
            filter_query |= Q(recipient=email)
        if sent_date:
            filter_query |= Q(created_at__date=sent_date.date())  # Using .date() for date comparison
        if sign_date:
            filter_query |= Q(sign_at__date=sign_date.date())
    
    # Apply the filter
        documents_send_to_me = data.filter(filter_query)
        print(documents_send_to_me.count())
        data1 = []
        for i in documents_send_to_me:
            document_name = None
            time = None
            if i.main_document and i.main_document.main_document:
                document_name = i.main_document.main_document.name
            if i.sign_at:
                time = i.sign_at.strftime("%Y-%m-%d %H:%M")
            data1.append({
                "id":i.id,
                "document_name":document_name,
                "recipient":i.recipient,
                "sent_from":i.user.get_full_name,
                "sent_at": i.created_at.strftime("%Y-%m-%d %H:%M"),
                "is_sign": i.is_sign,
                "sign_at": time,
                "link":i.link,
            })
        print(data1)
        return JsonResponse({"data":data1,"results":documents_send_to_me.count()})
    return render(request, 'myapp/agreements.html', context=context)

@login_required
def complete_agreements(request):
        title = 'Completed'
        data = Recipients_sign_documents.objects.filter(Q(user=request.user) & Q(is_sign=True))
        context = {'title':title,'data':data}
        if request.method == 'POST':
                print('call')
                body = json.loads(request.body)  # Parse the JSON body
                doc_name = body.get('document_name')
                email = body.get('email')
                sent_date = body.get('sent_date')
                sign_date = body.get('sign_date')
                print(doc_name, email, sent_date, sign_date)
                sent_date = timezone.make_aware(datetime.strptime(sent_date, "%Y-%m-%d")) if sent_date else None
                sign_date = timezone.make_aware(datetime.strptime(sign_date, "%Y-%m-%d")) if sign_date else None
                # print(doc_name, email, sent_date, sign_date)
                filter_query = Q()
            
            # Add conditions to the filter query based on provided inputs
                if doc_name:
                    filter_query |= Q(main_document__main_document__name__icontains=doc_name)
                if email:
                    filter_query |= Q(recipient=email)
                if sent_date:
                    filter_query |= Q(created_at__date=sent_date.date())  # Using .date() for date comparison
                if sign_date:
                    filter_query |= Q(sign_at__date=sign_date.date())
            
            # Apply the filter
                documents_send_to_me = data.filter(filter_query)
                print(documents_send_to_me.count())
                data = []
                for i in documents_send_to_me:
                    document_name = None
                    time = None
                    if i.main_document and i.main_document.main_document:
                        document_name = i.main_document.main_document.name
                    if i.sign_at:
                        time = i.sign_at.strftime("%Y-%m-%d %H:%M")
                    data.append({
                        "id":i.id,
                        "document_name":document_name,
                        "recipient":i.recipient,
                        "sent_at": i.created_at.strftime("%Y-%m-%d %H:%M"),
                        "is_sign": i.is_sign,
                        "sign_at": time,
                        "link":i.link,
                    })
                print(data)
                return JsonResponse({"data":data,"results":documents_send_to_me.count()})
        return render(request, 'myapp/complete_agreements.html',context=context)
 
    
@login_required
def download_recipient_document(request, id):
    agreement = Recipients_sign_documents.objects.get(id=id)
    with open(agreement.document.path, 'rb') as f:
            response = HttpResponse(f.read(), content_type='application/pdf')
            response['Content-Disposition'] = 'inline; filename=' + agreement.name
            return response

@login_required    
def delete_agreement(request,id):
    agreement = Recipients_sign_documents.objects.get(id=id)
    agreement.delete()
    messages.success(request, f'Agreement of {agreement.recipient} Deleted Successfully', extra_tags='alert alert-warning alert-dismissible show')
    return redirect('home')

@login_required
def download_prepare_document(request, id):
    agreement = prepare_documents.objects.get(id=id)
    with open(agreement.document.path, 'rb') as f:
            response = HttpResponse(f.read(), content_type='application/pdf')
            response['Content-Disposition'] = 'inline; filename=' + agreement.name
            return response 

@login_required
def delete_cancel(request):
    return redirect('home')  

    
class SignvDocumentiew(View):
    def get(self,request):
        title = "Sign Documents"
        document = Documents.objects.filter(user=request.user)
        if document:
            document=document.last()
        signatures = Signature.objects.filter(user=request.user)
        signatures_json = serializers.serialize('json', signatures)
        stamps = Stamp.objects.filter(user=request.user)
        stamp_json = serializers.serialize('json', stamps)
        context = {'title':title,'document':document,'signatures_json':signatures_json,'signatures':signatures,
                   'stamp_json':stamp_json,'stamps':stamps}
        return render(request, 'myapp/sign_document.html',context=context)  

    
    def post(self,request):
        print('call')
        if 'pdf' not in request.FILES:
                return JsonResponse({'status': 'error', 'message': 'No PDF file uploaded.'}, status=400)

        pdf_file = request.FILES['pdf']
        user = request.user
        doc_id = request.POST.get('doc_id')
        document = Documents.objects.get(id=doc_id)
        # Save the PDF to a file
        pdf_name = f'signed_{user.id}_{datetime.now().strftime("%Y%m%d%H%M%S")}.pdf'
        pdf_path = os.path.join(settings.MEDIA_ROOT, 'signed_documents', pdf_name)

        with open(pdf_path, 'wb') as f:
            for chunk in pdf_file.chunks():
                f.write(chunk)

        # Save the PDF path in the database
        signed_doc = sign_documents.objects.create(user=user,main_document=document, document=f'signed_documents/{pdf_name}',name=pdf_name)

        return JsonResponse({'status': 'success', 'id': signed_doc.id})

@login_required
def own_sign_success(request,id):
    title = 'Own Document Signature Success'
    context = {'title':title,'id':id}
    return render(request, 'myapp/own_sign_success.html',context=context)  

@login_required
def download_own_document(request, id):
    agreement = sign_documents.objects.get(id=id)
    with open(agreement.document.path, 'rb') as f:
            response = HttpResponse(f.read(), content_type='application/pdf')
            response['Content-Disposition'] = 'inline; filename=' + agreement.main_document.name
            return response

@login_required()
def delete_own_document(request,id):
    obj = sign_documents.objects.get(id=id)
    obj.delete()
    
    messages.success(request, f"Document deleted successfully",extra_tags="alert alert-success alert-dismissible show")
    return redirect('home')

@login_required
def delete_own_agreement_cancel(request):
    return redirect('home')  

def extract_text_from_pdf(pdf_path):
    reader = PdfReader(pdf_path)
    text = ""
    for page in reader.pages:
        text += page.extract_text()
    print(text)
    images = extract_images_from_pdf(pdf_path)
    text_data = ocr_images(images)
    text += text_data
    return text

def extract_images_from_pdf(pdf_path):
    # Open the PDF
    doc = fitz.open(pdf_path)
    images = []
    
    for page_num in range(doc.page_count):
        page = doc.load_page(page_num)
        image_list = page.get_images(full=True)
        
        for img_index, img in enumerate(image_list):
            xref = img[0]
            base_image = doc.extract_image(xref)
            image_bytes = base_image["image"]
            image = Image.open(io.BytesIO(image_bytes))
            images.append(image)
    
    return images

def ocr_images(images):
    print(images)
    text_list = ""
    
    pytesseract.tessdata_dir_config = r'--tessdata-dir /usr/share/tesseract-ocr/4.00/tessdata'

    for img in images:
        text = pytesseract.image_to_string(img)
        text_list += text
    
    return text_list

def extract_text_from_docx(pdf_path):
    document = Document(pdf_path)
    paragraphs = document.paragraphs
    return paragraphs
   
def chatbot(request):
    if request.method == 'POST':
        question = request.POST.get('question')
        print(question)
        doc_id = request.POST.get('doc_id')
        print(doc_id)
        document = prepare_documents.objects.get(id=doc_id)
        pdf_path = document.document.path

        pdf_text = None
        if pdf_path.endswith('.pdf'):
        # Extract text from the PDF
            pdf_text = extract_text_from_pdf(pdf_path)
            print(pdf_text)
        
        # Prepare the prompt
        prompt = f"{pdf_text}\n\nQuestion: {question}\nAnswer:"
        client = openai.OpenAI(
    
                api_key=config('openai_apikey')

                )
        # Get the response from OpenAI
        response = client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=[
            {
                "role": "user",
                "content": prompt,
            }
            ],
            stop=None,
            temperature=0.5
        )
        print(response)
        answer = response.choices[0].message.content

        print(answer)
        return JsonResponse({'answer': answer})

def notifications(request):
    
    notifications = Notification.objects.filter(user=request.user.email).order_by('-id')[:6]
    
    notifStatus = False
    total_unread = 0
    json_data = []
    
    
    
    
    for d in notifications:
        print(d.created)
        try:
            notif_status = mark_read_notifications.objects.get(user=request.user,notif=d)
            if notif_status:
                notifStatus = True
        except mark_read_notifications.DoesNotExist:
            notifStatus = False
        if not notifStatus:
            total_unread = total_unread + 1
        now = timezone.now()
                # Calculate the time difference between now and the value
        diff = now - d.created
        # print(diff)
        time = d.created.strftime('%Y-%m-%d')
                # If the difference is less than 1 hour, display in minutes ago
        if now - d.created > timedelta(days=1):
            time = d.created.strftime('%Y-%m-%d')
            print(time)    
        elif now - d.created > timedelta(hours=1):
            time = timesince(d.created)
            print(time)
            time = f'{time} ago'
        else:
            minutes = int((now - d.created).total_seconds() / 60)
            time = f"{minutes} minute{'s' if minutes > 1 else ''} ago"
            print(time)
        
        json_data.append({
            'id':d.id,
            'notify_detail':d.message,
            'notifStatus':notifStatus,
            'time':time,
            'link':d.link
        })
    
    # json_data.append({'total_unread':total_unread})
    return JsonResponse({"data":json_data,'total_unread':total_unread,'role':'employee'})

def mark_read_notify(request):
    notify_id = request.GET['notify_id']
    obj = Notification.objects.get(id=notify_id)
    emp = User_Profile.objects.get(pk=request.user.id)
    notif_data = mark_read_notifications.objects.filter(Q(notif=obj) & Q(user=request.user) & Q(status=True))
    print(notif_data)
    if not notif_data:

        mark_read_notifications.objects.create(notif=obj, user=emp, status=True)
    return JsonResponse({"msg":True})
