import datetime
from datetime import datetime
from django.shortcuts import render, redirect
from django.contrib import messages
from .models import user, appointment,location,company,department,website_setting,roles
from .context_processors import my_constants
from django.db.models import Q
import os
from PIL import Image
import io
from django.utils.html import strip_tags
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
import base64
# from gate_keeper_app.whatsapps_send_notification import whatsapps_send_notifications
from gate_keeper_app.visitor_qr_whatsapp_notification import whatsapps_send_notifications
import requests
from django.core import signing
from visitors_app.views import date_time,generate_vms_string,generate_unique_request_id
from visitor_management import settings
from email.mime.image import MIMEImage

def qr_appointment(request):
    al_location = location.objects.all()
    all_employee = user.objects.filter(Q(type__icontains='employee'), is_active=1)

    companyes = company.objects.all()

    departmentes = department.objects.all()


    constants = my_constants(request)

    from_email = constants['From_Email']

    role = roles.objects.all()
    website_settings = website_setting.objects.first()
    is_id_card_required = website_settings.is_id_card_required
    if request.method == "POST":

        user_ides = request.POST['user_id']
        if user_ides:
            user_ides_chane = int(user_ides)
            visitor_user = user.objects.filter(id=user_ides_chane).first()
            all_users = user.objects.get(id=user_ides_chane)

        employee_id = request.POST['employee']
        date = request.POST['date']
        time = request.POST['time']
        purpose = request.POST['Purpose']
        visitors_type = request.POST['visitors_type']
        detail = request.POST['detail']
        firstname = request.POST['Firstname']
        lastname = request.POST['Lastname']
        email = request.POST['Email']
        visitor_company_name = request.POST['visitor_company_name']
        address = request.POST['Address']
        mobile = request.POST['mobile']
        gender = request.POST['gender']
        company_id = request.POST['company_id']
        department_id = request.POST['department_id']
        location_id = request.POST['location_id']
        image = request.POST['user_image']
        id_card = request.POST['base_id_card']
        visitors_timing = request.POST['visitors_timing']
        device = request.POST['devices']
        vehicle_number = request.POST['vehicle_number']

        if 'user' in image:
            filename = image

        else:
            base64_data = image.split(",")[1]
            binary_data = base64.b64decode(base64_data)
            image = Image.open(io.BytesIO(binary_data))

            save_directory = 'user/'
            if not os.path.exists(save_directory):
                os.makedirs(save_directory)
            filename = firstname.replace(' ', '_')
            file_date = generate_vms_string()
            new_file_name = file_date.replace('VMS', '')
            filename = f"{filename}_{new_file_name}.jpg"
            face_image_path = os.path.join(save_directory, filename)

            image.save(face_image_path)
        id_cards_filename = ''
        if id_card:
            if 'id_cards/' in id_card:
                id_cards_filename = os.path.basename(id_card)
            else:
                try:
                    if ',' in id_card:
                        base64_data = id_card.split(',')[1]
                    else:
                        raise ValueError("Invalid ID card format")

                    binary_data = base64.b64decode(base64_data)

                    img = Image.open(io.BytesIO(binary_data))

                    if img.mode in ('RGBA', 'LA'):
                        background = Image.new('RGB', img.size, (255, 255, 255))
                        background.paste(img, mask=img.split()[3])
                        img = background
                    else:
                        img = img.convert('RGB')

                    save_directory = os.path.join(settings.MEDIA_ROOT, 'id_cards')
                    os.makedirs(save_directory, exist_ok=True)

                    unique_name = generate_vms_string().replace('VMS', '')
                    clean_name = firstname.strip().replace(' ', '_')

                    id_cards_filename = f"idcard_{clean_name}_{unique_name}.jpg"

                    id_card_path = os.path.join(save_directory, id_cards_filename)

                    img.save(id_card_path, 'JPEG', quality=95)

                except Exception as e:
                    messages.error(
                        request,
                        f"Error processing ID Card: {str(e)}",
                        extra_tags='danger'
                    )
                    return redirect('qr_appointment')
        if user_ides in '':
            if email != '':
                if user.objects.filter(email=email).exists():
                    messages.error(request, 'User Email already exists.', extra_tags='danger')
                    return redirect('visitors_self_safety_training')
            else:
                email = None
        else:
            email = email
            pass

        created_at = date_time()
        updated_at = date_time()

        if (employee_id == '' or employee_id == 'Choose employee' or
                date == '' or time == '' or purpose == '' or
                visitors_type == 'Choose visitors type' or visitors_type == '' or
                firstname == '' or
                lastname == '' or address == '' or gender == '' or
                company_id == '' or company_id == '-- Select Company  --' or
                department_id == '' or department_id == '-- Select Department --' or
                location_id == '' or location_id == '-- Select Location --' ):
            messages.error(request, "All fields are required.", extra_tags="danger")
            return render(request, 'dashboard/visitors_dashboard/qr_appointment.html', {
                 'all_employee': all_employee, 'locationes': al_location,
                'companyes': companyes, 'departmentes': departmentes, 'roles': role,'is_id_card_required':is_id_card_required
            })

        try:
            if user_ides in '':
                new_user = user.objects.create(
                    first_name=firstname,
                    last_name=lastname,
                    email=email,
                    address=address,
                    mobile=mobile,
                    gender=gender,
                    image=filename,
                    id_card=id_cards_filename,
                    type='visitors',
                    company_id=company_id,
                    department_id=department_id,
                    location_id=location_id,
                    is_active=1,
                    created_at=created_at,
                    uni_id=generate_vms_string(),
                    created_by=0,
                    employee_code=0,
                    designation_id=0
                )

                new_user.save()
                new_user.save()
                new_appointment = appointment.objects.create(
                    employee_id=employee_id,
                    date=date,
                    time=time,
                    status='pending',
                    purpose=purpose,
                    visitors_type=visitors_type,
                    detail=detail,
                    visitors_id=new_user.id,  # Assuming there's a ForeignKey relationship
                    created_at=date_time(),
                    created_by=0,
                    visitors_timing=visitors_timing,
                    employee_approval=None,
                    visitor_company_name=visitor_company_name,
                    devices=device,
                    request_id=generate_unique_request_id(),
                    vehicle_number=vehicle_number,
                    id_card=id_cards_filename,

                )
                # new_appointment.request_id = f"{datetime.now().strftime('VMS%d%m%Y%H%M')}{new_appointment.id}"
                # new_appointment.save(update_fields=['request_id'])
                # new_appointment.save()
                employee_email = user.objects.filter(id=employee_id).first()

                if employee_email != '':
                    try:
                        check_company = company.objects.get(id=company_id)
                        company_name = check_company.company_name
                        visitor_name = f"{new_user.first_name} {new_user.last_name}"
                        purpose = new_appointment.purpose
                        person_name = f"{employee_email.first_name} {employee_email.last_name}"
                        person_departments = department.objects.filter(id=employee_email.department_id).first()
                        person_departments = person_departments.department_name
                        # visit_schedule = f"{new_appointment.date} {new_appointment.time}"
                        new_appointment_created_at = new_appointment.created_at
                        dt = datetime.strptime(new_appointment_created_at, "%y-%m-%d %H:%M:%S")
                        check_in_date = dt.strftime("%d-%m-%Y")
                        check_in_time = dt.strftime("%H:%M:%S")
                        visit_schedule = f"{check_in_date} {check_in_time}"

                        appointment_id = new_appointment.id
                        encrypted_appointment_id = signing.dumps(appointment_id)
                        base_url = request.build_absolute_uri('/')[:-1]
                        subject_employee = f'New Visitor Request – Approval Required | {company_name}'
                        context_employee = {
                            'company_name': company_name,
                            'visitor_name': visitor_name,
                            'purpose': purpose,
                            'person_name': person_name,
                            'person_departments': person_departments,
                            'visit_schedule': visit_schedule,
                            'request_id': new_appointment.request_id,
                            'accept_url': f"{base_url}/accept/{encrypted_appointment_id}",
                            'reject_url': f"{base_url}/reject/{encrypted_appointment_id}",
                            'vehicle_number': new_appointment.vehicle_number,
                            # 'visitor_photo':f"{base_url}/user/{new_user.image.url}"
                            # 'visitor_photo':request.build_absolute_uri(new_user.image)
                            'visitor_photo': 'cid:visitor_image',
                            'other_guests_detail': detail
                        }
                        template_name_employee = 'dashboard/email_templates/email_to_concerned_person_(approval_required).html'

                        message_employee = render_to_string(template_name_employee, context_employee)
                        plain_message_employee = strip_tags(message_employee)
                        recipient_list_employee = [employee_email]

                        mail_employee = EmailMultiAlternatives(subject_employee, plain_message_employee, from_email,
                                                               recipient_list_employee)
                        mail_employee.attach_alternative(message_employee, "text/html")
                        # image_path = f"{base_url}/user/{new_user.image}"
                        # image_path =os.path.exists(new_user.image)
                        # image_path = new_user.image.path
                        if new_user.image:
                            image_filename = os.path.basename(new_user.image.name)
                            image_path = os.path.join(settings.MEDIA_ROOT, 'user', image_filename)

                            with open(image_path, "rb") as img:
                                mime_img = MIMEImage(img.read())
                                mime_img.add_header('Content-ID', '<visitor_image>')
                                mime_img.add_header('Content-Disposition', 'inline', filename="user.png")
                                mail_employee.attach(mime_img)
                        else:
                            pass
                        mail_employee.send()
                    except Exception as e:
                        messages.error(request, f"Error: {e}", extra_tags="danger")
                        # return redirect('visitors_self_safety_training')
                try:
                    if employee_email.mobile != '' or new_user.mobile != '':
                        # visitor_name = new_user.first_name
                        # visitor_name = new_user.first_name
                        visitor_name  =f"{new_user.first_name} {new_user.last_name}"
                        if visitor_name == '':
                            visitor_name = '(visitor name)'
                        else:
                            visitor_name = visitor_name

                        visitor_mobile = new_user.mobile

                        if visitor_mobile == '':
                            visitor_mobile = None
                        else:
                            visitor_mobile = visitor_mobile

                        invitation_link = f"{base_url}/register/{encrypted_appointment_id}"
                        employee_mobile = employee_email.mobile
                        employee_name = f"{employee_email.first_name} {employee_email.last_name}"
                        visitor_name = visitor_name if visitor_name else 'Default Visitor Name'
                        accept_url = f"{base_url}/accept/{encrypted_appointment_id}"
                        reject_url = f"{base_url}/reject/{encrypted_appointment_id}"
                        purpose_of_visit = new_appointment.purpose

                        check_company = company.objects.get(id=company_id)
                        company_name = check_company.company_name

                        check_location = location.objects.get(id=location_id)
                        company_location = check_location.location_name

                        new_appointment_created_at = new_appointment.created_at
                        dt = datetime.strptime(new_appointment_created_at, "%y-%m-%d %H:%M:%S")
                        check_in_date = dt.strftime("%d-%m-%Y")
                        check_in_time = dt.strftime("%H:%M:%S")
                        # check_in_date = datetime.today().strftime("%d-%m-%Y")
                        # check_in_time = datetime.now().strftime("%H:%M")
                        visitor_image = f"{base_url}/user/{new_user.image}"
                        request_id = new_appointment.request_id
                        qr_code = request.build_absolute_uri(f'/gate_keeper/qr_code_visitor_details/{signing.dumps(new_appointment.id)}'),
                        visitor_company_name = new_appointment.visitor_company_name
                        if visitor_company_name in [None, '', 'NULL', 'null']:
                            visitor_company_name = 'N/A'
                        website_settings = website_setting.objects.first()
                        if website_settings.whatsapp_notification == 1:
                            company_website = website_settings.company_domain
                            whatsapps_send_notifications(request, employee_mobile, employee_name, visitor_name,
                                                         accept_url, reject_url, purpose_of_visit, company_name,
                                                         company_location, check_in_date, check_in_time,
                                                         company_website, visitor_mobile, invitation_link,request_id,visitor_image,qr_code[0],visitor_company_name)
                except requests.exceptions.RequestException as e:
                    messages.error(request, f"Error: {e}", extra_tags="danger")
                    return redirect('visitors_self_safety_training')
                if email != '' and email != None:
                    try:
                        check_company = company.objects.get(id=company_id)
                        company_name = check_company.company_name
                        visitor_name = f"{new_user.first_name} {new_user.last_name}"
                        person_name = f"{employee_email.first_name} {employee_email.last_name}"
                        person_departments = department.objects.filter(id=employee_email.department_id).first()
                        person_departments = person_departments.department_name
                        subject_visitor = f'Visitor Request Received – {company_name}'
                        context_visitor = {
                            'company_name': company_name,
                            'visitor_name': visitor_name,
                            'person_name': person_name,
                            'person_departments': person_departments,
                            'request_id': new_appointment.request_id,

                        }
                        template_name_visitor = 'dashboard/email_templates/visitor_request_submitted.html'
                        message_visitor = render_to_string(template_name_visitor, context_visitor)
                        plain_message_visitor = strip_tags(message_visitor)
                        recipient_list_visitor = [email]

                        mail_visitor = EmailMultiAlternatives(subject_visitor, plain_message_visitor, from_email,
                                                              recipient_list_visitor)
                        mail_visitor.attach_alternative(message_visitor, "text/html")
                        mail_visitor.send()

                        messages.success(request, "Appointment successfully created.", extra_tags="success")
                        return redirect('visitors_self_safety_training')
                    except requests.RequestException as e:
                        messages.success(request, "Appointment successfully created.", extra_tags="success")
                        messages.error(request, f"API request error: {e}", extra_tags="danger")
                        return redirect('visitors_self_safety_training')
                else:
                    messages.success(request, "Appointment successfully created.", extra_tags="success")
                    return redirect('visitors_self_safety_training')
            else:
                if email == '':
                    email = None
                all_users.first_name = firstname
                all_users.last_name = lastname
                all_users.email = email
                # all_users.password = password
                all_users.address = address
                all_users.mobile = mobile
                all_users.gender = gender
                all_users.image = filename
                all_users.type = 'visitors'
                all_users.company_id = company_id
                all_users.department_id = department_id
                all_users.location_id = location_id
                all_users.is_active = 1
                all_users.created_at = created_at
                # all_users.uni_id = generate_vms_string()
                all_users.created_by =  0
                all_users.employee_code = 0
                all_users.designation_id = 0
                all_users.save()

                new_appointment = appointment.objects.create(
                    employee_id=employee_id,
                    date=date,
                    time=time,
                    status='pending',
                    purpose=purpose,
                    visitors_type=visitors_type,
                    detail=detail,
                    visitors_id=user_ides,  # Assuming there's a ForeignKey relationship
                    created_at=date_time(),
                    created_by=0,
                    # access_card_id=employees_API,
                    visitors_timing=visitors_timing,
                    employee_approval=None,
                    visitor_company_name=visitor_company_name,
                    devices=device,
                    request_id=generate_unique_request_id(),
                    vehicle_number=vehicle_number,
                    id_card=id_cards_filename,
                )
                # new_appointment.request_id = f"{datetime.now().strftime('VMS%d%m%Y%H%M')}{new_appointment.id}"
                # new_appointment.save(update_fields=['request_id'])
                # new_appointment.save()
                employee_email = user.objects.filter(id=employee_id).first()

                if employee_email != '':
                    try:
                        appointment_id = new_appointment.id
                        check_company = company.objects.get(id=company_id)
                        company_name = check_company.company_name
                        visitor_name = f"{all_users.first_name} {all_users.last_name}"
                        purpose = new_appointment.purpose
                        person_name = f"{employee_email.first_name} {employee_email.last_name}"
                        person_departments = department.objects.filter(id=employee_email.department_id).first()
                        person_departments = person_departments.department_name
                        # visit_schedule = f"{new_appointment.date} {new_appointment.time}"
                        new_appointment_created_at = new_appointment.created_at
                        dt = datetime.strptime(new_appointment_created_at, "%y-%m-%d %H:%M:%S")
                        check_in_date = dt.strftime("%d-%m-%Y")
                        check_in_time = dt.strftime("%H:%M:%S")
                        visit_schedule = f"{check_in_date} {check_in_time}"
                        appointment_id = new_appointment.id
                        encrypted_appointment_id = signing.dumps(appointment_id)
                        base_url = request.build_absolute_uri('/')[:-1]
                        subject_employee = f'New Visitor Request – Approval Required | {company_name}'
                        context_employee = {
                            'company_name': company_name,
                            'visitor_name': visitor_name,
                            'purpose': purpose,
                            'person_name': person_name,
                            'person_departments': person_departments,
                            'visit_schedule': visit_schedule,
                            'accept_url': f"{base_url}/accept/{encrypted_appointment_id}",
                            'reject_url': f"{base_url}/reject/{encrypted_appointment_id}",
                            'request_id': new_appointment.request_id,
                            'vehicle_number': new_appointment.vehicle_number,
                            # 'visitor_photo':f"{base_url}/user/{all_users.image.url}"
                            # 'visitor_photo':request.build_absolute_uri(all_users.image)
                            # 'visitor_photo':f"https://vms.easyvisit.in/user/user.png"
                            'visitor_photo': 'cid:visitor_image',
                            'other_guests_detail': detail
                        }
                        template_name_employee = 'dashboard/email_templates/email_to_concerned_person_(approval_required).html'

                        message_employee = render_to_string(template_name_employee, context_employee)
                        plain_message_employee = strip_tags(message_employee)
                        recipient_list_employee = [employee_email]

                        mail_employee = EmailMultiAlternatives(subject_employee, plain_message_employee, from_email,
                                                               recipient_list_employee)
                        mail_employee.attach_alternative(message_employee, "text/html")
                        image_filename = os.path.basename(all_users.image.name)
                        image_path = os.path.join(settings.MEDIA_ROOT, 'user', image_filename)

                        with open(image_path, "rb") as img:
                            mime_img = MIMEImage(img.read())
                            mime_img.add_header('Content-ID', '<visitor_image>')
                            mime_img.add_header('Content-Disposition', 'inline', filename="user.png")
                            mail_employee.attach(mime_img)
                        mail_employee.send()
                    except Exception as e:
                        messages.success(request, "Appointment successfully created.", extra_tags="success")
                        messages.error(request, f"Error: {e}", extra_tags="danger")
                        # return redirect('visitors_self_safety_training')
                try:
                    if employee_email.mobile != '' or all_users.mobile != '':
                        # visitor_name = new_user.first_name
                        visitor_name =f"{all_users.first_name} {all_users.last_name}"
                        if visitor_name == '':
                            visitor_name = '(visitor name)'
                        else:
                            visitor_name = visitor_name

                        visitor_mobile = all_users.mobile
                        if visitor_mobile == '':
                            visitor_mobile = None
                        else:
                            visitor_mobile = visitor_mobile
                        invitation_link = f"{base_url}/register/{encrypted_appointment_id}"
                        employee_mobile = employee_email.mobile
                        employee_name = f"{employee_email.first_name} {employee_email.last_name}"
                        visitor_name = visitor_name if visitor_name else 'Default Visitor Name'
                        accept_url = f"{base_url}/accept/{encrypted_appointment_id}"
                        reject_url = f"{base_url}/reject/{encrypted_appointment_id}"

                        purpose_of_visit = new_appointment.purpose
                        request_id = new_appointment.request_id
                        check_company = company.objects.get(id=company_id)
                        company_name = check_company.company_name
                        check_location = location.objects.get(id=location_id)
                        company_location = check_location.location_name

                        new_appointment_created_at = new_appointment.created_at
                        dt = datetime.strptime(new_appointment_created_at, "%y-%m-%d %H:%M:%S")
                        check_in_date = dt.strftime("%d-%m-%Y")
                        check_in_time = dt.strftime("%H:%M:%S")
                        visitor_image = f"{base_url}/user/{all_users.image}"
                        request_id = new_appointment.request_id
                        qr_code = request.build_absolute_uri(f'/gate_keeper/qr_code_visitor_details/{signing.dumps(new_appointment.id)}'),
                        visitor_company_name = new_appointment.visitor_company_name
                        if visitor_company_name in [None, '', 'NULL', 'null']:
                            visitor_company_name = 'N/A'
                        website_settings = website_setting.objects.first()
                        if website_settings.whatsapp_notification == 1:
                            company_website = website_settings.company_domain

                            whatsapps_send_notifications(request, employee_mobile, employee_name, visitor_name,
                                                         accept_url, reject_url, purpose_of_visit, company_name,
                                                         company_location, check_in_date, check_in_time,
                                                         company_website, visitor_mobile, invitation_link, request_id,
                                                         visitor_image, qr_code[0],visitor_company_name)
                except requests.exceptions.RequestException as e:
                    messages.error(request, f"Error: {e}", extra_tags="danger")
                    return redirect('visitors_self_safety_training')
                if email != '' and email != None:
                    try:
                        check_company = company.objects.get(id=company_id)
                        company_name = check_company.company_name
                        visitor_name = f"{all_users.first_name} {all_users.last_name}"
                        person_name = f"{employee_email.first_name} {employee_email.last_name}"
                        person_departments = department.objects.filter(id=employee_email.department_id).first()
                        person_departments = person_departments.department_name
                        subject_visitor = f'Visitor Request Received – {company_name}'
                        context_visitor = {
                            'company_name': company_name,
                            'visitor_name': visitor_name,
                            'person_name': person_name,
                            'person_departments': person_departments,
                            'request_id': new_appointment.request_id,

                        }
                        template_name_visitor = 'dashboard/email_templates/visitor_request_submitted.html'
                        message_visitor = render_to_string(template_name_visitor, context_visitor)
                        plain_message_visitor = strip_tags(message_visitor)
                        recipient_list_visitor = [email]

                        mail_visitor = EmailMultiAlternatives(subject_visitor, plain_message_visitor, from_email,
                                                              recipient_list_visitor)
                        mail_visitor.attach_alternative(message_visitor, "text/html")
                        mail_visitor.send()

                        messages.success(request, "Appointment successfully created.", extra_tags="success")
                        return redirect('visitors_self_safety_training')
                    except requests.RequestException as e:
                        messages.success(request, "Appointment successfully created.", extra_tags="success")
                        messages.error(request, f"API request error: {e}", extra_tags="danger")
                        return redirect('visitors_self_safety_training')
                else:
                    messages.success(request, "Appointment successfully created.", extra_tags="success")
                    return redirect('visitors_self_safety_training')
        except requests.RequestException as e:
            messages.error(request, f"API request error: {e}", extra_tags="danger")

    return render(request, 'dashboard/visitors_dashboard/qr_appointment.html', {
         'all_employee': all_employee, 'locationes': al_location,
        'companyes': companyes, 'departmentes': departmentes, 'roles': role,'is_id_card_required':is_id_card_required
    })