
from django.shortcuts import redirect, render
from django.contrib import messages
from datetime import datetime, timedelta
from django.db.models import Sum, Count, Q, F
from django.urls import reverse
from account.models import *
from django.core.paginator import Paginator
from .utils.decorators import role_required
#for pdf
from django.template.loader import get_template
from django.http import HttpResponse
from xhtml2pdf import pisa



from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import login_required
User = get_user_model()
from .variable import *
from .custom_today import get_custom_today



#TODO:admin dashboard
@role_required('dashboard_admin')
def dashboard_admin(request):
    date = get_custom_today()
    attendance_summary = AttendanceSummary.objects.filter(date=date,attendance_summary_cart__battalion_approved=True,attendance_summary_cart__dq_approved=True,attendance_summary_cart__adjutant_approved=True)
    total_posted = Member.objects.filter(active=True).count()
    total_out_of_unit_emp = OutOfUnitEmp.objects.filter(status=True, member__active=True,member__t_company__isnull=True).count()
    total_ops_depl = Member.objects.filter(ops_depl=True, active=True).count()
    
    # Dynamically create the aggregate query
    aggregate_query = {field: Sum(field) for field in field_names}
    # Execute the aggregate query
    record = attendance_summary.aggregate(**aggregate_query)
    # Replace None values with 0
    record = {key: value or 0 for key, value in record.items()}
    # calculate out of unit emp


    # Aggregate values
    toe_auth = Company.objects.aggregate(**{field: Sum(field) for field in member_types_fields})
    toe_auth['total'] = sum(value or 0 for value in toe_auth.values())
    ere_auth = Company.objects.aggregate(**{field: Sum(field) for field in ere_member_types_fields})
    ere_auth['total'] = sum(value or 0 for value in ere_auth.values())
    total_auth = toe_auth['total'] + ere_auth['total']
    # Calculate combined totals
    combined_total_auth = {}
    for field in member_types_fields:
        toe_value = toe_auth.get(field) or 0
        ere_value = ere_auth.get(f'ere_{field}') or 0
        combined_total_auth[field + '_total'] = toe_value + ere_value
    # Optional: calculate overall total of all combined
    combined_total_auth['grand_total'] = sum(combined_total_auth.values())


    # Create a dictionary to store counts dynamically
    posted = {
    field: Member.objects.filter(member_type__name=field,active=True).count() for field in member_types_fields
    }
    # Calculate total sum of all members
    posted['total'] = sum(posted.values())
    
    # Create a dictionary to store counts dynamically
    ops_depl = {
    field: Member.objects.filter(member_type__name=field,active=True,ops_depl=True).count() for field in member_types_fields
    }
    # Calculate total sum of all members
    ops_depl['total'] = sum(ops_depl.values())
    
    # Create a dictionary to store counts dynamically
    out_of_unit_emp = {
    field: OutOfUnitEmp.objects.filter(type_name=field,status=True,member__active=True).count() for field in leave_out_of_unit_emp_fields
    }
    # Calculate total sum of all members
    out_of_unit_emp['total'] = sum(out_of_unit_emp.values())
    

    total_leaves =attendance_summary.aggregate(**{field: Sum(field) for field in total_leaves_fields})
    total_cct =attendance_summary.aggregate(**{field: Sum(field) for field in cct_fields})
    total_unauth_absent =attendance_summary.aggregate(**{field: Sum(field) for field in unauth_absent_fields})
    total_other_reason =attendance_summary.aggregate(**{field: Sum(field) for field in other_reason_fields})

    # Calculate the total sum and append it to total_leaves
    total_leaves['total'] = sum(value or 0 for value in total_leaves.values())
    total_cct['total'] = sum(value or 0 for value in total_cct.values())
    total_unauth_absent['total'] = sum(value or 0 for value in total_unauth_absent.values())
    total_other_reason['total'] = sum(value or 0 for value in total_other_reason.values())
    context = {
        'total_posted':total_posted,
        'total_auth':total_auth,
        'toe_auth':toe_auth,
        'ere_auth':ere_auth,
        'total_leaves':total_leaves,
        'total_cct':total_cct,
        'total_out_of_unit_emp':total_out_of_unit_emp,
        'total_ops_depl':total_ops_depl,
        'total_unauth_absent':total_unauth_absent,
        'total_other_reason':total_other_reason,
        'deficiency': total_auth - total_posted,
        'held': total_posted - total_out_of_unit_emp,
        'record': record,
        'combined_total_auth': combined_total_auth,
        'posted': posted,
        'ops_depl':ops_depl,
        'out_of_unit_emp': out_of_unit_emp,
    }
    return render(request,"dashboard/dashboard_admin.html",context)


   
    
#TODO:parade state  
@role_required('dashboard_admin')
def parade_state_admin(request, date=None):
    if date:
        date = datetime.strptime(date, "%Y-%m-%d").date()
    else:
        date = get_custom_today()
        
    # Get role based access
    role = request.user.role
    if role and role.modules.filter(name='dq_admin').exists():
        attendance_summary = AttendanceSummary.objects.filter( date=date,attendance_summary_cart__battalion_approved=True,attendance_summary_cart__adjutant_approved=True)
    else:
        attendance_summary = AttendanceSummary.objects.filter(date=date,attendance_summary_cart__battalion_approved=True,attendance_summary_cart__dq_approved=True,attendance_summary_cart__adjutant_approved=True)
    
    dq_approved = False
    if attendance_summary.filter(attendance_summary_cart__dq_approved=True).exists():
        dq_approved = True
  
    # Dynamically create the aggregate query
    aggregate_query = {field: Sum(field) for field in field_names}

    # Execute the aggregate query
    totals = attendance_summary.aggregate(**aggregate_query)

    # Replace None values with 0
    totals = {key: value or 0 for key, value in totals.items()}
    
    # store everything in one dict keyed by battalion
    battalions = Battalion.objects.all().order_by('sn')
    data_by_battalion = []

    for battalion in battalions:
        records = attendance_summary.filter(attendance_summary_cart__battalion=battalion)
        if records:
            totals_battalion = records.aggregate(**{field: Sum(field) for field in field_names})
            totals_battalion = {key: value or 0 for key, value in totals_battalion.items()}

            data_by_battalion.append({
                "battalion": battalion,
                "totals": totals_battalion,
            })
    # Aggregate auth values
    toe_auth = Company.objects.aggregate(**{field: Sum(field) for field in member_types_fields})
    toe_auth['total'] = sum(value or 0 for value in toe_auth.values())
    ere_auth = Company.objects.aggregate(**{field: Sum(field) for field in ere_member_types_fields})
    ere_auth['total'] = sum(value or 0 for value in ere_auth.values())
    total_auth = toe_auth['total'] + ere_auth['total']
    

    # Calculate combined totals
    combined_total_auth = {}
    for field in member_types_fields:
        toe_value = toe_auth.get(field) or 0
        ere_value = ere_auth.get(f'ere_{field}') or 0
        combined_total_auth[field + '_total'] = toe_value + ere_value

    # Optional: calculate overall total of all combined
    combined_total_auth['grand_total'] = sum(combined_total_auth.values())
    
    attendance_summary_carts = AttendanceSummaryCart.objects.filter(date=date,battalion_approved=True,adjutant_approved=True)
    
    context = {
        'totals': totals,
        'date': date,
        'data_by_battalion': data_by_battalion,        
        'total_auth':total_auth,
        'toe_auth':toe_auth,
        'ere_auth':ere_auth,
        'combined_total_auth': combined_total_auth,
        'dq_approved':dq_approved,
        "attendance_summary_carts":attendance_summary_carts
    }
    
    return render(request,'admin/attendance_table.html',context)
    
@role_required('dq_admin')
def parade_state_submit_dq_admin(request):
    date = get_custom_today()
    attendance_summary_cart = AttendanceSummaryCart.objects.filter(date=date)
    attendance_summary_cart.update(dq_approved=True)
    messages.success(request, "Attendance Submitted Successfully")
    return redirect('parade_state_admin')
        
def parade_state_reject_dq_admin(request):
    date = get_custom_today()
    if request.method != 'POST':
        messages.error(request, "Method Not Allowed")
        return redirect('parade_state_admin')
    else:
        cart_id = request.POST.get('cart_id')
        attendance_summary_cart = AttendanceSummaryCart.objects.get(id=cart_id)
        attendance_summary_cart.adjutant_approved = False
        attendance_summary_cart.save()
        messages.success(request, "Attendance Rejected Successfully")
        return redirect('parade_state_admin')



#list attendance summary
@role_required('dashboard_admin')
def parade_state_list_admin(request): 
    date = request.GET.get('date')  # Get selected date from request
    dates = AttendanceSummaryCart.objects.filter(
            battalion_approved=True,
            dq_approved=True,
            adjutant_approved=True
        ).values_list("date", flat=True).distinct().order_by('-date')
    if date:
        dates = dates.filter(date=date,battalion_approved=True,dq_approved=True,adjutant_approved=True).values_list("date", flat=True).distinct()

    # paginator for dates
    paginator = Paginator(dates, 30)
    page_number = request.GET.get('page')
    dates = paginator.get_page(page_number)
    context = {
        "dates": dates,  # Pass the dates to the template
        "date": date
    }
    
    return render(request, 'admin/list_attendance_summary.html', context)


@role_required('other_admin')
def parade_state_jco_admin(request, date):
    attendance_summary = AttendanceSummary.objects.filter(date=date,attendance_summary_cart__battalion_approved=True,attendance_summary_cart__dq_approved=True,attendance_summary_cart__adjutant_approved=True)
  
    # Dynamically create the aggregate query
    aggregate_query = {field: Sum(field) for field in jco_fields}

    # Execute the aggregate query
    totals = attendance_summary.aggregate(**aggregate_query)

    # Replace None values with 0
    totals = {key: value or 0 for key, value in totals.items()}
    
    # store everything in one dict keyed by battalion
    battalions = Battalion.objects.all().order_by('sn')
    data_by_battalion = []

    for battalion in battalions:
        records = AttendanceSummary.objects.filter(
            attendance_summary_cart__battalion=battalion,
            date=date,
            attendance_summary_cart__battalion_approved=True,
            attendance_summary_cart__dq_approved=True,
            attendance_summary_cart__adjutant_approved=True
        )
        if records:
            totals_battalion = records.aggregate(**{field: Sum(field) for field in jco_fields})
            totals_battalion = {key: value or 0 for key, value in totals_battalion.items()}

            data_by_battalion.append({
                "battalion": battalion,
                "totals": totals_battalion,
            })
    # Aggregate auth values
    toe_auth = Company.objects.aggregate(**{field: Sum(field) for field in member_types_fields})
    toe_auth['total'] = sum(value or 0 for value in toe_auth.values())
    ere_auth = Company.objects.aggregate(**{field: Sum(field) for field in ere_member_types_fields})
    ere_auth['total'] = sum(value or 0 for value in ere_auth.values())
    total_auth = toe_auth['total'] + ere_auth['total']
    

    # Calculate combined totals
    combined_total_auth = {}
    for field in member_types_fields:
        toe_value = toe_auth.get(field) or 0
        ere_value = ere_auth.get(f'ere_{field}') or 0
        combined_total_auth[field + '_total'] = toe_value + ere_value

    # Optional: calculate overall total of all combined
    combined_total_auth['grand_total'] = sum(combined_total_auth.values())
    context = {
        'totals': totals,
        'date': datetime.strptime(date, "%Y-%m-%d").date(),
        'data_by_battalion': data_by_battalion,        
        'total_auth':total_auth,
        'toe_auth':toe_auth,
        'ere_auth':ere_auth,
        'combined_total_auth': combined_total_auth,
    }
    
    return render(request,'admin/parade_state_jco.html',context)


@role_required('other_admin')
def parade_state_offr_admin(request, date):
    attendance_summary = AttendanceSummary.objects.filter(date=date,attendance_summary_cart__battalion_approved=True,attendance_summary_cart__adjutant_approved=True,attendance_summary_cart__dq_approved=True)
    attendance_summary = AttendanceSummaryOffr.objects.filter(attendance_summary__in=attendance_summary)
    # Dynamically create the aggregate query
    aggregate_query = {field: Sum(field) for field in offr_fields}
    # Execute the aggregate query
    totals = attendance_summary.aggregate(**aggregate_query)
    # Replace None values with 0
    totals = {key: value or 0 for key, value in totals.items()}
    # store everything in one dict keyed by battalion
    battalions = Battalion.objects.all().order_by('sn')
    data_by_battalion = []
    for battalion in battalions:
        records = AttendanceSummary.objects.filter(
            attendance_summary_cart__battalion=battalion,
            date=date,
            attendance_summary_cart__battalion_approved=True,
            attendance_summary_cart__adjutant_approved=True,
            attendance_summary_cart__dq_approved=True
        )
        if records:
            records = AttendanceSummaryOffr.objects.filter(attendance_summary__in=records)
            totals_battalion = records.aggregate(**{field: Sum(field) for field in offr_fields})
            totals_battalion = {key: value or 0 for key, value in totals_battalion.items()}
            data_by_battalion.append({
                "battalion": battalion,
                "totals": totals_battalion,
            })
    # Aggregate auth values
    toe_auth = Company.objects.aggregate(**{field: Sum(field) for field in offr_types_fields})
    toe_auth['total'] = sum(value or 0 for value in toe_auth.values())
    ere_auth = Company.objects.aggregate(**{field: Sum(field) for field in ere_offr_types_fields})
    ere_auth['total'] = sum(value or 0 for value in ere_auth.values())
    total_auth = toe_auth['total'] + ere_auth['total']
    # Calculate combined totals
    combined_total_auth = {}
    for field in offr_types_fields:
        toe_value = toe_auth.get(field) or 0
        ere_value = ere_auth.get(f'ere_{field}') or 0
        combined_total_auth[field + '_total'] = toe_value + ere_value

    # Optional: calculate overall total of all combined
    combined_total_auth['grand_total'] = sum(combined_total_auth.values())
    context = {
        'totals': totals,
        'date': datetime.strptime(date, "%Y-%m-%d").date(),
        'data_by_battalion': data_by_battalion, 
        'total_auth':total_auth,
        'toe_auth':toe_auth,
        'ere_auth':ere_auth,
        'combined_total_auth': combined_total_auth,
    }
    
    return render(request,'admin/parade_state_offr.html',context) 


@role_required('other_admin')
def parade_state_battalion_admin(request, date, battalion_id):
    battalion= Battalion.objects.get(id=battalion_id)
    attendance_summary = AttendanceSummary.objects.filter(attendance_summary_cart__battalion=battalion,date=date)
    # Dynamically create the aggregate query
    aggregate_query = {field: Sum(field) for field in field_names}

    # Execute the aggregate query
    totals = attendance_summary.aggregate(**aggregate_query)

    # Replace None values with 0
    totals = {key: value or 0 for key, value in totals.items()}    
    
    context = {
        'records': attendance_summary,
        'totals': totals,
        'date': date,
        'battalion_name': battalion.name,
    }
    return render(request,'admin/view_battalion_attendance_summary.html',context)





@role_required('other_admin')
def parade_state_pdf_admin(request, date):
    attendance_summary = AttendanceSummary.objects.filter(
        date=date,
        attendance_summary_cart__battalion_approved=True,
        attendance_summary_cart__adjutant_approved=True,
        attendance_summary_cart__dq_approved=True
    )

    # Dynamically create the aggregate query
    aggregate_query = {field: Sum(field) for field in field_names}

    # Execute the aggregate query
    totals = attendance_summary.aggregate(**aggregate_query)

    # Replace None values with 0
    totals = {key: value or 0 for key, value in totals.items()}
    
    # store everything in one dict keyed by battalion
    battalions = Battalion.objects.all().order_by('sn')
    data_by_battalion = []

    for battalion in battalions:
        records = AttendanceSummary.objects.filter(
            attendance_summary_cart__battalion=battalion,
            date=date,
            attendance_summary_cart__battalion_approved=True,
            attendance_summary_cart__adjutant_approved=True,
            attendance_summary_cart__dq_approved=True,
        )
        if records:
            totals_battalion = records.aggregate(**{field: Sum(field) for field in field_names})
            totals_battalion = {key: value or 0 for key, value in totals_battalion.items()}

            data_by_battalion.append({
                "battalion": battalion,
                "totals": totals_battalion,
            })
     # Aggregate values
    toe_auth = Company.objects.aggregate(**{field: Sum(field) for field in member_types_fields})
    toe_auth['total'] = sum(value or 0 for value in toe_auth.values())
    ere_auth = Company.objects.aggregate(**{field: Sum(field) for field in ere_member_types_fields})
    ere_auth['total'] = sum(value or 0 for value in ere_auth.values())
    total_auth = toe_auth['total'] + ere_auth['total']
    

    # Calculate combined totals
    combined_total_auth = {}
    for field in member_types_fields:
        toe_value = toe_auth.get(field) or 0
        ere_value = ere_auth.get(f'ere_{field}') or 0
        combined_total_auth[field + '_total'] = toe_value + ere_value

    # Optional: calculate overall total of all combined
    combined_total_auth['grand_total'] = sum(combined_total_auth.values())
    context = {
        'totals': totals,
        'date': datetime.strptime(date, "%Y-%m-%d").strftime('%d-%b-%Y'),
        'data_by_battalion': data_by_battalion,        
        'total_auth':total_auth,
        'toe_auth':toe_auth,
        'ere_auth':ere_auth,
        'combined_total_auth': combined_total_auth,
    }
    # Load the HTML template and render it with context data
    template = get_template('admin/attendance_summary_pdf.html')
    html = template.render(context)

    # Create a response with PDF content type
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = f'inline; filename="manpower_parade_state_{date}.pdf"'

    # Convert HTML to PDF
    pisa_status = pisa.CreatePDF(html, dest=response)

    if pisa_status.err:
        return HttpResponse("Error generating PDF", status=500)
    
    return response


@role_required('other_admin')
def parade_state_jco_pdf_admin(request, date):
    attendance_summary = AttendanceSummary.objects.filter(date=date,attendance_summary_cart__battalion_approved=True,attendance_summary_cart__adjutant_approved=True,attendance_summary_cart__dq_approved=True)
  
    # Dynamically create the aggregate query
    aggregate_query = {field: Sum(field) for field in jco_fields}

    # Execute the aggregate query
    totals = attendance_summary.aggregate(**aggregate_query)

    # Replace None values with 0
    totals = {key: value or 0 for key, value in totals.items()}
    
    # store everything in one dict keyed by battalion
    battalions = Battalion.objects.all().order_by('sn')
    data_by_battalion = []

    for battalion in battalions:
        records = AttendanceSummary.objects.filter(
            attendance_summary_cart__battalion=battalion,
            date=date,
            attendance_summary_cart__battalion_approved=True,
            attendance_summary_cart__dq_approved=True
        )
        if records:
            totals_battalion = records.aggregate(**{field: Sum(field) for field in jco_fields})
            totals_battalion = {key: value or 0 for key, value in totals_battalion.items()}

            data_by_battalion.append({
                "battalion": battalion,
                "totals": totals_battalion,
            })
     # Aggregate values
    toe_auth = Company.objects.aggregate(**{field: Sum(field) for field in member_types_fields})
    toe_auth['total'] = sum(value or 0 for value in toe_auth.values())
    ere_auth = Company.objects.aggregate(**{field: Sum(field) for field in ere_member_types_fields})
    ere_auth['total'] = sum(value or 0 for value in ere_auth.values())
    total_auth = toe_auth['total'] + ere_auth['total']
    

    # Calculate combined totals
    combined_total_auth = {}
    for field in member_types_fields:
        toe_value = toe_auth.get(field) or 0
        ere_value = ere_auth.get(f'ere_{field}') or 0
        combined_total_auth[field + '_total'] = toe_value + ere_value

    # Optional: calculate overall total of all combined
    combined_total_auth['grand_total'] = sum(combined_total_auth.values())
    context = {
        'totals': totals,
        'date': datetime.strptime(date, "%Y-%m-%d").strftime('%d-%b-%Y'),
        'data_by_battalion': data_by_battalion,         
        'total_auth':total_auth,
        'toe_auth':toe_auth,
        'ere_auth':ere_auth,
        'combined_total_auth': combined_total_auth,
    }
    
    # Load the HTML template and render it with context data
    template = get_template('admin/parade_state_jco_pdf.html')
    html = template.render(context)

    # Create a response with PDF content type
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = f'inline; filename="jco_manpower_parade_state_{date}.pdf"'

    # Convert HTML to PDF
    pisa_status = pisa.CreatePDF(html, dest=response)

    if pisa_status.err:
        return HttpResponse("Error generating PDF", status=500)
    
    return response


@role_required('other_admin')
def parade_state_offr_pdf_admin(request, date):
    attendance_summary = AttendanceSummary.objects.filter(date=date,attendance_summary_cart__battalion_approved=True,attendance_summary_cart__adjutant_approved=True,attendance_summary_cart__dq_approved=True)
    attendance_summary = AttendanceSummaryOffr.objects.filter(attendance_summary__in=attendance_summary)
    # Dynamically create the aggregate query
    aggregate_query = {field: Sum(field) for field in offr_fields}
    # Execute the aggregate query
    totals = attendance_summary.aggregate(**aggregate_query)
    # Replace None values with 0
    totals = {key: value or 0 for key, value in totals.items()}
    # store everything in one dict keyed by battalion
    battalions = Battalion.objects.all().order_by('sn')
    data_by_battalion = []
    for battalion in battalions:
        records = AttendanceSummary.objects.filter(
            attendance_summary_cart__battalion=battalion,
            date=date,
            attendance_summary_cart__battalion_approved=True,
            attendance_summary_cart__adjutant_approved=True,
            attendance_summary_cart__dq_approved=True
        )
        if records:
            records = AttendanceSummaryOffr.objects.filter(attendance_summary__in=records)
            totals_battalion = records.aggregate(**{field: Sum(field) for field in offr_fields})
            totals_battalion = {key: value or 0 for key, value in totals_battalion.items()}
            data_by_battalion.append({
                "battalion": battalion,
                "totals": totals_battalion,
            })
    # Aggregate values
    toe_auth = Company.objects.aggregate(**{field: Sum(field) for field in offr_types_fields})
    toe_auth['total'] = sum(value or 0 for value in toe_auth.values())
    ere_auth = Company.objects.aggregate(**{field: Sum(field) for field in ere_offr_types_fields})
    ere_auth['total'] = sum(value or 0 for value in ere_auth.values())
    total_auth = toe_auth['total'] + ere_auth['total']
    # Calculate combined totals
    combined_total_auth = {}
    for field in offr_types_fields:
        toe_value = toe_auth.get(field) or 0
        ere_value = ere_auth.get(f'ere_{field}') or 0
        combined_total_auth[field + '_total'] = toe_value + ere_value

    # Optional: calculate overall total of all combined
    combined_total_auth['grand_total'] = sum(combined_total_auth.values())
    context = {
        'totals': totals,
        'date': datetime.strptime(date, "%Y-%m-%d").strftime('%d-%b-%Y'),
        'data_by_battalion': data_by_battalion,         
        'total_auth':total_auth,
        'toe_auth':toe_auth,
        'ere_auth':ere_auth,
        'combined_total_auth': combined_total_auth,
    }
    
    # Load the HTML template and render it with context data
    template = get_template('admin/parade_state_offr_pdf.html')
    html = template.render(context)

    # Create a response with PDF content type
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = f'inline; filename="offr_manpower_parade_state_{date}.pdf"'

    # Convert HTML to PDF
    pisa_status = pisa.CreatePDF(html, dest=response)

    if pisa_status.err:
        return HttpResponse("Error generating PDF", status=500)
    
    return response




# Attendance Member
@role_required('dashboard_admin')
def attendance_member_list_admin(request, date, company_id=None):
    try:
        # Convert string to date object
        date = datetime.strptime(date, "%Y-%m-%d").date()
    except ValueError:
        messages.error(request, "Invalid date format. Please use YYYY-MM-DD.")
        return redirect('companyDashboard')

    # Get attendance records
    attendance_records = AttendanceMember.objects.filter(
        attendance__attendance_date=date
    ).select_related('attendance', 'member')

    # Get leave details for absent members
    leave_records = Leave.objects.filter(
        date=date  # Assuming 'created_at' stores leave request date
    ).select_related('member', 'leave_type')
    if company_id:
        company = Company.objects.get(id=company_id)
        attendance_records = attendance_records.filter(member__company=company)
        leave_records = leave_records.filter(member__company=company)
    search_query = request.GET.get("search", "")  # Get search query
    if search_query:
        # Use Q objects for OR logic
        attendance_records = attendance_records.filter(
            Q(member__army_no__icontains=search_query) |
            Q(member__mobile_no__icontains=search_query) |
            Q(member__name__icontains=search_query)
        ) 

    context = {
        'attendance_records': attendance_records,
        'leave_records': leave_records,
        'date': date,
        'search_query': search_query
    }

    return render(request, 'dashboard/attendance_report.html', context)

@role_required('dashboard_admin')
def absent_list_admin(request,member_type):
    date = get_custom_today()
    # Get attendance records
    attendance_records = AttendanceMember.objects.filter(
        attendance__attendance_date=date,
        status=False
    ).select_related('attendance', 'member')

    # Get leave details for present members
    leave_records = Leave.objects.filter(
        date=date 
    ).select_related('member', 'leave_type')
    
    if member_type != 'total':
        attendance_records = attendance_records.filter(member__member_type__name=member_type)
        leave_records = leave_records.filter(member__member_type__name=member_type)
        
    context = {
        'attendance_records': attendance_records,
        'leave_records': leave_records,
        'date': date,
    }

    return render(request, 'dashboard/attendance_report.html', context)

@role_required('dashboard_admin')
def present_list_admin(request,member_type):
    date = get_custom_today()
    # Get attendance records
    attendance_records = AttendanceMember.objects.filter(
        attendance__attendance_date=date,
        status=True
    ).select_related('attendance', 'member')

    # Get leave details for absent members
    leave_records = Leave.objects.filter(
        date=date 
    ).select_related('member', 'leave_type')
    if member_type != 'total':
        attendance_records = attendance_records.filter(member__member_type__name=member_type)
        leave_records = leave_records.filter(member__member_type__name=member_type)
    context = {
        'attendance_records': attendance_records,
        'leave_records': leave_records,
        'date': date,
    }

    return render(request, 'dashboard/attendance_report.html', context)

@role_required('dashboard_admin')
def leave_list_admin(request,type="total"):
    date = get_custom_today()
    # Get attendance records
    attendance_records = AttendanceMember.objects.filter(
        attendance__attendance_date=date,
        status=False
    ).select_related('attendance', 'member')

    # Get leave details for present members
    leave_records = Leave.objects.filter(
        date=date 
    ).select_related('member', 'leave_type')
    if type == 'total_leaves':
    #get leave attendance records
        total_leaves_fields = [
            "p_leave", "c_leave", "r_leave", "w_leave", "j_leave"
        ]
        leave_attendance_records = []
        for i in attendance_records:
            for j in leave_records:
                if i.member == j.member and j.leave_type.name in total_leaves_fields:
                    leave_attendance_records.append(i)
    elif type == 'total_cct':
        #get leave attendance records
        total_cct_fields = [
            "course_leave", "cadre_leave", "trg"
        ]
        leave_attendance_records = []
        for i in attendance_records:
            for j in leave_records:
                if i.member == j.member and j.leave_type.name in total_cct_fields:
                    leave_attendance_records.append(i)
    elif type == 'total_out_of_unit_emp':
        #get leave attendance records
        total_out_of_unit_emp_fields = [
        "ere", "att", "t_duty", "msn_okp", "stmk", "demov"
        ]
        leave_attendance_records = []
        for i in attendance_records:
            for j in leave_records:
                if i.member == j.member and j.leave_type.name in total_out_of_unit_emp_fields:
                    leave_attendance_records.append(i)
    elif type == 'total_unauth_absent':
        #get leave attendance records
        total_unauth_absent_fields = [
            "awol","osl"
        ]
        leave_attendance_records = []
        for i in attendance_records:
            for j in leave_records:
                if i.member == j.member and j.leave_type.name in total_unauth_absent_fields:
                    leave_attendance_records.append(i)
    elif type == 'total_other_reason':
        #get leave attendance records
        total_other_reason_fields = [
            "cmh","line_sick","misc", "iacp_duty"
        ]
        leave_attendance_records = []
        for i in attendance_records:
            for j in leave_records:
                if i.member == j.member and j.leave_type.name in total_other_reason_fields:
                    leave_attendance_records.append(i)
    elif type == 'total':
        leave_attendance_records = []
        for i in attendance_records:
            for j in leave_records:
                if i.member == j.member:
                    leave_attendance_records.append(i)
    else:
        leave_attendance_records = []
        for i in attendance_records:
            for j in leave_records:
                if i.member == j.member and j.leave_type.name == type:
                    leave_attendance_records.append(i)

        
    context = {
        'attendance_records': leave_attendance_records,
        'leave_records': leave_records,
        'date': date,
    }
    return render(request,'dashboard/attendance_report.html',context)









#TODO:Battalion
@role_required('read_battalion_admin')
def read_battalion_admin(request):
    context = {
        'battalionTable':Battalion.objects.all(),    }
    return render(request,'admin/battalion_table.html',context)
   
@role_required('create_battalion_admin')
def create_battalion_admin(request):
    if request.method != "POST":
        messages.error(request, "Method Not Allowed")
        return redirect('create_battalion_admin')
    else:
        name = request.POST.get('name')
        # Check if all fields are provided
        if not all([name]):
            messages.error(request, "All fields are required")
            return redirect('create_battalion_admin')
        try:
            # Create the battalion entry
            battalion = Battalion.objects.create(name=name)
            messages.success(request, "Battalion added successfully")
            return redirect('create_battalion_admin')
        except Exception as e:
            messages.error(request, "An error occurred")
            return redirect('create_battalion_admin')

@role_required('update_battalion_admin')  
def update_battalion_admin(request,id):
    battalion = Battalion.objects.get(id=id)
    if request.method == 'POST':
        name = request.POST.get('name')
        # Check if all fields are provided
        if not all([name]):
            messages.error(request, "All fields are required")
            return redirect('read_battalion_admin')
        try:
            # Update the battalion entry
            battalion.name = name
            battalion.save()
            messages.success(request, "Battalion updated successfully")
            return redirect('read_battalion_admin')
        except Exception as e:
            messages.error(request, "An error occurred")
            return redirect('read_battalion_admin')
    context = {
        'battalion':battalion,
        'users':User.objects.filter(role='battalion')
    }
    return render(request,'admin/edit_battalion_form.html',context)

@role_required('delete_battalion_admin')
def delete_battalion_admin(request,id):
    battalion = Battalion.objects.get(id=id)
    battalion.delete()
    messages.success(request, "Battalion deleted successfully")
    return redirect('read_battalion_admin')



#TODO:Company
@role_required('read_company_admin')
def read_company_admin(request):
    context = {
        'companyTable':Company.objects.all() 
    }
    return render(request,'admin/company_table.html',context)
   

@role_required('create_company_admin')
def create_company_admin(request):
    if request.method == "POST":
        name = request.POST.get('name')
        user_id = request.POST.get('user')
        battalion_id = request.POST.get('battalion')
        
        #member type
        offr = request.POST.get('offr')
        mwo = request.POST.get('mwo')
        smo = request.POST.get('smo')
        wo = request.POST.get('wo')
        sgt = request.POST.get('sgt')
        cpl = request.POST.get('cpl')
        lcpl = request.POST.get('lcpl')
        snk = request.POST.get('snk')
        clk = request.POST.get('clk')
        tailor = request.POST.get('tailor')
        e_br = request.POST.get('e_br')
        ck_mm = request.POST.get('ck_mm')
        carp = request.POST.get('carp')
        rco = request.POST.get('rco')
        nc_e = request.POST.get('nc_e')
        nc_u = request.POST.get('nc_u')
        att = request.POST.get('att')
        #ere member type
        ere_offr = request.POST.get('ere_offr')
        ere_mwo = request.POST.get('ere_mwo')
        ere_smo = request.POST.get('ere_smo')
        ere_wo = request.POST.get('ere_wo')
        ere_sgt = request.POST.get('ere_sgt')
        ere_cpl = request.POST.get('ere_cpl')
        ere_lcpl = request.POST.get('ere_lcpl')
        ere_snk = request.POST.get('ere_snk')
        ere_clk = request.POST.get('ere_clk')
        ere_tailor = request.POST.get('ere_tailor')
        ere_e_br = request.POST.get('ere_e_br')
        ere_ck_mm = request.POST.get('ere_ck_mm')
        ere_carp = request.POST.get('ere_carp')
        ere_rco = request.POST.get('ere_rco')
        ere_nc_e = request.POST.get('ere_nc_e')
        ere_nc_u = request.POST.get('ere_nc_u')
        ere_att = request.POST.get('ere_att')
        
        #for offr type
        g = request.POST.get('g')
        lg = request.POST.get('lg')
        mg = request.POST.get('mg')
        bg = request.POST.get('bg')
        c = request.POST.get('c')
        lc = request.POST.get('lc')
        m = request.POST.get('m')
        cp = request.POST.get('cp')
        l = request.POST.get('l')
        sl = request.POST.get('sl')
        #ere
        ere_g = request.POST.get('ere_g')
        ere_lg = request.POST.get('ere_lg')
        ere_mg = request.POST.get('ere_mg')
        ere_bg = request.POST.get('ere_bg')
        ere_c = request.POST.get('ere_c')
        ere_lc = request.POST.get('ere_lc')
        ere_m = request.POST.get('ere_m')
        ere_cp = request.POST.get('ere_cp')
        ere_l = request.POST.get('ere_l')
        ere_sl = request.POST.get('ere_sl')
        
        
        # Check if all fields are provided
        if not all([name, battalion_id]):
            messages.error(request, "Name and Battalion fields are required")
            return redirect('addCompanyForm')
        try:
            # Get the battalion
            battalion= Battalion.objects.get(id=battalion_id)
            # Create the battalion entry
            company = Company.objects.create(
                battalion=battalion, name=name,offr=offr,mwo=mwo,smo=smo,wo=wo,sgt=sgt,cpl=cpl,lcpl=lcpl,snk=snk,clk=clk, tailor=tailor,e_br=e_br,ck_mm=ck_mm,carp=carp,rco=rco,nc_e=nc_e,nc_u=nc_u,att=att,ere_offr=ere_offr,ere_mwo=ere_mwo,ere_smo=ere_smo,ere_wo=ere_wo,ere_sgt=ere_sgt,ere_cpl=ere_cpl,ere_lcpl=ere_lcpl,ere_snk=ere_snk,ere_clk=ere_clk,ere_tailor=ere_tailor,ere_e_br=ere_e_br,ere_ck_mm=ere_ck_mm,ere_carp=ere_carp,ere_rco=ere_rco,ere_nc_e=ere_nc_e,ere_nc_u=ere_nc_u, ere_att= ere_att,
                #for offr type
                g=g,lg=lg,mg=mg,bg=bg,c=c,lc=lc,m=m,cp=cp,l=l,sl=sl,ere_g=ere_g,ere_lg=ere_lg,ere_mg=ere_mg,ere_bg=ere_bg,ere_c=ere_c,ere_lc=ere_lc,ere_m=ere_m,ere_cp=ere_cp,ere_l=ere_l,ere_sl=ere_sl
            )
            if user_id:
                # Get the user
                user = User.objects.get(id=user_id)
                company.user = user
                company.save()
            messages.success(request, "Company added successfully")
            return redirect('create_company_admin')
        except Exception as e:
            print("error for add company",e)
            messages.error(request, "An error occurred")
            return redirect('create_company_admin')
    context = {
        'battalions':Battalion.objects.all(),
    }
    return render(request,'add_company_form.html',context)

@role_required('update_company_admin')
def update_company_admin(request,id):
    company = Company.objects.get(id=id)
    if request.method == 'POST':
        name = request.POST.get('name')
        battalion_id = request.POST.get('battalion')

        #member type
        offr = request.POST.get('offr')
        mwo = request.POST.get('mwo')
        smo = request.POST.get('smo')
        wo = request.POST.get('wo')
        sgt = request.POST.get('sgt')
        cpl = request.POST.get('cpl')
        lcpl = request.POST.get('lcpl')
        snk = request.POST.get('snk')
        clk = request.POST.get('clk')
        tailor = request.POST.get('tailor')
        e_br = request.POST.get('e_br')
        ck_mm = request.POST.get('ck_mm')
        carp = request.POST.get('carp')
        rco = request.POST.get('rco')
        nc_e = request.POST.get('nc_e')
        nc_u = request.POST.get('nc_u')
        att = request.POST.get('att')
        #ere member type
        ere_offr = request.POST.get('ere_offr')
        ere_mwo = request.POST.get('ere_mwo')
        ere_smo = request.POST.get('ere_smo')
        ere_wo = request.POST.get('ere_wo')
        ere_sgt = request.POST.get('ere_sgt')
        ere_cpl = request.POST.get('ere_cpl')
        ere_lcpl = request.POST.get('ere_lcpl')
        ere_snk = request.POST.get('ere_snk')
        ere_clk = request.POST.get('ere_clk')
        ere_tailor = request.POST.get('ere_tailor')
        ere_e_br = request.POST.get('ere_e_br')
        ere_ck_mm = request.POST.get('ere_ck_mm')
        ere_carp = request.POST.get('ere_carp')
        ere_rco = request.POST.get('ere_rco')
        ere_nc_e = request.POST.get('ere_nc_e')
        ere_nc_u = request.POST.get('ere_nc_u')
        ere_att = request.POST.get('ere_att')
        
        #for offr type
        g = request.POST.get('g')
        lg = request.POST.get('lg')
        mg = request.POST.get('mg')
        bg = request.POST.get('bg')
        c = request.POST.get('c')
        lc = request.POST.get('lc')
        m = request.POST.get('m')
        cp = request.POST.get('cp')
        l = request.POST.get('l')
        sl = request.POST.get('sl')
        #ere
        ere_g = request.POST.get('ere_g')
        ere_lg = request.POST.get('ere_lg')
        ere_mg = request.POST.get('ere_mg')
        ere_bg = request.POST.get('ere_bg')
        ere_c = request.POST.get('ere_c')
        ere_lc = request.POST.get('ere_lc')
        ere_m = request.POST.get('ere_m')
        ere_cp = request.POST.get('ere_cp')
        ere_l = request.POST.get('ere_l')
        ere_sl = request.POST.get('ere_sl')
        
        # Check if all fields are provided
        if not all([name, battalion_id]):
            messages.error(request, "Name and Battalion fields are required")
            return redirect('read_company_admin')
        try:
            # Get the battalion
            battalion = Battalion.objects.get(id=battalion_id)
            # Update the battalion entry
            company.name = name
            company.battalion = battalion
            company.offr = offr
            company.mwo = mwo
            company.smo = smo
            company.wo = wo
            company.sgt = sgt
            company.cpl = cpl
            company.lcpl = lcpl
            company.snk = snk
            company.clk = clk
            company.ck_mm = ck_mm
            company.tailor = tailor
            company.e_br = e_br
            company.carp = carp
            company.rco = rco
            company.nc_e = nc_e
            company.nc_u = nc_u
            company.att = att
            company.ere_offr = ere_offr
            company.ere_mwo = ere_mwo
            company.ere_smo = ere_smo
            company.ere_wo = ere_wo
            company.ere_sgt = ere_sgt
            company.ere_cpl = ere_cpl
            company.ere_lcpl = ere_lcpl
            company.ere_snk = ere_snk
            company.ere_clk = ere_clk
            company.ere_tailor = ere_tailor
            company.ere_e_br = ere_e_br
            company.ere_ck_mm = ere_ck_mm
            company.ere_carp = ere_carp
            company.ere_rco = ere_rco
            company.ere_nc_e = ere_nc_e
            company.ere_nc_u = ere_nc_u
            company.ere_att = ere_att
            
            #for offr type
            company.g = g
            company.lg = lg
            company.mg = mg
            company.bg = bg
            company.c = c
            company.lc = lc
            company.m = m
            company.cp = cp
            company.l = l
            company.sl = sl
            #for ere
            company.ere_g = ere_g
            company.ere_lg = ere_lg
            company.ere_mg = ere_mg
            company.ere_bg = ere_bg
            company.ere_c = ere_c
            company.ere_lc = ere_lc
            company.ere_m = ere_m
            company.ere_cp = ere_cp
            company.ere_l = ere_l
            company.ere_sl = ere_sl
            company.save()

            messages.success(request, "Company updated successfully")
            return redirect('read_company_admin')
        except Exception as e:
            print("error for edit company",e)
            messages.error(request, "An error occurred")
            return redirect('read_company_admin')
    context = {
        'company':company,
        'battalions':Battalion.objects.all()
    }
    return render(request,'admin/edit_company_form.html',context)
 
@role_required('delete_company_admin')
def delete_company_admin(request,id):
    try:
        company = Company.objects.get(id=id)
        company.delete()
        messages.success(request, "Company deleted successfully")
        return redirect('read_company_admin')
    except Exception as e:
        messages.error(request, "An error occurred")
        return redirect('read_company_admin')
 
 
 
 
 
#TODO:Member  
@role_required('create_member_admin')
def create_member_admin(request):
    if request.method == "POST":
        name = request.POST.get('name')
        army_no = request.POST.get('army_no')
        rank_id = request.POST.get('rank')
        apartment_id = request.POST.get('apartment')
        mobile_no = request.POST.get('mobile_no')
        short_name = request.POST.get('short_name')
        picture = request.FILES.get('picture') if request.FILES.get('picture') else None
        company_id = request.POST.get('company')
        # Check if all fields are provided
        if not all([name, army_no, rank_id, apartment_id, mobile_no, company_id,short_name]):
            messages.error(request, "All fields are required")
            return redirect('create_member_admin')
        # Check if the army_no is valid
        if len(mobile_no) != 11 or not mobile_no.startswith("01") or not mobile_no.isdigit():
            messages.error(request, "Mobile number must be exactly 11 digits and start with 01")
            return redirect('create_member_admin')
        # Check if the email is already in use
        if User.objects.filter(email=army_no).exists():
            messages.error(request, "Army No already in use")
            return redirect('create_member_admin')
        try:
            # Get the company
            company = Company.objects.get(id=company_id)
            # Get the other
            rank = Rank.objects.get(id=rank_id)
            apartment = Apartment.objects.get(id=apartment_id)
            # Create the user
            user = User.objects.create_user(email=army_no, password=mobile_no)
            user.role = Role.objects.get(h_name='member')
            if picture:
                user.picture = picture
            user.name = name
            user.army_no = army_no
            user.rank = rank
            user.mobile_no = mobile_no
            user.save()
            # Create the Member entry
            Member.objects.create(user=user, company=company, member_type=rank.memberType, rank=rank, apartment=apartment, name=name, army_no=army_no, mobile_no=mobile_no, short_name=short_name, picture=picture)
            messages.success(request, "Member added successfully")
            return redirect('create_member_admin')

        except Company.DoesNotExist:
            messages.error(request, "Invalid company ID")
            return redirect('create_member_admin')

        except Exception as e:messages.error(request, "An error occurred")
        return redirect('create_member_admin')

    context = {
        'battalions':Battalion.objects.all(),
        'member_statuses':MemberStatus.objects.all(),
        'apartments':Apartment.objects.all() 
    }
    return render(request,'admin/add_member_form.html',context)

@role_required('update_member_admin')
def update_member_admin(request,id):
    member = Member.objects.get(id=id)
    if request.method == 'POST':
        name = request.POST.get('name')
        rank_id = request.POST.get('rank')
        apartment_id = request.POST.get('apartment')
        mobile_no = request.POST.get('mobile_no')
        short_name = request.POST.get('short_name')
        picture = request.FILES.get('picture')
        company_id = request.POST.get('company')
        member_status = request.POST.get('member_status')
        # Check if all fields are provided
        if not all([name, rank_id, apartment_id, mobile_no, company_id, short_name]):
            messages.error(request, "All fields are required")
            return redirect('update_member_admin', id=id)
        try:
            # Get the company
            company = Company.objects.get(id=company_id)
            # Get the other
            rank = Rank.objects.get(id=rank_id)
            apartment = Apartment.objects.get(id=apartment_id)
            # Update the Member entry
            member.user.name = name
            member.user.rank = rank
            member.user.mobile_no = mobile_no
            user_update_fields = ['name', 'rank', 'mobile_no']
            if picture:
                member.user.picture = picture
                user_update_fields.append('picture')
            member.user.save(update_fields=user_update_fields)
            member.company = company
            member.name = name
            member.member_type = rank.memberType
            member.rank = rank
            member.apartment = apartment
            member.mobile_no = mobile_no
            member.short_name = short_name
            if picture:
                member.picture = picture
            member.save()
            messages.success(request, "Member updated successfully")
            return redirect("read_member")

        except Company.DoesNotExist:
            messages.error(request, "Invalid company ID")
            return redirect("read_member")
    
    context = {
        'member':member,
        'member_statuses':MemberStatus.objects.all(),
        'ranks':Rank.objects.all(),
        'apartments':Apartment.objects.all(),
        'battalions':Battalion.objects.all(),
        'companies':Company.objects.all()
    }
    return render(request,'admin/edit_member_form.html',context)

@login_required
def delete_member(request,id):
    role = request.user.role
    if role and role.modules.filter(name='delete_member_admin').exists():
        pass
    elif role and role.modules.filter(name='delete_member_battalion').exists():
        companies = request.user.battalion.companies.all()
        members = Member.objects.filter(Q(company__in=companies)|Q(p_company__in=companies), active=True, id=id).exists()
        if members:
            pass
        else:
            messages.error(request, "You don't have permission to delete this member.")
            return redirect("read_member")
    elif role and role.modules.filter(name='delete_member_company').exists():
        company=request.user.company
        members = Member.objects.filter(Q(company=company)|Q(p_company=company), active=True).exists()
        if members:
            pass
        else:
            messages.error(request, "You don't have permission to delete this member.")
            return redirect("read_member")
    else:
        messages.error(request, "You don't have permission to view this page.")
        return render(request, 'others/no_permission.html')
    member = Member.objects.get(id=id)
    member.delete()
    member.user.delete()
    messages.success(request, "Member deleted successfully")
    return redirect("read_member")


@login_required
def read_member(request, member_type="total"):
    role = request.user.role
    if role and role.modules.filter(name='read_member_admin').exists():
        members = Member.objects.filter(active=True).order_by('company__battalion__sn','company__sn','rank')
    elif role and role.modules.filter(name='read_member_battalion').exists():
        companies = request.user.battalion.companies.all()
        members = Member.objects.filter(Q(company__in=companies)|Q(p_company__in=companies), active=True).select_related( 'rank', 'apartment').order_by('rank')
    elif role and role.modules.filter(name='read_member_company').exists():
        company=request.user.company
        members = Member.objects.filter(Q(company=company)|Q(p_company=company), active=True).select_related( 'rank', 'apartment').order_by('rank')
    else:
        messages.error(request, "You don't have permission to view this page.")
        return render(request, 'others/no_permission.html')

    search_query = request.GET.get("search", "")  # Get search query
    if member_type != "total":
        members = members.filter(member_type__name=member_type)

    battalion_query = request.GET.get("battalion_query")
    if battalion_query:
        battalion = Battalion.objects.get(id=battalion_query)
        members = members.filter(company__battalion=battalion)

    company_query = request.GET.get("company_query")
    if company_query:
        company = Company.objects.get(id=company_query)
        members = members.filter(company=company)
        
    rank_query = request.GET.get("rank_query")
    if rank_query:
        rank = Rank.objects.get(id=rank_query)
        members = members.filter(rank=rank)
    
    member_status_query = request.GET.get("member_status_query")
    if member_status_query:
        member_status = MemberStatus.objects.get(id=member_status_query)
        members = members.filter(rank__member_status=member_status)
    
    if search_query:
        # Use Q objects for OR logic
        members = members.filter(
            Q(army_no__icontains=search_query) |
            Q(mobile_no__icontains=search_query) |
            Q(name__icontains=search_query)
        ) 

    paginator = Paginator(members, 50)  # 10 members per page
    page_number = request.GET.get("page")   
    members_page = paginator.get_page(page_number)
    
    movementType = [(key, value) for key, value in MovementOrder.CHOICE_LIST]
    
    
    # get the current page number with query string
    query_dict = request.GET.copy()
    if 'page' in query_dict:
        query_dict.pop('page')
    query_string = query_dict.urlencode()
    
    context = {
        "memberTable": members_page,
        "search_query": search_query,  # Pass search query to template
        "movementType": movementType,
        "battalions": Battalion.objects.all(),
        "companies": Company.objects.all(),
        "member_statuses": MemberStatus.objects.all(),
        "ranks": Rank.objects.all(),
        #query
        "battalion_query": int(battalion_query or 0),
        "company_query": int(company_query or 0),
        "rank_query": int(rank_query or 0),
        "member_status_query": int(member_status_query or 0),
        
        "query_string": query_string,
        "member_type": member_type
    }
    
    return render(request, "admin/member_table.html", context)


def read_deactivated_member(request, member_type="total"):
    role = request.user.role
    if role and role.modules.filter(name='read_member_admin').exists():
        members = Member.objects.filter(active=False).order_by('company__battalion__sn','company__sn','rank')
    elif role and role.modules.filter(name='read_member_battalion').exists():
        companies = request.user.battalion.companies.all()
        members = Member.objects.filter(Q(company__in=companies)|Q(p_company__in=companies), active=False).select_related( 'rank', 'apartment').order_by('rank')
    elif role and role.modules.filter(name='read_member_company').exists():
        company=request.user.company
        members = Member.objects.filter(Q(company=company)|Q(p_company=company), active=False).select_related( 'rank', 'apartment').order_by('rank')
    else:
        messages.error(request, "You don't have permission to view this page.")
        return render(request, 'others/no_permission.html')


    # Get search query
    search_query = request.GET.get("search", "")
    
    if member_type != "total":
        members = members.filter(member_type__name=member_type)

    battalion_query = request.GET.get("battalion_query")
    if battalion_query:
        battalion = Battalion.objects.get(id=battalion_query)
        members = members.filter(company__battalion=battalion)

    company_query = request.GET.get("company_query")
    if company_query:
        company = Company.objects.get(id=company_query)
        members = members.filter(company=company)
        
    rank_query = request.GET.get("rank_query")
    if rank_query:
        rank = Rank.objects.get(id=rank_query)
        members = members.filter(rank=rank)
    
    member_type_query = request.GET.get("member_type_query")
    if member_type_query:
        member_type = MemberType.objects.get(id=member_type_query)
        members = members.filter(member_type=member_type)
    
    if search_query:
        # Use Q objects for OR logic
        members = members.filter(
            Q(army_no__icontains=search_query) |
            Q(mobile_no__icontains=search_query) |
            Q(name__icontains=search_query)
        ) 

    paginator = Paginator(members, 50)  # 10 members per page
    page_number = request.GET.get("page")   
    members_page = paginator.get_page(page_number)
    
    movementType = [(key, value) for key, value in MovementOrder.CHOICE_LIST]
    
    
    # get the current page number with query string
    query_dict = request.GET.copy()
    if 'page' in query_dict:
        query_dict.pop('page')
    query_string = query_dict.urlencode()
    
    context = {
        "memberTable": members_page,
        "search_query": search_query,  # Pass search query to template
        "movementType": movementType,
        "battalions": Battalion.objects.all(),
        "companies": Company.objects.all(),
        "member_status": MemberStatus.objects.all(),
        #query
        "battalion_query": int(battalion_query or 0),
        "company_query": int(company_query or 0),
        "rank_query": int(rank_query or 0),
        "member_type_query": int(member_type_query or 0),
        "query_string": query_string,
        "deactivate": True,
        "member_type": member_type
    }
    return render(request, "admin/member_table.html", context)

def reset_password_member(request,id):
    role = request.user.role
    if role and role.modules.filter(name='reset_password_member_admin').exists():
        pass
    elif role and role.modules.filter(name='reset_password_member_battalion').exists():
        companies = request.user.battalion.companies.all()
        members = Member.objects.filter(Q(company__in=companies)|Q(p_company__in=companies), active=True, id=id).exists()
        if members:
            pass
        else:
            messages.error(request, "You don't have permission to reset_password this member.")
            return redirect("read_member")
    elif role and role.modules.filter(name='reset_password_member_company').exists():
        company=request.user.company
        members = Member.objects.filter(Q(company=company)|Q(p_company=company), active=True).exists()
        if members:
            pass
        else:
            messages.error(request, "You don't have permission to reset_password this member.")
            return redirect("read_member")
    else:
        messages.error(request, "You don't have permission to view this page.")
        return render(request, 'others/no_permission.html')
    
    member = Member.objects.get(id=id)
    member.user.email = member.army_no
    member.user.set_password(member.mobile_no)
    member.user.save()
    messages.success(request, "Password reset successfully")
    return redirect("read_member")

def deactivate_member(request,id):
    role = request.user.role
    if role and role.modules.filter(name='deactivate_member_admin').exists():
        pass
    elif role and role.modules.filter(name='deactivate_member_battalion').exists():
        companies = request.user.battalion.companies.all()
        members = Member.objects.filter(Q(company__in=companies)|Q(p_company__in=companies), id=id).exists()
        print("pass")
        if members:
            pass
        else:
            messages.error(request, "You don't have permission to deactivate this member.")
            return redirect("read_member")
    elif role and role.modules.filter(name='deactivate_member_company').exists():
        company=request.user.company
        members = Member.objects.filter(Q(company=company)|Q(p_company=company)).exists()
        if members:
            pass
        else:
            messages.error(request, "You don't have permission to deactivate this member.")
            return redirect("read_member")
    else:
        messages.error(request, "You don't have permission to view this page.")
        return render(request, 'others/no_permission.html')
    
    
    member = Member.objects.get(id=id)
    type = request.POST.get('type')
    reason = request.POST.get('reason')
    
    if member.active:
        # all fields are required
        if not all([type]):
            messages.error(request, "All fields are required")
            return redirect('read_member')
        member.user.is_active = False
        member.user.save()
        # Deactivate the member
        member.active = False
        member.save()
        # Create a MovementOrder entry
        try:
            MovementOrder.objects.create(member=member, movement_type=type,show_movement_type=type, reason=reason, status='out')
            print("pass")
            messages.success(request, "Member deactivated successfully")
        except Exception as e:
            messages.error(request, "An error occurred")
    else:
        # all fields are required
        if not all([reason]):
            messages.error(request, "All fields are required")
            return redirect('read_memberAdmin')
        member.user.is_active = True
        member.user.save()
        # Activate the member
        member.active = True
        member.save()
        # create a MovementOrder entry
        try:
            MovementOrder.objects.create(member=member, movement_type=None, reason=reason, status='in')
            messages.success(request, "Member activated successfully")
            return redirect("read_deactivated_member")
        except Exception as e:
            messages.error(request, "An error occurred")
        
    return redirect("read_member")













# TODO:user
@role_required('read_user_admin')
def read_user_admin(request):
    roles = Role.objects.all().exclude(h_name='member')  # Exclude 'member' role
    # Get all battalions, member types, and apartments
    battalions = Battalion.objects.all()
    companies = Company.objects.all()
    member_statuses = MemberStatus.objects.all()
    apartments = Apartment.objects.all()
    userTable = User.objects.exclude(role__h_name='member').order_by('-role','battalion__sn','company__sn','rank')
    
    battalion_query = request.GET.get("battalion_query")
    if battalion_query:
        battalion = Battalion.objects.get(id=battalion_query)
        userTable = userTable.filter(battalion=battalion)

    company_query = request.GET.get("company_query")
    if company_query:
        company = Company.objects.get(id=company_query)
        userTable = userTable.filter(company=company)
        
    role_query = request.GET.get("role_query")
    if role_query:
        role = Role.objects.get(id=role_query)
        userTable = userTable.filter(role=role)
        
    search_query = request.GET.get("search", "")  # Get search query
    if search_query:
        # Use Q objects for OR logic
        userTable = userTable.filter(
            Q(name__icontains=search_query) |
            Q(email__icontains=search_query) |
            Q(mobile_no__icontains=search_query) |
            Q(army_no__icontains=search_query)
        ) 

    paginator = Paginator(userTable, 20)  # 20 users per page
    page_number = request.GET.get("page")   
    userTable = paginator.get_page(page_number)
    
    
    # get the current page number with query string
    query_dict = request.GET.copy()
    if 'page' in query_dict:
        query_dict.pop('page')
    query_string = query_dict.urlencode()
    # Filter out 'member' role and keep the name-value pairs
    context = {
        "userTable":userTable,
        "roles":roles,
        "battalions":battalions,
        "companies":companies,
        "member_statuses":member_statuses,
        "apartments":apartments,
        "search_query": search_query,
        #query
        "battalion_query": int(battalion_query or 0),
        "company_query": int(company_query or 0),
        "role_query": int(role_query or 0),
        "query_string": query_string
    }
    return render(request,'admin/user_table.html',context)

@role_required('create_user_admin')
def create_user_admin(request):
    if request.method == "POST":
        name = request.POST.get('name')
        email = request.POST.get('email')
        mobile_no = request.POST.get('mobile_no')
        army_no = request.POST.get('army_no')
        picture = request.FILES.get('picture')
        battalion_id = request.POST.get('battalion')
        company_id = request.POST.get('company')
        rank_id = request.POST.get('rank')
        apartment_id = request.POST.get('apartment')
        role_id = request.POST.get('role')
        # Validate password
        # try:
        #     validate_password(password)
        # except ValidationError as e:
        #     messages.error(request, ", ".join(e.messages))  # Show validation errors
        #     return redirect("read_user_admin")
        # Check if all fields are provided
        if not all([name, email, mobile_no, army_no, rank_id,role_id,battalion_id,company_id]):
            messages.error(request, "All fields are required")
            return redirect('read_user_admin')
        # Check if the email is already in use
        if User.objects.filter(email=email).exists():
            messages.error(request, "Email already in use")
            return redirect('read_user_admin')
        try:
            user = User.objects.create_user(email=email, password=mobile_no)
            user.name = name
            user.army_no = army_no
            user.battalion = Battalion.objects.get(id=battalion_id)
            user.company = Company.objects.get(id=company_id)
            user.rank = Rank.objects.get(id=rank_id)
            if picture:
                user.picture = picture
            if apartment_id:
                user.apartment = Apartment.objects.get(id=apartment_id)
            user.mobile_no = mobile_no
            user.role = Role.objects.get(id=role_id)
            user.is_staff = True
            user.save()
            messages.success(request, "User created successfully")
            return redirect('read_user_admin')
        except Exception as e:
            messages.error(request, "An error occurred")
        return redirect('read_user_admin')
    
    roles = Role.objects.all().exclude(h_name='member')  # Exclude 'member' role
    # Get all battalions, member types, and apartments
    battalions = Battalion.objects.all()
    companies = Company.objects.all()
    member_statuses = MemberStatus.objects.all()
    apartments = Apartment.objects.all()
    
    context = {
        'roles': roles,
        'battalions': battalions,
        'companies': companies,
        'member_statuses': member_statuses,
        'apartments': apartments,
    } 
    return render(request, 'admin/add_user_form.html', context)
  
@role_required('update_user_admin')  
def update_user_admin(request,id):
    user = User.objects.get(id=id)
    context={
        'user':user,
        'member_statuses':MemberStatus.objects.all(),
        'ranks':Rank.objects.all(),
        'battalions':Battalion.objects.all(),
        'companies':Company.objects.all(),
        'apartments':Apartment.objects.all(),
        'roles':Role.objects.all(). exclude(h_name='member'),  # Exclude 'member' role
    }
    if request.method == "POST":
        name = request.POST.get('name')
        email = request.POST.get('email')
        mobile_no = request.POST.get('mobile_no')
        army_no = request.POST.get('army_no')
        picture = request.FILES.get('picture')
        battalion_id = request.POST.get('battalion')
        company_id = request.POST.get('company')
        rank_id = request.POST.get('rank')
        apartment_id = request.POST.get('apartment')
        role_id = request.POST.get('role')
        if not all([name,email,mobile_no,army_no,rank_id,battalion_id,company_id,role_id]):
            messages.error(request, "All fields are required")
            return redirect('read_user_admin')

        try:
            user.name = name
            user.email = email
            user.mobile_no = mobile_no
            user.army_no = army_no
            user.battalion = Battalion.objects.get(id=battalion_id)
            user.company = Company.objects.get(id=company_id)
            user.role = Role.objects.get(id=role_id)
            user.rank = Rank.objects.get(id=rank_id)
            if picture:
                user.picture = picture
            if apartment_id:
                user.apartment = Apartment.objects.get(id=apartment_id)
            user.save()
            messages.success(request, "User Updated successfully")
            return redirect('read_user_admin')
        except Exception as e:
            print(e)
            messages.error(request, "An error occurred")
        return redirect('read_user_admin')
    return render(request,'admin/edit_user_form.html',context) 
    
    
@role_required('delete_user_admin')
def delete_user_admin(request,id):
    user = User.objects.get(id=id)
    user.delete()
    messages.success(request, "User deleted successfully")
    return redirect('read_user_admin')

@role_required('reset_password_user_admin')
def reset_password_user_admin(request,id):
    user = User.objects.get(id=id)
    user.set_password(user.mobile_no)
    user.save()
    messages.success(request, "Password reset successfully")
    return redirect('read_user_admin')
    
    
    
 









#TODO: Member PDF
def read_member_pdf(request, member_type='total'):
    role = request.user.role
    if role and role.modules.filter(name='read_member_admin').exists():
        members = Member.objects.filter(active=True).order_by('company__battalion__sn','company__sn','rank')
    elif role and role.modules.filter(name='read_member_battalion').exists():
        companies = request.user.battalion.companies.all()
        members = Member.objects.filter(Q(company__in=companies)|Q(p_company__in=companies), active=True).select_related( 'rank', 'apartment').order_by('company__battalion__sn','company__sn','rank')
    elif role and role.modules.filter(name='read_member_company').exists():
        company=request.user.company
        members = Member.objects.filter(Q(company=company)|Q(p_company=company), active=True).select_related( 'rank', 'apartment').order_by('company__battalion__sn','company__sn','rank')
    else:
        messages.error(request, "You don't have permission to view this page.")
        return render(request, 'others/no_permission.html')
    
    if member_type != "total":
        members = members.filter(member_type__name=member_type)
    search_query = request.GET.get("search", "")  
    
    
    # Get search query
    if search_query:
        members = members.filter(
            Q(army_no__icontains=search_query) |
            Q(mobile_no__icontains=search_query) |
            Q(name__icontains=search_query)
        )
        
    battalion_query = request.GET.get("battalion_query")
    if battalion_query and battalion_query != "0":
        battalion = Battalion.objects.get(id=battalion_query)
        members = members.filter(company__battalion=battalion)

    company_query = request.GET.get("company_query")
    if company_query and company_query != "0":
        company = Company.objects.get(id=company_query)
        members = members.filter(company=company)
        
    rank_query = request.GET.get("rank_query")
    if rank_query and rank_query != "0":
        rank = Rank.objects.get(id=rank_query)
        members = members.filter(rank=rank)
    
    member_status_query = request.GET.get("member_status_query")
    if member_status_query and member_status_query != "0":
        member_status = MemberStatus.objects.get(id=member_status_query)
        members = members.filter(rank__member_status=member_status)
        
        
    name = 'Pers'
    file_name = 'pers'
    context = {
        'members':members,
        'name': name,
    }
    # Load the HTML template and render it with context data
    template = get_template('pdf/memberTablePDF.html')
    html = template.render(context)

    # Create a response with PDF content type
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = f'inline; filename="{file_name}.pdf"'

    # Convert HTML to PDF
    pisa_status = pisa.CreatePDF(html, dest=response)

    if pisa_status.err:
        return HttpResponse("Error generating PDF", status=500)
    
    return response






