import json
import pandas as pd
from .forms import * 
from .models import *
from django.views.generic import CreateView, UpdateView, DeleteView, ListView,TemplateView , DetailView
from django.urls import reverse_lazy
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import authenticate, login , logout ,update_session_auth_hash
from django.contrib import messages
from django.http import HttpResponseRedirect , HttpResponse , JsonResponse , HttpResponseBadRequest
from django.views.decorators.csrf import csrf_protect , csrf_exempt
from django.contrib.auth.decorators import login_required
from django.db import IntegrityError , transaction
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin
from django.utils.decorators import method_decorator
from functools import wraps
from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth.hashers import make_password
from django.db.models import Q
from django.urls import reverse
import pandas as pd
from django.http import HttpResponse
from openpyxl import Workbook  # این خط را اضافه کنید
from openpyxl.drawing.image import Image
from io import BytesIO
from django.core.files.storage import default_storage
from PIL import Image as PILImage
from django.core.paginator import Paginator
def custom_404_view(request, exception):
    return render(request, '404.html', status=404)

def role_required(*role_names):
    """
    دکوراتوری برای بررسی دسترسی کاربران براساس نقش‌هایشان.
    """
    def decorator(view_func):
        @wraps(view_func)
        def _wrapped_view(request, *args, **kwargs):
            # اگر کاربر احراز هویت نشده باشد
            if not request.user.is_authenticated:
                return render(request, "404.html", status=404)
            
            try:
                # بررسی ارتباط کاربر با مدل Person
                person = Person.objects.get(user=request.user)
            except Person.DoesNotExist:
                # اگر کاربر هیچ شخص مرتبطی نداشته باشد
                return render(request, "404.html", status=404)
            
            # بررسی نقش‌ها
            user_roles = person.role.values_list('name', flat=True)
            if not any(role in user_roles for role in role_names):
                # اگر کاربر هیچ یک از نقش‌های مجاز را نداشته باشد
                return render(request, "404.html", status=404)
            
            # دسترسی مجاز
            return view_func(request, *args, **kwargs)
        
        return _wrapped_view
    return decorator

@csrf_protect
def custom_login_view(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        remember_me = request.POST.get('remember') ==  'on' # بررسی وضعیت دکمه "مرا به خاطر بسپار"

        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            user = authenticate(request, username=username, password=password)

            if user is not None:
                login(request, user)
                
                return redirect('information')  # به صفحه داشبورد هدایت کنید
            else:
                form.add_error(None, 'نام کاربری یا رمز عبور اشتباه است')
        else:
            form.add_error(None, 'لطفا اطلاعات را به درستی وارد کنید.')
    else:
        form = LoginForm()

    return render(request, 'login.html', {'form': form})

def logout_view(request):
    # خروج از سیستم کاربر
    logout(request)
    # بعد از خروج، کاربر را به صفحه لاگین یا هر صفحه دلخواه هدایت کنید
    return redirect('/')  # به صفحه لاگین هدایت می‌شود
def profile_view(request):
    # فرض می‌کنیم که فقط کاربر لاگین شده اطلاعات خود را ببیند
    person = Person.objects.filter(user=request.user).first()
    person_private_info = PersonPrivateInfo.objects.filter(
        person=person).first()
    person_edu = PersonEDU.objects.filter(
        person=person).first()  # فراخوانی () اضافه شد
    person_other_info = PersonOtherInfo.objects.filter(person=person).first()
    Person_address = PersonAddress.objects.filter(person=person).first()
    Person_cultural = PersonCultural.objects.filter(person=person).first()
    context = {
        'person': person,
        'person_private_info': person_private_info,
        'person_edu': person_edu,
        'person_other_info': person_other_info,
        'person_address': Person_address,
        'person_cultural': Person_cultural
    }
    return render(request, 'profile/dashboard.html', context)
@login_required(login_url='/')
def profile_viewInfo(request):
    try:
        person = Person.objects.get(user=request.user)
    except Person.DoesNotExist:
        return render(request, 'profile/informationuser.html', {'error': 'کاربر یافت نشد.'})
    
    # بررسی نقش "خانواده"
    is_family_role = person.role.filter(name='خانواده').exists()

    person_private_info = getattr(person, 'person_private_info', None)
    person_edu = getattr(person, 'person_edu', None)
    person_other_info = getattr(person, 'person_other_info', None)
    person_address = getattr(person, 'person_address', None)
    person_cultural = getattr(person, 'person_cultural', None)

    # دریافت نام فرزند در صورتی که نقش "خانواده" وجود داشته باشد
    family = Family.objects.filter(individual=person).first() # در اینجا فرد خانواده را جستجو می‌کنیم
    if family:
        children = family.child.all()  # دریافت لیست فرزندان
        child_names = ", ".join([f"{child.user.first_name} {child.user.last_name}" for child in children])
    else:
        child_names = None  # در صورتی که خانواده یافت نشد، مقدار None می‌دهیم

    context = {
        'person': person,
        'person_private_info': person_private_info,
        'person_edu': person_edu,
        'person_other_info': person_other_info,
        'person_address': person_address,
        'person_cultural': person_cultural,
        'is_family_role': is_family_role,
        'child_name': child_names,  # ارسال نام فرزند
    }

    return render(request, 'profile/informationuser.html', context)
@login_required(login_url='/')
def profile_viewaAddress(request):
    # فرض می‌کنیم که فقط کاربر لاگین شده اطلاعات خود را ببیند
    person = Person.objects.filter(user=request.user).first()
    person_private_info = PersonPrivateInfo.objects.filter(
        person=person).first()
    person_edu = PersonEDU.objects.filter(
        person=person).first()  # فراخوانی () اضافه شد
    person_other_info = PersonOtherInfo.objects.filter(person=person).first()
    person_address = PersonAddress.objects.filter(person=person)
    person_cultural = PersonCultural.objects.filter(person=person).first()
    context = {
        'person': person,
        'person_private_info': person_private_info,
        'person_edu': person_edu,
        'person_other_info': person_other_info,
        'person_address': person_address,
        'person_cultural': person_cultural
    }
    return render(request, 'profile/addressuser.html', context)
@login_required(login_url='/')
def profile_viewOther(request):
    # فرض می‌کنیم که فقط کاربر لاگین شده اطلاعات خود را ببیند
    person = Person.objects.filter(user=request.user).first()
    person_private_info = PersonPrivateInfo.objects.filter(
        person=person).first()
    person_edu = PersonEDU.objects.filter(
        person=person).first()  # فراخوانی () اضافه شد
    person_other_info = PersonOtherInfo.objects.filter(person=person).first()
    Person_address = PersonAddress.objects.filter(person=person)
    Person_cultural = PersonCultural.objects.filter(person=person).first()
    context = {
        'person': person,
        'person_private_info': person_private_info,
        'person_edu': person_edu,
        'person_other_info': person_other_info,
        'person_address': Person_address,
        'person_cultural': Person_cultural
    }
    return render(request, 'profile/other.html', context)

@role_required('فرماندهی', 'ادمین_اصلی','نیرو_انسانی')
def add_user(request):
    # فرم‌ست آدرس‌ها
    PersonAddressFormSet = modelformset_factory(
        PersonAddress,
        form=PersonAddressForm,
        extra=1,  # تعداد فرم‌های خالی که نمایش داده می‌شود
        can_delete=True,
    )

    if request.method == 'POST':
        # فرم‌های ورودی
        user_form = UserForm(request.POST)
        person_form = PersonForm(request.POST)
        private_info_form = PersonPrivateInfoForm(request.POST, request.FILES)
        edu_form = PersonEDUForm(request.POST)
        other_info_form = PersonOtherInfoForm(request.POST)
        cultural_form = PersonCulturalForm(request.POST)
        address_formset = PersonAddressFormSet(request.POST, queryset=PersonAddress.objects.none())

        if (
            user_form.is_valid() and person_form.is_valid() and 
            private_info_form.is_valid() and edu_form.is_valid() and 
            other_info_form.is_valid() and cultural_form.is_valid() and 
            address_formset.is_valid()
        ):
            # ذخیره کاربر
            user = user_form.save()

            # ذخیره اطلاعات شخص
            person = person_form.save(commit=False)
            person.user = user
            person.save()

            # ذخیره نقش‌ها
            roles = person_form.cleaned_data.get('role')
            person.role.set(roles)  # ذخیره نقش‌ها

            # ذخیره اطلاعات خصوصی
            private_info = private_info_form.save(commit=False)
            private_info.person = person
            private_info.save()

            # ذخیره اطلاعات آموزشی
            edu_info = edu_form.save(commit=False)
            edu_info.person = person
            edu_info.save()

            # ذخیره سایر اطلاعات
            other_info = other_info_form.save(commit=False)
            other_info.person = person
            other_info.save()

            # ذخیره اطلاعات فرهنگی
            cultural_info = cultural_form.save(commit=False)
            cultural_info.person = person
            cultural_info.save()

            # ذخیره آدرس‌ها
            for form in address_formset:
                if form.cleaned_data and not form.cleaned_data.get('DELETE', False):
                    address = form.save(commit=False)
                    address.person = person
                    address.save()

            # ارسال پیغام موفقیت
            messages.success(request, 'کاربر با موفقیت اضافه شد!', 'info')

            return redirect('upload_pic', person_id=person.id)  # ریدایرکت به صفحه لیست کاربران
        else:
            # در صورت عدم اعتبار سنجی، نمایش پیغام خطا (اختیاری)
            messages.error(request, 'لطفاً اطلاعات را به درستی وارد کنید.', 'danger')
    else:
        # فرم‌های خالی برای GET
        user_form = UserForm()
        person_form = PersonForm()
        private_info_form = PersonPrivateInfoForm()
        edu_form = PersonEDUForm()
        other_info_form = PersonOtherInfoForm()
        cultural_form = PersonCulturalForm()
        address_formset = PersonAddressFormSet(queryset=PersonAddress.objects.none())  # فرم‌های خالی

    context = {
        'user_form': user_form,
        'person_form': person_form,
        'private_info_form': private_info_form,
        'edu_form': edu_form,
        'other_info_form': other_info_form,
        'cultural_form': cultural_form,
        'address_formset': address_formset,
        'is_edit': False,  # مشخص‌کننده وضعیت افزودن
    }
    return render(request, 'profile/add_user.html', context)
import os
from django.utils import timezone  # ✅ اینجا تغییر دادم

def upload_pic(request, person_id):
    person = get_object_or_404(PersonPrivateInfo, person__id=person_id)
    print("pics of user", person.pic)

    initial_data = {'pic': person.pic.url if person.pic else None}

    if request.method == 'POST' and 'pic' in request.FILES:
        form = PersonPicForm(request.POST, request.FILES, instance=person)

        if form.is_valid():
            uploaded_file = request.FILES['pic']

            # بررسی حجم فایل
            if uploaded_file.size > 102400:  # 100KB
                messages.error(request, 'حجم فایل باید کمتر از 100 کیلوبایت باشد.')
                return render(request, 'profile/upload_pic.html', {'form': form, 'person': person})

            # حذف فایل قبلی اگر وجود داشته باشد
            if person.pic:
                old_pic_path = person.pic.path
                if os.path.exists(old_pic_path):
                    os.remove(old_pic_path)
                
            ext = uploaded_file.name.split('.')[-1]  # استخراج پسوند فایل
            current_time = timezone.now().strftime('%Y%m%d%H%M%S')
            new_name = f"profile_{person.id}_{current_time}.{ext}"

            # تغییر نام فایل جدید
            person.pic.name = os.path.join('profile_pics', new_name)

            # ذخیره فرم و تصویر جدید
            form.save()
            messages.success(request, 'عکس با موفقیت آپلود شد!', 'info')

            return redirect('psychological_test', person_id=person.id)
        else:
            print("form is not valid")
    else:
        form = PersonPicForm(instance=person, initial=initial_data)

    context = {
        'form': form,
        'person': person,
    }
    return render(request, 'profile/upload_pic.html', context)


from django.utils import timezone
from datetime import datetime as now

def psychological_test_view(request, person_id):
    person = get_object_or_404(PersonCultural, person__id=person_id)
    initial_data = {'Psychological_test': person.Psychological_test.url if person.Psychological_test else None}

    # استخراج نام فایل
    file_name = None
    if person.Psychological_test:
        file_name = person.Psychological_test.name.split('/')[-1]

    if request.method == 'POST':
        form = PersonPsyForm(request.POST, request.FILES, instance=person)
        if form.is_valid():
            if 'Psychological_test' in request.FILES:
                uploaded_file = request.FILES['Psychological_test']

                # بررسی حجم فایل
                if uploaded_file.size > 1536000:  # 1.5MB
                    messages.warning(request, 'حجم فایل باید کمتر از 1.5 مگابایت باشد.')
                    return render(request, 'profile/psychological_test_form.html', {'form': form, 'person': person})

                # حذف فایل قبلی اگر وجود داشته باشد
                if person.Psychological_test:
                    old_file_path = person.Psychological_test.path
                    if os.path.exists(old_file_path):
                        os.remove(old_file_path)

                # ایجاد نام جدید برای فایل
                ext = uploaded_file.name.split('.')[-1]
                current_time = timezone.now().strftime('%Y%m%d%H%M%S')
                new_name = f"psy_test_{person.id}_{current_time}.{ext}"
                person.Psychological_test.name = os.path.join('psychological_tests', new_name)

            form.save(commit=False)
            person.save()

            messages.success(request, 'عملیات با موفقیت انجام شد!', 'info')
            return redirect('user_list')
    else:
        form = PersonPsyForm(request.POST or None, initial=initial_data, instance=person)

    context = {
        'form': form,
        'person': person,
        'file_name': file_name,  # ارسال نام فایل به قالب
    }
    return render(request, 'profile/psychological_test_form.html', context)

def save_changed_fields(form, instance):
    """
    این متد بررسی می‌کند که آیا فیلدی از فرم تغییر کرده است یا خیر. 
    در صورتی که تغییری باشد، آن را ذخیره می‌کند.
    """
    # بررسی هر فیلد فرم
    if form.has_changed():  # بررسی اینکه آیا تغییری در فرم ایجاد شده است
        form.save()  # ذخیره فرم فقط در صورت تغییر



from django.forms import modelformset_factory


@role_required('فرماندهی', 'ادمین_اصلی','نیرو_انسانی')
def profile_update_view(request, person_id):
    PersonAddressFormSet = modelformset_factory(PersonAddress, form=PersonAddressForm, extra=1, can_delete=True)
    # دریافت شخص بر اساس ID یا ارسال خطای 404
    person = get_object_or_404(Person, id=person_id)
    
    # اطلاعات شخص
    user_info = person.user
    person_private_info = PersonPrivateInfo.objects.filter(person=person).first()
    person_edu = PersonEDU.objects.filter(person=person).first()
    person_other_info = PersonOtherInfo.objects.filter(person=person).first()
    person_cultural = PersonCultural.objects.filter(person=person).first()
    
    # آدرس‌های مرتبط با شخص
    person_addresses = PersonAddress.objects.filter(person=person)
    for address in person_addresses:
        print("address =============== ", address.id)
    

    if request.method == 'POST':
        user_form = UserForm(request.POST, instance=user_info)
        person_form = PersonForm(request.POST, instance=person)
        private_info_form = PersonPrivateInfoForm(request.POST, instance=person_private_info)
        edu_form = PersonEDUForm(request.POST, instance=person_edu)
        other_info_form = PersonOtherInfoForm(request.POST, instance=person_other_info)
        cultural_form = PersonCulturalForm(request.POST, instance=person_cultural)
        
        # FormSet برای آدرس‌ها
        address_formset = PersonAddressFormSet(request.POST, queryset=person_addresses)
        # print("@@@@@@@@@@ = ", address_formset.cleaned_data)
        # for formmm in address_formset:
        #     print(formmm.cleaned_data)
        # print("start ===============")
        # if  address_formset.is_valid():
        #     print("condition start =========== ")
        #     for formmm in address_formset:
        #         formmm.instance.person = person
        #     add_data = address_formset.cleaned_data
        #     address_formset.save()
        #     print(add_data)
        # else:
        #     print("address_formset is not valid ===========")
        #     print(address_formset.errors)

        # بررسی اعتبار فرم‌ها و ذخیره تغییرات
        if (
            
            user_form.is_valid() and
            person_form.is_valid() and
            private_info_form.is_valid() and
            edu_form.is_valid() and
            other_info_form.is_valid() and
            cultural_form.is_valid() and
            address_formset.is_valid()
        ):
            print("user_form is valid")
            # ذخیره تغییرات در فرم‌ها
            save_changed_fields(user_form, user_info)
            save_changed_fields(person_form, person)
            save_changed_fields(private_info_form, person_private_info)
            save_changed_fields(edu_form, person_edu)
            save_changed_fields(other_info_form, person_other_info)
            save_changed_fields(cultural_form, person_cultural)

            # ذخیره فرم‌ست آدرس‌ها
            addresses = address_formset.save(commit=False)
            for address in addresses:
                address.person = person  # اطمینان از مرتبط بودن آدرس با شخص
                address.save()

            # حذف آدرس‌های حذف‌شده
            for address in address_formset.deleted_objects:
                address.delete()

            return redirect('upload_pic', person_id=person.id)  # هدایت به صفحه موفقیت یا هر مقصد دیگری
        else:
            print("user_form is not valid")
            # در صورت عدم اعتبار، هدایت به صفحه لیست کاربران
            return redirect('user_list')
    else:
        user_form = UserForm(instance=user_info)
        person_form = PersonForm(instance=person)
        private_info_form = PersonPrivateInfoForm(instance=person_private_info)
        edu_form = PersonEDUForm(instance=person_edu)
        other_info_form = PersonOtherInfoForm(instance=person_other_info)
        cultural_form = PersonCulturalForm(instance=person_cultural)
        
        # فرم‌ست برای آدرس‌ها
        address_formset = PersonAddressFormSet(queryset=person_addresses)

    # آماده‌سازی context برای ارسال به قالب
    context = {
        'user_form': user_form,
        'person_form': person_form,
        'private_info_form': private_info_form,
        'edu_form': edu_form,
        'other_info_form': other_info_form,
        'cultural_form': cultural_form,
        'address_formset': address_formset,
        'person': person, 
        'is_edit': True,  # مشخص‌کننده وضعیت ویرایش
    }
    return render(request, 'profile/add_user.html', context)




@role_required('فرماندهی', 'ادمین_اصلی','نیرو_انسانی')
def profile_update2_view(request, person_id):
    PersonAddressFormSet = modelformset_factory(PersonAddress, form=PersonAddressForm, extra=1, can_delete=True)
    # دریافت شخص بر اساس ID یا ارسال خطای 404
    person = get_object_or_404(Person, id=person_id)
    
    # اطلاعات شخص
    user_info = person.user
    person_private_info = PersonPrivateInfo.objects.filter(person=person).first()
    person_edu = PersonEDU.objects.filter(person=person).first()
    person_other_info = PersonOtherInfo.objects.filter(person=person).first()
    person_cultural = PersonCultural.objects.filter(person=person).first()
    
    # آدرس‌های مرتبط با شخص
    person_addresses = PersonAddress.objects.filter(person=person)
    for address in person_addresses:
        print("address =============== ", address.id)
    

    if request.method == 'POST':
        user_form = UserForm(request.POST, instance=user_info)
        person_form = PersonForm(request.POST, instance=person)
        private_info_form = PersonPrivateInfoForm(request.POST, instance=person_private_info)
        edu_form = PersonEDUForm(request.POST, instance=person_edu)
        other_info_form = PersonOtherInfoForm(request.POST, instance=person_other_info)
        cultural_form = PersonCulturalForm(request.POST, instance=person_cultural)
        
        # FormSet برای آدرس‌ها
        address_formset = PersonAddressFormSet(request.POST, queryset=person_addresses)
        # print("@@@@@@@@@@ = ", address_formset.cleaned_data)
        # for formmm in address_formset:
        #     print(formmm.cleaned_data)
        # print("start ===============")
        # if  address_formset.is_valid():
        #     print("condition start =========== ")
        #     for formmm in address_formset:
        #         formmm.instance.person = person
        #     add_data = address_formset.cleaned_data
        #     address_formset.save()
        #     print(add_data)
        # else:
        #     print("address_formset is not valid ===========")
        #     print(address_formset.errors)

        # بررسی اعتبار فرم‌ها و ذخیره تغییرات
        if (
            
            user_form.is_valid() and
            person_form.is_valid() and
            private_info_form.is_valid() and
            edu_form.is_valid() and
            other_info_form.is_valid() and
            cultural_form.is_valid() and
            address_formset.is_valid()
        ):
            print("user_form is valid")
            # ذخیره تغییرات در فرم‌ها
            save_changed_fields(user_form, user_info)
            save_changed_fields(person_form, person)
            save_changed_fields(private_info_form, person_private_info)
            save_changed_fields(edu_form, person_edu)
            save_changed_fields(other_info_form, person_other_info)
            save_changed_fields(cultural_form, person_cultural)

            # ذخیره فرم‌ست آدرس‌ها
            addresses = address_formset.save(commit=False)
            for address in addresses:
                address.person = person  # اطمینان از مرتبط بودن آدرس با شخص
                address.save()

            # حذف آدرس‌های حذف‌شده
            for address in address_formset.deleted_objects:
                address.delete()


            return redirect('council_members_list')
    else:
        user_form = UserForm(instance=user_info)
        person_form = PersonForm(instance=person)
        private_info_form = PersonPrivateInfoForm(instance=person_private_info)
        edu_form = PersonEDUForm(instance=person_edu)
        other_info_form = PersonOtherInfoForm(instance=person_other_info)
        cultural_form = PersonCulturalForm(instance=person_cultural)
        
        # فرم‌ست برای آدرس‌ها
        address_formset = PersonAddressFormSet(queryset=person_addresses)

    # آماده‌سازی context برای ارسال به قالب
    context = {
        'user_form': user_form,
        'person_form': person_form,
        'private_info_form': private_info_form,
        'edu_form': edu_form,
        'other_info_form': other_info_form,
        'cultural_form': cultural_form,
        'address_formset': address_formset,
        'person': person, 
        'is_edit': True,  # مشخص‌کننده وضعیت ویرایش
    }
    return render(request, 'profile/add_user2.html', context)
@login_required(login_url='/')
@login_required
@role_required('فرماندهی', 'ادمین_اصلی','نیرو_انسانی','امام_جماعت','ورزشی_و_اردویی','علمی_و_آموزشی','تعلیم_و_تربیت','حفاظت')
def user_list_view(request):
    people = Person.objects.all()

    # اعمال فیلترهای جستجو
    search_query = request.GET.get('search')
    search_field = request.GET.get('search_field', 'first_name')
    per_page = request.GET.get('per_page', '10')  

    if search_query:
        if search_field == 'first_name':
            people = people.filter(user__first_name__icontains=search_query)
        elif search_field == 'last_name':
            people = people.filter(user__last_name__icontains=search_query)
        elif search_field == 'national_code':
            people = people.filter(national_code__icontains=search_query)
        elif search_field == 'birthday':
            people = people.filter(personprivateinfo__birthday__icontains=search_query)
        elif search_field == 'ozviat_categories':
            people = people.filter(person_cultural__ozviat_categories__icontains=search_query)
        elif search_field == 'tarbyat_categories':
            people = people.filter(person_cultural__tarbyat_categories__icontains=search_query)
        elif search_field == 'sardoshi_categories':
            people = people.filter(person_cultural__sardoshi_categories__icontains=search_query)

    # بررسی مقدار per_page برای صفحه‌بندی
    if per_page == "all":
        paginator = Paginator(people, people.count())  # نمایش همه رکوردها
    else:
        paginator = Paginator(people, int(per_page))

    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)

    people_data = []
    for person in page_obj:
        person_private_info = PersonPrivateInfo.objects.filter(person=person).first()
        person_cultural = PersonCultural.objects.filter(person=person).first()

        people_data.append({
            'id': person.id,
            'pic': person_private_info.pic if person_private_info else None,
            'first_name': person.user.first_name,
            'last_name': person.user.last_name,
            'phone': person_private_info.phone if person_private_info else '',
            'national_code': person.national_code,
            'birthday': person_private_info.birthday if person_private_info else '',
            'ozviat_categories': person_cultural.ozviat_categories if person_cultural else '',
            'tarbyat_categories': person_cultural.tarbyat_categories if person_cultural else '',
            'sardoshi_categories': person_cultural.sardoshi_categories if person_cultural else '',
        })

    context = {
        'people_data': people_data,
        'search_query': search_query,
        'search_field': search_field,
        'per_page': per_page,
        'page_obj': page_obj,
    }
    return render(request, 'profile/user_list.html', context)



import pandas as pd
from django.http import HttpResponse
from .models import Person, PersonPrivateInfo, PersonCultural
import io
import jdatetime
from django.http import HttpResponse
from django.shortcuts import get_list_or_404
from openpyxl import Workbook
from tempfile import NamedTemporaryFile
from PIL import Image as PILImage  # اضافه کردن Pillow
from django.conf import settings  # برای دسترسی به دامنه سایت

def download_excel(request):
    user_ids = request.GET.getlist('users')  # دریافت لیست آی‌دی کاربران
    
    if not user_ids:
        return render(request, 'error.html', {'message': 'هیچ کاربری انتخاب نشده است.'})

    people = get_list_or_404(Person, id__in=user_ids)

    wb = Workbook()
    ws = wb.active
    ws.title = "کاربران"

    headers = [
        "ردیف", "نام", "نام خانوادگی", "کدملی",
        "تولد", "جنسیت", "محل تولد", "شماره موبایل", "نام پدر", "شماره پدر", "تحصیلات پدر", "شغل پدر",
        "نام مادر", "شماره مادر", "تحصیلات مادر", "شغل مادر",
        "عضویت", "رده تربیتی", "سردوشی", "رسته",
        "رشته تحصیلی", "وضعیت تحصیلی", "محل تحصیل", "ترم", "آدرس محل تحصیل", "کلاس خارج مدرسه",
        "شغل", "عنوان شغل", "درآمد ماهانه", "تاهل", "تعداد اعضای خانواده", "فرزند چندم",
        "استعدادها",
        "آدرس‌ها (نوع:آدرس،کدپستی،تلفن ثابت،موقعیت)"
    ]
    ws.append(headers)

    row_number = 1
    for person in people:
        private = getattr(person, 'person_private_info', None)
        cultural = getattr(person, 'person_cultural', None)
        edu = getattr(person, 'person_edu', None)
        other = getattr(person, 'person_other_info', None)
        addresses = person.person_address.all()

        birthday = ''
        if private and private.birthday:
            try:
                if isinstance(private.birthday, jdatetime.date):
                    birthday = private.birthday.strftime('%Y/%m/%d')
                else:
                    birthday = jdatetime.datetime.fromgregorian(date=private.birthday).strftime('%Y/%m/%d')
            except Exception as e:
                birthday = 'خطا در تبدیل'

        # آدرس‌ها (چند تایی)
        address_strs = []
        for addr in addresses:
            a = f"{addr.typee or ''}: {addr.address or ''}, کدپستی: {addr.postal_code or ''}, تلفن: {addr.tell or ''}, موقعیت: {addr.location or ''}"
            address_strs.append(a)
        all_addresses = " | ".join(address_strs)

        row = [
            row_number,
            person.user.first_name,
            person.user.last_name,
            person.national_code,

            birthday,
            private.gender if private else "",
            private.birth_place if private else "",
            private.phone if private else "",
            private.father_name if private else "",
            private.father_phone if private else "",
            private.father_grade if private else "",
            private.fatherJob if private else "",
            private.mother_name if private else "",
            private.mother_phone if private else "",
            private.mother_grade if private else "",
            private.motherJob if private else "",

            cultural.ozviat_categories if cultural else "",
            cultural.tarbyat_categories if cultural else "",
            cultural.sardoshi_categories if cultural else "",
            cultural.raste_categories if cultural else "",

            edu.edu_name if edu else "",
            edu.typee if edu else "",
            edu.place_name if edu else "",
            edu.term_name if edu else "",
            edu.place_address if edu else "",
            edu.otherClass if edu else "",

            other.job_type if other else "",
            other.job_title if other else "",
            other.salary_month if other else "",
            other.wife_type if other else "",
            other.family_count if other else "",
            other.numberOfChild if other else "",
            other.talents if other else "",

            all_addresses
        ]

        ws.append(row)
        row_number += 1

    # خروجی اکسل
    output = io.BytesIO()
    wb.save(output)
    output.seek(0)

    response = HttpResponse(output, content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
    response["Content-Disposition"] = 'attachment; filename=users.xlsx'
    return response

def usersreportcard_detail(request):
    # دریافت اطلاعات تمام کاربران
    people = Person.objects.all()

    # دریافت اطلاعات مدل Index
    indices = Index.objects.all()

    # اعمال فیلترهای جستجو
    search_query = request.GET.get('search')
    search_field = request.GET.get('search_field', 'first_name')

    if search_query:
        if search_field == 'first_name':
            people = people.filter(user__first_name__icontains=search_query)
        elif search_field == 'last_name':
            people = people.filter(user__last_name__icontains=search_query)
        elif search_field == 'national_code':
            people = people.filter(national_code__icontains=search_query)
        elif search_field == 'birthday':
            people = people.filter(personprivateinfo__birthday__icontains=search_query)
        elif search_field == 'ozviat_categories':
            people = people.filter(person_cultural__ozviat_categories__icontains=search_query)
        elif search_field == 'tarbyat_categories':
            people = people.filter(person_cultural__tarbyat_categories__icontains=search_query)
        elif search_field == 'sardoshi_categories':
            people = people.filter(person_cultural__sardoshi_categories__icontains=search_query)

    # دریافت اطلاعات اضافی برای هر شخص
    people_data = []
    for person in people:
        person_private_info = PersonPrivateInfo.objects.filter(person=person).first()
        person_cultural = PersonCultural.objects.filter(person=person).first()

        # دریافت اطلاعات کارنامه برای هر فرد
        report_card_details = ReportCardDetail.objects.filter(reportcard__person=person)

        # اضافه کردن نمرات به مدل
        report_card_scores = []
        for index in indices:
            report_card = report_card_details.filter(index=index).first()
            report_card_scores.append({
                'index_id': index.id,
                'score': report_card.score if report_card else None
            })

        people_data.append({
            'id': person.id,
            'pic': person_private_info.pic if person_private_info else None,
            'first_name': person.user.first_name,
            'last_name': person.user.last_name,
            'phone': person_private_info.phone if person_private_info else '',
            'national_code': person.national_code,
            'birthday': person_private_info.birthday if person_private_info else '',
            'ozviat_categories': person_cultural.ozviat_categories if person_cultural else '',
            'tarbyat_categories': person_cultural.tarbyat_categories if person_cultural else '',
            'sardoshi_categories': person_cultural.sardoshi_categories if person_cultural else '',
            'report_card_scores': report_card_scores,  # اضافه کردن نمرات به صورت دیکشنری
        })

    # ارسال داده‌ها به قالب
    context = {
        'people_data': people_data,
        # 'indices': indices,  # ارسال اطلاعات مدل Index
        'search_query': search_query,
        'search_field': search_field,
    }
    return render(request, 'profile/users_reportcard_detail.html', context)
def rate_users_view(request, role_key):
    role_display_names = {
        "sargroh": "سرگروه",
        "talimvatarbiat": "تعلیم و تربیت",
        "elmivaamozeshi": "علمی و آموزشی",
        "varzeshivaordoee": "ورزشی و اردویی",
        "syasatgozari": "سیاست‌گذاری",
        "farmandehi": "فرماندهی",
        "emamjamaat": "امام جماعت",
    }

    role_fields = {
        "sargroh": "sargroh",
        "talimvatarbiat": "talimvatarbiat",
        "elmivaamozeshi": "elmivaamozeshi",
        "varzeshivaordoee": "varzeshivaordoee",
        "syasatgozari": "syasatgozari",
        "farmandehi": "farmandehi",
        "emamjamaat": "emamjamaat",
    }

    role_name = role_display_names.get(role_key)
    role_field = role_fields.get(role_key)

    if not role_name or not role_field:
        return render(request, "error.html", {"message": "نقش نامعتبر است."})

# نقش‌های موردنظر برای فیلتر
   # نقش‌های موردنظر برای فیلتر
    people = Person.objects.exclude(
    role__name__in=["فرماندهی", "جانشین", "ادمین_اصلی", "خانواده"]
).exclude(
    person_cultural__tarbyat_categories__in=["مربی", "شورا ی سیاست گذاری"]
)


    # جستجو و فیلتر کردن افراد
    search_query = request.GET.get('search')
    search_field = request.GET.get('search_field', 'first_name')

    if search_query:
        if search_field == 'first_name':
            people = people.filter(user__first_name__icontains=search_query)
        elif search_field == 'last_name':
            people = people.filter(user__last_name__icontains=search_query)
        elif search_field == 'national_code':
            people = people.filter(national_code__icontains=search_query)

    people_data = []
    for person in people:
        # پیدا کردن آخرین کارنامه نهایی
        report_card_finaly = ReportCardFinaly.objects.filter(person=person).order_by('-created_at').first()
        role_score = getattr(report_card_finaly, role_field, None) if report_card_finaly else None
        image_url = person.person_private_info.pic.url if person.person_private_info and person.person_private_info.pic else None

        people_data.append({
            'id': person.id,
            'image': image_url,
            'first_name': person.user.first_name,
            'last_name': person.user.last_name,
            'national_code': person.national_code,
            'role_score': role_score,
            'report_card': report_card_finaly,
        })

    context = {
        'people_data': people_data,
        'search_query': search_query,
        'search_field': search_field,
        'role_name': role_name,
        'role_key': role_key,
    }
    return render(request, "profile/rate_users.html", context)
@login_required(login_url='/')
@role_required('فرماندهی', 'ادمین_اصلی','نیرو_انسانی','امام_جماعت','ورزشی_و_اردویی','علمی_و_آموزشی','تعلیم_و_تربیت','حفاظت')
def roles_list(request):
    roles = [
        {"name": "سرگروه", "key": "sargroh"},
        {"name": "تعلیم و تربیت", "key": "talimvatarbiat"},
        {"name": "علمی و آموزشی", "key": "elmivaamozeshi"},
        {"name": "ورزشی و اردویی", "key": "varzeshivaordoee"},
        {"name": "سیاست‌گذاری", "key": "syasatgozari"},
        {"name": "فرماندهی", "key": "farmandehi"},
        {"name": "امام جماعت", "key": "emamjamaat"},
    ]
    return render(request, "profile/roles_list.html", {"roles": roles})

# def update_user_scores(request):
#     if request.method == 'POST':
#         # پیمایش از روی فیلدهای ارسال‌شده در فرم
#         for key, value in request.POST.items():
#             # اگر نام فیلد شامل 'score_' باشد، یعنی نمره مربوط به کاربر است
#             if key.startswith('score_'):
#                 # استخراج person_id از نام فیلد
#                 person_id = key.split('_')[1]
#                 try:
#                     # جستجوی کاربر با استفاده از person_id
#                     person = Person.objects.get(id=person_id)
#                     # دریافت کارنامه مربوط به شخص
#                     report_card_finaly = ReportCardFinaly.objects.filter(title__person=person).first()
#                     if report_card_finaly:
#                         # به‌روزرسانی نمره نقش خاص در کارنامه
#                         setattr(report_card_finaly, 'sargroh' if 'sargroh' in key else 
#                                 'talimvatarbiat' if 'talimvatarbiat' in key else
#                                 'elmivaamozeshi' if 'elmivaamozeshi' in key else
#                                 'varzeshivaordoee' if 'varzeshivaordoee' in key else
#                                 'syasatgozari' if 'syasatgozari' in key else 
#                                 'farmandehi' if 'farmandehi' in key else 
#                                 'emamjamaat', value)
#                         report_card_finaly.save()
#                 except Person.DoesNotExist:
#                     continue

#         # هدایت به صفحه قبلی بعد از ذخیره
#         referer = request.META.get('HTTP_REFERER')
#         if referer:
#             return redirect(referer)
#         else:
#             return redirect('rate_users')
#     return HttpResponseBadRequest("Invalid request")

# تعریف نقش‌ها و فیلدهای مرتبط در مدل `ReportCardFinaly`
role_fields = {
    "sargroh": "sargroh",
    "talimvatarbiat": "talimvatarbiat",
    "elmivaamozeshi": "elmivaamozeshi",
    "varzeshivaordoee": "varzeshivaordoee",
    "syasatgozari": "syasatgozari",
    "farmandehi": "farmandehi",
    "emamjamaat": "emamjamaat",
}

def edit_user_scores(request, person_id, role_key):
    role_fields = {
        "sargroh": "sargroh",
        "talimvatarbiat": "talimvatarbiat",
        "elmivaamozeshi": "elmivaamozeshi",
        "varzeshivaordoee": "varzeshivaordoee",
        "syasatgozari": "syasatgozari",
        "farmandehi": "farmandehi",
        "emamjamaat": "emamjamaat",
    }

    role_display_names = {
        "sargroh": "سرگروه",
        "talimvatarbiat": "تعلیم و تربیت",
        "elmivaamozeshi": "علمی و آموزشی",
        "varzeshivaordoee": "ورزشی و اردویی",
        "syasatgozari": "سیاست‌گذاری",
        "farmandehi": "فرماندهی",
        "emamjamaat": "امام جماعت",
    }

    role_name = role_display_names.get(role_key)
    role_field = role_fields.get(role_key)
    person = get_object_or_404(Person, id=person_id)

    # پیدا کردن آخرین کارنامه نهایی
    report_card_finaly = ReportCardFinaly.objects.filter(person=person).order_by('-created_at').first()

    if not report_card_finaly:
        return render(request, 'error.html', {'message': 'گزارش نهایی یافت نشد'})

    if request.method == 'POST':
        new_score = request.POST.get(f'score_{person.id}')
        if new_score:
            setattr(report_card_finaly, role_field, new_score)
            report_card_finaly.save()

        return redirect('rate_users', role_key=role_key)

    return render(request, 'profile/reportcard/edit_scores.html', {
        'person': person,
        'report_card_finaly': report_card_finaly,
        'role_key': role_key,
        'role_name': role_name,
    })



@login_required
def roles_list_view(request):
    # دریافت نقش‌های کاربر
    user_roles = request.user.person.role.all()

    # تعریف نقش‌ها و کلیدهای مربوطه
    roles = {
        "سرگروه": "sargroh",
        "تعلیم_و_تربیت": "talimvatarbiat",
        "علمی_و_آموزشی": "elmivaamozeshi",
        "ورزشی_و_اردویی": "varzeshivaordoee",
        "فرماندهی": "farmandehi",
        "امام_جماعت": "emamjamaat",
        "نیرو_انسانی": "niro_ensani",
    }

    # بررسی نقش‌های ویژه
    special_roles = ["فرماندهی", "نیرو_انسانی", "ادمین_اصلی"]
    if user_roles.filter(name__in=special_roles).exists():
        return redirect("roles_list")  # مسیر صحیح برای نقش‌های ویژه

    # بررسی نقش‌های دیگر و هدایت به مسیر مربوطه
    for role in user_roles:
        if role.name in roles:
            role_key = roles[role.name]
            return redirect("rate_users", role_key=role_key)

    # اگر هیچ نقشی پیدا نشد
    return redirect("no_access")  # مسیر پیش‌فرض برای دسترسی نداشتن

def no_access_view(request):
    return render(request, "profile/no_access.html", {"message": "شما به این بخش دسترسی ندارید."})

import jdatetime
import pandas as pd
from io import BytesIO
from openpyxl import Workbook
from openpyxl.drawing.image import Image
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from .models import Person, PersonPrivateInfo, PersonEDU, PersonCultural


def convert_jdate_to_gdate(jdate):
    """تبدیل jdatetime.date به datetime.date"""
    if isinstance(jdate, jdatetime.date):
        return jdate.togregorian()
    return jdate

    # ارسال فایل اکسل به عنوان پاسخ HTTP
    response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename="users.xlsx"'

    with BytesIO() as output:
        wb.save(output)
        output.seek(0)
        response.write(output.read())

    return response
@login_required(login_url='/')
def profile_viewuser(request, person_id):
    # دریافت شخص با استفاده از person_id
    person = get_object_or_404(Person, id=person_id)
    
    # اطلاعات مربوط به شخص
    person_private_info = PersonPrivateInfo.objects.filter(person=person).first()
    person_edu = PersonEDU.objects.filter(person=person).first()
    person_other_info = PersonOtherInfo.objects.filter(person=person).first()
    person_address = PersonAddress.objects.filter(person=person)
    person_cultural = PersonCultural.objects.filter(person=person).first()

    context = {
        'person': person,
        'person_private_info': person_private_info,
        'person_edu': person_edu,
        'person_other_info': person_other_info,
        'person_address': person_address,
        'person_cultural': person_cultural
    }
    
    return render(request, 'profile/detail.html', context)

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
import os

@csrf_exempt
def upload_avatar(request):
    if request.method == 'POST' and request.FILES.get('file'):
        user = request.user

        # بررسی آیا `Person` برای این کاربر وجود دارد یا نه
        person, _ = Person.objects.get_or_create(user=user)

        # بررسی آیا `PersonPrivateInfo` برای `Person` وجود دارد یا نه
        person_private_info, created = PersonPrivateInfo.objects.get_or_create(person=person)

        # ذخیره عکس
        file = request.FILES['file']
        file_name = f'avatars/{user.username}.jpg'
        file_path = default_storage.save(file_name, ContentFile(file.read()))

        # به‌روزرسانی مسیر تصویر در دیتابیس
        person_private_info.avatar = file_path
        person_private_info.save()

        return JsonResponse({'success': True, 'image_url': default_storage.url(file_path)})

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

@role_required('فرماندهی', 'ادمین_اصلی','نیرو_انسانی')
def delete_user(request, person_id):
    # دریافت شخص بر اساس ID یا ارسال خطای 404
    person = get_object_or_404(Person, id=person_id)
    
    # بررسی اینکه ID برابر 1 نباشد
    if person_id == 1:
        messages.error(request, 'این کاربر را نمی‌توان حذف کرد.')
        return redirect('user_list')

    if request.method == 'POST':
        # حذف موجودیت‌های مرتبط
        PersonPrivateInfo.objects.filter(person=person).delete()
        PersonEDU.objects.filter(person=person).delete()
        PersonOtherInfo.objects.filter(person=person).delete()
        PersonCultural.objects.filter(person=person).delete()
        PersonAddress.objects.filter(person=person).delete()

        # حذف اطلاعات کاربر (اگر مرتبط است)
        if person.user:
            person.user.delete()

        # حذف خود شخص
        person.delete()

        # پیام موفقیت‌آمیز
        messages.success(request, 'پروفایل با موفقیت حذف شد.')

        # ری‌دایرکت به داشبورد یا لیست کاربران
        return redirect('user_list')

    return render(request, 'profile/delete.html', {'person': person})


@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class RingCreateView(CreateView):
    model = Ring
    form_class = RingForm  # استفاده از فرم
    template_name = 'profile/ring/ring_form.html'
    success_url = reverse_lazy('rings_with_members') 

    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.success(self.request, 'حلقه جدید با موفقیت ایجاد شد.')
        return super().form_valid(form)
   
@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class RingCreateeView(CreateView):
    model = Ring
    form_class = RingForm  # استفاده از فرم
    template_name = 'profile/ring/ring_with_form.html'
    success_url = reverse_lazy('rings_with_members')  
    
    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.success(self.request, 'حلقه جدید با موفقیت ایجاد شد.')
        return super().form_valid(form)
   
# ویوی ویرایش حلقه
@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class RingUpdateView(UpdateView):
    model = Ring
    form_class = RingForm  # استفاده از فرم
    template_name = 'profile/ring/ring_form.html'
    success_url = reverse_lazy('rings_with_members')

    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.warning(self.request, 'حلقه  با موفقیت ویرایش شد.')
        return super().form_valid(form)

@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class RingDeleteView(DeleteView):
    model = Ring
    template_name = 'profile/ring/ring_confirm_delete.html'
    success_url = reverse_lazy('rings_with_members')
    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.error(self.request, 'حلقه  با موفقیت حذف شد.' , extra_tags='danger')
        return super().form_valid(form)

# ویوی لیست حلقه‌ها
@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class RingListView(ListView):
    model = Ring
    template_name = 'profile/ring/rings_with_members.html'
    context_object_name = 'rings'

@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class RingMemberCreateView(CreateView):
    model = RingMember
    form_class = RingMemberForm  # استفاده از فرم
    template_name = 'profile/ring/ring_member_form.html'
    success_url = reverse_lazy('ring_member_list')

    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.success(self.request, 'عضو جدید با موفقیت ایجاد شد.')
        return super().form_valid(form)

@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class RingMemberCreateeView(CreateView):
    model = RingMember
    form_class = RingMemberForm  # استفاده از فرم
    template_name = 'profile/ring/ring_with_member_form.html'
    success_url = reverse_lazy('rings_with_members')

    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.success(self.request, 'عضو جدید با موفقیت ایجاد شد.')
        return super().form_valid(form)
   

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['view'] = self
        return context

class MemberDetailView(LoginRequiredMixin, DetailView):
    model = Person 
    template_name = 'profile/ring/member_detail.html'
    context_object_name = 'member'

    def get_object(self):
        return get_object_or_404(Person, pk=self.kwargs['pk'])

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # افزودن داده‌های مرتبط به context
        person_private_info = self.object.person_private_info  # استفاده از related_name
        person_edu = self.object.person_edu  # فرض می‌کنیم رابطه‌ای وجود دارد
        person_other_info = self.object.person_other_info  # فرض می‌کنیم رابطه‌ای وجود دارد
        person_cultural = self.object.person_cultural  # فرض می‌کنیم رابطه‌ای وجود دارد
        person_address = self.object.person_address.all()  # فرض می‌کنیم رابطه OneToMany وجود دارد

        # افزودن داده‌های به context
        context['person_private_info'] = person_private_info
        context['person_edu'] = person_edu
        context['person_other_info'] = person_other_info
        context['person_cultural'] = person_cultural
        context['person_address'] = person_address

        return context    

@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class RingMemberUpdateView(UpdateView):
    model = RingMember
    form_class = RingMemberForm  # استفاده از فرم
    template_name = 'profile/ring/ring_member_form.html'
    success_url = reverse_lazy('ring_member_list')

    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.warning(self.request, 'عضو  با موفقیت ویرایش شد.')
        return super().form_valid(form)
   
@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class RingMemberDeleteView(DeleteView):
    model = RingMember
    template_name = 'profile/ring/ring_member_confirm_delete.html'
    success_url = reverse_lazy('ring_member_list')
    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.error(self.request, 'عضو  با موفقیت حذف شد.' , extra_tags='danger')
        return super().form_valid(form)
   
@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class RingMemberListView(ListView):
    model = RingMember
    template_name = 'profile/ring/ring_member_list.html'
    context_object_name = 'ring_members'
    
class RingWithMembersListView(TemplateView):
    template_name = 'profile/ring/ring_with_members.html'
    context_object_name = 'rings'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # گرفتن تمام حلقه‌ها همراه با اعضای آن‌ها
        context['rings'] = Ring.objects.prefetch_related('members__person')  # اطمینان از پیش‌بارگذاری اعضا و اطلاعات افراد
        return context
@method_decorator(login_required(login_url='/'), name='dispatch')
@method_decorator(role_required('سرگروه'), name='dispatch')
class RingMembersView(LoginRequiredMixin, ListView):
    model = RingMember
    template_name = 'profile/ring/ring_members.html'
    context_object_name = 'members'

    def get_queryset(self):
        person = get_object_or_404(Person, user=self.request.user)
        rings = Ring.objects.filter(major=person)
        return RingMember.objects.filter(ring__in=rings)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        members = context['members']
        
        # گرفتن اطلاعات شخصی برای هر عضو
        for member in members:
            # گرفتن اطلاعات private_info برای هر عضو
            private_info = PersonPrivateInfo.objects.filter(person=member.person).first()
            member.private_info = private_info  # اضافه کردن به شی عضو
          
        return context
# تغییر متد 

import pandas as pd
from django.http import HttpResponse
from django.contrib import messages
from django.shortcuts import redirect
from .models import Person  # مطمئن شوید که مدل درست را ایمپورت می‌کنید
from django.shortcuts import get_list_or_404
def export_selected_members(request):
    if request.method == "POST":
        selected_ids = request.POST.getlist("selected_members")

        if not selected_ids:
                   return HttpResponse("لطفاً حداقل یک کاربر را انتخاب کنید.", status=400)



        people = get_list_or_404(Person, id__in=selected_ids)
    for person in people:

        private_info = PersonPrivateInfo.objects.filter(person=person).first()


        if not selected_ids:
            messages.error(request, 'لطفا حداقل یک عضو را انتخاب کنید.', extra_tags='danger')
            return redirect('ring_members')  # نام صفحه‌ای که لیست اعضا را نمایش می‌دهد

        members = get_list_or_404(RingMember, pk__in=selected_ids)
        birth_date = ""
        if private_info and private_info.birthday:
            try:
                if isinstance(private_info.birthday, jdatetime.date):
                    # اگر تاریخ قبلاً شمسی است، همان را ذخیره کنیم
                    birth_date = private_info.birthday.strftime("%Y/%m/%d")
                else:
                    # اگر تاریخ میلادی است، به شمسی تبدیل کنیم
                    shamsi_date = jdatetime.datetime.fromgregorian(date=private_info.birthday)
                    birth_date = shamsi_date.strftime("%Y/%m/%d")
            except Exception as e:
                print(f"⚠️ خطا در تبدیل تاریخ: {e}")

        data = []
        for member in members:
            data.append({
                 "شماره":  member.person.id,
                "نام": member.person.user.first_name,
                 "نام خانوادگی": member.person.user.last_name,  
                "تاریخ تولد": birth_date   ,
                "موبایل" :private_info.phone         
            })

        df = pd.DataFrame(data)
        response = HttpResponse(content_type='application/vnd.ms-excel')
        response['Content-Disposition'] = 'attachment; filename="selected_members.xlsx"'
        df.to_excel(response, index=False)

        return response

@role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی')
def edit_ring_members(request, ring_pk):
    ring = get_object_or_404(Ring, pk=ring_pk)
    members = ring.members.all()  # گرفتن اعضای حلقه

    if request.method == 'POST':
        # اگر دکمه حذف فشار داده شود
        if 'delete_member' in request.POST:
            member_pk = request.POST['delete_member']
            member = get_object_or_404(RingMember, pk=member_pk)
            member.delete()  
            messages.success(request, 'کاربر با موفقیت حذف شد.')

            return redirect('edit_ring_members', ring_pk=ring.pk)  # بازگشت به صفحه ویرایش اعضا

    return render(request, 'profile/ring/edit_ring_members.html', {'ring': ring, 'members': members})
@method_decorator(login_required(login_url='/'), name='dispatch')
@method_decorator(role_required('فرماندهی', 'ادمین_اصلی'), name='dispatch')
class ReportCardListView(ListView):
    model = ReportCard
    template_name = 'profile/reportcard/reportcard_list.html'
    context_object_name = 'reportcards'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        
        # مقدار `baze` را از اولین رکورد دریافت کن
        first_report_card = ReportCard.objects.first()
        if first_report_card:
            context['baze'] = first_report_card.title
        else:
            context['baze'] = None  

        return context

 
# تغییر متد 

@role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی')
def add_member_to_ring(request, ring_pk):
    ring = get_object_or_404(Ring, pk=ring_pk)

    if request.method == 'POST':
        form = RingMemberForm1(request.POST)
        if form.is_valid():
            member = form.save(commit=False)
            member.ring = ring  # حلقه را به صورت خودکار تنظیم می‌کنیم
            member.save()
            messages.success(request, 'کاربر با موفقیت ساخته شد.')

            return redirect('edit_ring_members', ring_pk=ring.pk)
    else:
        form = RingMemberForm1()

    return render(request, 'profile/ring/add_member_to_ring.html', {'form': form, 'ring': ring})

def ReportCardDetailView(request, reportcard_id):
    # دریافت اطلاعات کارنامه
    reportcard = ReportCard.objects.get(id=reportcard_id)
    indexes = Index.objects.all()  # شاخص‌ها
    details = ReportCardDetail.objects.filter(reportcard=reportcard  )  # جزئیات کارنامه
    

    # ساخت داده‌های مورد نیاز
    index_details = []
    for index in indexes:
        detail = details.filter(index=index).first()  # جزئیات مرتبط با شاخص
        index_details.append({
            'index': index,
            'details': detail
        })

    context = {
        'reportcard': reportcard,
        'index_details': index_details,
        'csrf_token': request.COOKIES.get('csrftoken'),  # ارسال CSRF برای جاوااسکریپت
    }
    return render(request, 'profile/reportcard/reportcard_detail.html', context)
  
# @csrf_exempt
# def update_detail_scores(request):
#     if request.method == "POST":
#         data = json.loads(request.body)
#         scores = data.get('scores', [])
#         for score_data in scores:
#             detail_id = score_data.get('detailId')
#             index_id = score_data.get('indexId')
#             reportcard_id = score_data.get('reportcardId')
#             score = score_data.get('score')

#             # اگر detailId موجود است، آن را بروزرسانی کن، در غیر این صورت ایجاد کن
#             if detail_id:
#                 detail = ReportCardDetail.objects.get(id=detail_id)
#             else:
#                 detail = ReportCardDetail.objects.create(
#                     index_id=index_id,
#                     reportcard_id=reportcard_id
#                 )
#             detail.score = score
#             detail.save()

#         return JsonResponse({'success': True})

#     return JsonResponse({'success': False}, status=400)

# ایجاد کارنامه جدید
class ReportCardCreateView(CreateView):
    model = ReportCard
    form_class = ReportCardForm
    template_name = 'profile/reportcard/reportcard_form.html'

    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.success(self.request, 'کارنامه جدید با موفقیت ایجاد شد.')
        return super().form_valid(form)
   
    def get_success_url(self):
        return reverse_lazy('reportcard_detail', kwargs={'reportcard_id': self.object.pk})

# ویرایش کارنامه
class ReportCardUpdateView(UpdateView):
    model = ReportCard
    form_class = ReportCardForm
    template_name = 'profile/reportcard/reportcard_form.html'
    success_url = reverse_lazy('reportcard_list')

    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.warning(self.request, 'کارنامه  با موفقیت ویرایش شد.')
        return super().form_valid(form)
   
# حذف کارنامه
class ReportCardDeleteView(DeleteView):
    model = ReportCard
    template_name = 'profile/reportcard/reportcard_confirm_delete.html'
    success_url = reverse_lazy('reportcard_list')

    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.error(self.request, 'کارنامه  با موفقیت حذف شد.' , extra_tags='danger')
        return super().form_valid(form)

# مدیریت جزئیات کارنامه
class ReportCardDetailCreateView(CreateView):
    model = ReportCardDetail
    form_class = ReportCardDetailForm
    template_name = 'profile/reportcard/reportcarddetail_form.html'
    success_url = reverse_lazy('reportcard_list')

class ReportCardDetailUpdateView(UpdateView):
    model = ReportCardDetail
    form_class = ReportCardDetailForm
    template_name =  'profile/reportcard/reportcarddetail_form.html'

    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.success(self.request, 'کارنامه  با موفقیت ویرایش شد.')
        return super().form_valid(form)
   

    def get_success_url(self):
        # پس از ذخیره جزئیات، به صفحه جزئیات کارنامه هدایت می‌کند
        return reverse_lazy('reportcard_detail', kwargs={'pk': self.object.pk})

class ReportCardDetailDeleteView(DeleteView):
    model = ReportCardDetail
    template_name = 'profile/reportcard/reportcarddetail_confirm_delete.html'
    success_url = reverse_lazy('reportcard_list')
    def form_valid(self, form):
        # ثبت پیام موفقیت
        messages.error(self.request, 'کارنامه  با موفقیت حذف شد.' , extra_tags='danger')
        return super().form_valid(form)
   
@csrf_exempt
def update_all_detail_scores(request):
    if request.method == "POST":
        try:
            data = json.loads(request.body)
            scores = data.get("scores", [])
            
            updated = False
            created = False

            for score_data in scores:
                detail_id = score_data.get("detailId")
                reportcard_id = score_data.get("reportcardId")
                index_id = score_data.get("indexId")
                score_value = score_data.get("score")

                if detail_id:
                    # به‌روزرسانی جزئیات موجود
                    detail = ReportCardDetail.objects.get(pk=detail_id)
                    detail.score = score_value
                    detail.save()
                    updated = True  # مشخص کردن اینکه ویرایشی انجام شده است
                else:
                    # ایجاد جزئیات جدید
                    ReportCardDetail.objects.create(
                        reportcard_id=reportcard_id,
                        index_id=index_id,
                        score=score_value
                    )
                    created = True  # مشخص کردن اینکه آیتم جدیدی ساخته شده است

            # نمایش پیام بر اساس نوع عملیات انجام‌شده
            if updated:
                messages.warning(request, 'نمرات با موفقیت ویرایش شدند.')
            if created:
                messages.success(request, 'نمرات جدید با موفقیت اضافه شدند.')

            return JsonResponse({"success": True, "message": "نمرات با موفقیت ذخیره شدند."})

        except ReportCardDetail.DoesNotExist:
            return JsonResponse({"success": False, "message": "جزئیات یافت نشد."})

        except Exception as e:
            return JsonResponse({"success": False, "message": f"خطا: {str(e)}"})

    return JsonResponse({"success": False, "message": "درخواست معتبر نیست."})

@csrf_exempt
def calculate_average(request):
    if request.method == "POST":
        data = json.loads(request.body)
        scores = data.get('scores', [])

        total_score = 0
        total_coefficient = 0

        for score in scores:
            score_value = float(score.get('score', 0))  # نمره
            coefficient = float(score.get('coefficient', 1))  # ضریب

            total_score += score_value * coefficient
            total_coefficient += coefficient

        if total_coefficient > 0:
            average_score = total_score / total_coefficient
        else:
            average_score = 0

        return JsonResponse({'success': True, 'average_score': average_score})

    return JsonResponse({'success': False, 'message': 'Request method not allowed'}, status=400)

def add_index(request):
    if request.method == 'POST':
        form = IndexForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, 'شاخصه  با موفقیت اضافه شد.' )

            return redirect('index_list')
            
    else:
        form = IndexForm()
    
    return render(request, 'profile/reportcard/add_index.html', {'form': form})

def index_list(request):
    indices = Index.objects.all()
    return render(request, 'profile/reportcard/index_list.html', {'indices': indices})

def update_index(request, pk):
    index = get_object_or_404(Index, pk=pk)
    if request.method == 'POST':
        form = IndexForm(request.POST, instance=index)
        if form.is_valid():
            form.save()
            messages.warning(request, 'شاخصه  با موفقیت ویرایش شد.')
            return redirect('index_list')
    else:
        form = IndexForm(instance=index)
    return render(request, 'profile/reportcard/add_index.html', {'form': form})

# حذف شاخصه
def delete_index(request, pk):
    index = get_object_or_404(Index, pk=pk)
    if request.method == 'POST':
        index.delete()
        messages.error(request, 'شاخصه  با موفقیت حذف شد.' , extra_tags='danger')
        return redirect('index_list')
    return render(request, 'profile/reportcard/index_delete.html', {'index': index})
def verify_identity_view(request):
    if request.method == 'POST':
        form = VerifyIdentityForm(request.POST)
        if form.is_valid():
            national_id = form.cleaned_data['national_id']
            birth_date = form.cleaned_data['birth_date']
            father_name = form.cleaned_data['father_name']
            try:
                user = User.objects.get(
                    person__national_code=national_id,
                    person__person_private_info__birthday=birth_date,
                    person__person_private_info__father_name=father_name
                )
                request.session['user_id'] = user.id
                return redirect('reset_password')
            except User.DoesNotExist:
                form.add_error(None, 'کد ملی یا تاریخ تولد اشتباه است.')
    else:
        form = VerifyIdentityForm()

    return render(request, 'verify_identity.html', {'form': form})


def reset_password_view(request):
    user_id = request.session.get('user_id')
    if not user_id:
        return redirect('verify_identity')

    try:
        user = User.objects.get(id=user_id)
    except User.DoesNotExist:
        return redirect('verify_identity')

    if request.method == 'POST':
        form = ResetPasswordForm(request.POST)
        if form.is_valid():
            new_password = form.cleaned_data['new_password']  # تغییر به new_password
            confirm_password = form.cleaned_data['confirm_password']  # تغییر به confirm_password

            if new_password != confirm_password:
                form.add_error('confirm_password', 'رمز عبور و تکرار آن مطابقت ندارند.')
            else:
                user.password = make_password(new_password)
                user.save()
                messages.success(request, 'رمز عبور با موفقیت تغییر کرد.')
                return redirect('custom_login_view')
    else:
        form = ResetPasswordForm()

    return render(request, 'reset_password.html', {'form': form, 'user': user})

class MajorRingMembersView(LoginRequiredMixin, View):
    template_name = 'profile/ring/ring_members.html'  # مسیر قالبی که اعضا را نمایش می‌دهد

    def get(self, request, *args, **kwargs):
        # دریافت کاربر وارد شده
        person = getattr(request.user, 'person', None)

        if not person:
            return render(request, self.template_name, {'error': 'شخصی مرتبط با این کاربر یافت نشد.'})

        # حلقه‌هایی که این کاربر سرگروه آنها است
        rings = Ring.objects.filter(major=person)

        if not rings.exists():
            return render(request, self.template_name, {'error': 'شما مسئول هیچ حلقه‌ای نیستید.'})

        # اعضای تمام حلقه‌ها
        members = RingMember.objects.filter(ring__in=rings).select_related('person', 'ring')

        return render(request, self.template_name, {
            'rings': rings,
            'members': members
        })

@login_required
def password_change_view(request):
    if request.method == 'POST':
        form = PasswordChangeForm(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()  # رمز عبور جدید ذخیره می‌شود
            update_session_auth_hash(request, form.user)  # برای جلوگیری از لاگ‌آوت شدن
            return redirect(reverse('custom_login_view'))  # بازگشت به صفحه لاگین پس از تغییر رمز
    else:
        form = PasswordChangeForm(user=request.user)

    return render(request, 'password_change.html', {'form': form})

def check_if_family_score_exists(report_cards):
    # بررسی نمره خانوادگی برای هر یک از report card ها
    return ReportCardDetail.objects.filter(
        reportcard__in=report_cards,  # بررسی در report card های مشخص
        index__title='خانواده'
    ).exists()

@login_required(login_url='/')
def user_dashboard(request):
    """
    داشبورد اصلی که نقش کاربر را بررسی و داده‌های مناسب را نمایش می‌دهد.
    """
    # گرفتن اطلاعات شخص مرتبط با کاربر
    person = get_object_or_404(Person, user=request.user)

    # اگر نقش کاربر سرگروه باشد
    if person.role.filter(name='سرگروه').exists():
        rings = person.rings_major.all()  # تمام حلقه‌هایی که این شخص مسئول آنهاست
        return render(request, 'profile/reportcard/report_card_major.html', {'rings': rings})

    # اگر نقش کاربر خانواده باشد
   # اگر نقش کاربر خانواده باشد
    elif person.role.filter(name='خانواده').exists():
    # یافتن فرزندان مرتبط با خانواده
        children_ids = Family.objects.filter(individual=person).values_list('child__id', flat=True)
        report_cards = ReportCard.objects.filter(person__id__in=children_ids,title = "فرهنگی")

    # بررسی اینکه آیا نمره برای خانواده وارد شده است یا نه
        report_cards_with_family_score = [
            {
                'report_card': report_card,
                'is_family_score_exists': check_if_family_score_exists([report_card])  # بررسی برای هر کارنامه به صورت جداگانه
            }
            for report_card in report_cards
        ]

        # ارسال داده‌ها به قالب
        return render(request, 'profile/reportcard/report_card_family.html', {
            'report_cards_with_family_score': report_cards_with_family_score

        })


    # اگر نقش کاربر فرماندهی باشد
   

    elif person.role.filter(name='ادمین_اصلی').exists():
        members = Person.objects.filter(memberships__isnull=False)


        # اعمال فیلتر جستجو برای اعضا
        search_query = request.GET.get('search')
        search_field = request.GET.get('search_field', 'first_name')  # فیلد جستجو پیش‌فرض: نام
        if search_query:
            # جستجو بر اساس فیلد انتخابی
            if search_field == 'first_name':
                members = members.filter(user__first_name__icontains=search_query)
            elif search_field == 'last_name':
                members = members.filter(user__last_name__icontains=search_query)
            elif search_field == 'national_code':
                members = members.filter(national_code__icontains=search_query)
            elif search_field == 'raste':
                members = members.filter(person_cultural__raste_categories__icontains=search_query)
            elif search_field == 'ring':
                members = members.filter(memberships__ring__name__icontains=search_query)

        return render(request, 'profile/reportcard/report_card_admin.html', {'members': members})

    # اگر نقش کاربر نیروی انسانی باشد
    elif person.role.filter(name='نیرو_انسانی').exists() or person.role.filter(name='حفاظت').exists():
        members = Person.objects.filter(memberships__isnull=False)

        # اعمال فیلتر جستجو برای اعضا
        search_query = request.GET.get('search')
        search_field = request.GET.get('search_field', 'first_name')  # فیلد جستجو پیش‌فرض: نام

        if search_query:
            # جستجو بر اساس فیلد انتخابی
            if search_field == 'first_name':
                members = members.filter(user__first_name__icontains=search_query)
            elif search_field == 'last_name':
                members = members.filter(user__last_name__icontains=search_query)
            elif search_field == 'national_code':
                members = members.filter(national_code__icontains=search_query)
            elif search_field == 'raste':
                members = members.filter(person_cultural__raste_categories__icontains=search_query)
            elif search_field == 'ring':
                members = members.filter(memberships__ring__name__icontains=search_query)

        return render(request, 'profile/reportcard/report_card_admin.html', {'members': members})
    elif person.role.filter(name='فرماندهی').exists():
        members = Person.objects.filter(memberships__isnull=False)

        # اعمال فیلتر جستجو برای اعضا
        search_query = request.GET.get('search')
        search_field = request.GET.get('search_field', 'first_name')  # فیلد جستجو پیش‌فرض: نام

        if search_query:
            # جستجو بر اساس فیلد انتخابی
            if search_field == 'first_name':
                members = members.filter(user__first_name__icontains=search_query)
            elif search_field == 'last_name':
                members = members.filter(user__last_name__icontains=search_query)
            elif search_field == 'national_code':
                members = members.filter(national_code__icontains=search_query)
            elif search_field == 'raste':
                members = members.filter(person_cultural__raste_categories__icontains=search_query)
            elif search_field == 'ring':
                members = members.filter(memberships__ring__name__icontains=search_query)

        return render(request, 'profile/reportcard/report_card_admin.html', {'members': members})
    # اگر نقش دیگری نداشته باشد (نمایش کارنامه‌های خودش)
    else:
        report_cards = ReportCard.objects.filter(person=person,title = "فرهنگی")  # کارنامه‌های شخص
        return render(request, 'profile/reportcard/personal_report_card.html', {'report_cards': report_cards})

from django.shortcuts import render, get_object_or_404

# def show_report(request):
#     # دریافت شخص با بررسی وجود کاربر
#     person = get_object_or_404(Person, user=request.user)
    
#     reports = []  # مقدار پیش‌فرض برای جلوگیری از خطای عدم مقداردهی

#     # بررسی اینکه شخص دارای نقش "خانواده" هست یا نه
#     if person.role.filter(name='خانواده').exists():
#         # یافتن فرزندان مرتبط با خانواده
#         children_ids = Family.objects.filter(individual=person).values_list('child__id', flat=True)
#         print(children_ids , "$$$$$$$$$$$$$$$$")
#         # دریافت کارنامه‌های مرتبط با فرزندان
#         reports = ReportCard.objects.filter(person__id__in=children_ids, title="فرهنگی")
#         print(reports , "*********************")
#     # ارسال داده‌ها به قالب
#     return render(request, 'profile/reportcard/report_card_mychild.html', {
#         'reports': reports ,
#         'children_ids' : children_ids # ارسال لیست کارنامه‌ها (نه فقط یک مقدار)
#     })
def show_report(request):
    # دریافت شخص با بررسی وجود کاربر
    person = get_object_or_404(Person, user=request.user)

    user=request.user
    reports = []  # مقدار پیش‌فرض برای جلوگیری از خطای عدم مقداردهی

    # بررسی اینکه شخص دارای نقش "خانواده" هست یا نه
    if person.role.filter(name='خانواده').exists():
        # یافتن فرزندان مرتبط با خانواده
        families = Family.objects.filter(individual__user=user)
        child = Family.objects.filter(individual__user=user).values_list('child__id', flat=True)
        # دریافت کارنامه‌های مرتبط با فرزندان
        reports = ReportCard.objects.filter(person__id__in=child, title="فرهنگی")
    # ارسال داده‌ها به قالب
    return render(request, 'profile/reportcard/report_card_mychild.html', {
        'reports': reports ,
        'families' : families # ارسال لیست کارنامه‌ها (نه فقط یک مقدار)
    })
@login_required
def member_report_cards(request, member_id):
    """
    نمایش لیست کارنامه‌های یک عضو خاص.
    """
    person = get_object_or_404(Person, id=member_id)
    report_cards = ReportCard.objects.filter(person=person  ,title = "فرهنگی")
    
    return render(request, 'profile/reportcard/member_report_cards.html', {'person': person, 'report_cards': report_cards})

@login_required
def report_card_details(request, report_card_id):
    """
    نمایش جزئیات یک کارنامه خاص.
    """
    report_card = get_object_or_404(ReportCard, id=report_card_id)
    details = report_card.details.all()
    return render(request, 'profile/reportcard/report_card_details.html', {'report_card': report_card, 'details': details})

def create_report_card_detail(request, report_card_id):
    report_card = get_object_or_404(ReportCard, id=report_card_id)

    # بررسی اینکه آیا نمره‌ای برای "خانواده" قبلاً وارد شده است
    is_family_score_exists = ReportCardDetail.objects.filter(
        reportcard=report_card,
        index__title='خانواده'
    ).exists()

    if request.method == 'POST':
        report_card_form = ReportCardDetailForm(request.POST, request.FILES)

        if report_card_form.is_valid():
            # ذخیره اطلاعات بدون commit برای تغییرات اضافی
            report_card_detail = report_card_form.save(commit=False)
            report_card_detail.reportcard = report_card  # اتصال به کارنامه

            # بررسی اینکه آیا شاخصه‌ای با عنوان "خانواده" و role='خانواده' وجود دارد یا نه
            index_instance, created = Index.objects.get_or_create(
                role=Role.objects.get(name='خانواده'),  # بررسی بر اساس role 'خانواده'
                title='خانواده',  # بررسی بر اساس عنوان 'خانواده'
                defaults={'coefficient': 5}  # اگر شاخصه‌ای ساخته شد، این مقادیر استفاده می‌شود
            )
            
            report_card_detail.index = index_instance  # اتصال index به گزارش
            report_card_detail.save()  # ذخیره رکورد

            # ارسال پیغام به قالب در صورت موفقیت
            return redirect('user_dashboard')  # تغییر به صفحه موفقیت یا ریدایرکت دلخواه
        else:
            # اگر فرم معتبر نباشد، اطلاعات خطا را نمایش می‌دهیم
            return render(request, 'profile/create_report_card_detail.html', {
                'report_card_form': report_card_form,
                'errors': report_card_form.errors,  # ارسال خطاها
                'is_family_score_exists': is_family_score_exists,  # ارسال وضعیت نمره خانوادگی
            })

    else:
        # اگر متد GET باشد
        report_card_form = ReportCardDetailForm()

    return render(request, 'profile/create_report_card_detail.html', {
        'report_card_form': report_card_form,
        'is_family_score_exists': is_family_score_exists,
        'report_card' : report_card,  # ارسال وضعیت نمره خانوادگی
    })

@role_required('خانواده')
def child_list(request):
    # فرد لاگین شده
    user = request.user

    # پیدا کردن خانواده‌هایی که فرد لاگین شده عضو آنهاست
    families = Family.objects.filter(individual__user=user)

    # ارسال داده به قالب
    return render(request, 'profile/child_list.html', {'families': families})
@method_decorator(login_required(login_url='/'), name='dispatch')
@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class FamilyListView(ListView):
    model = Family
    template_name = 'profile/ring/family_list.html'
    context_object_name = 'families'

@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class FamilyCreateView(CreateView):
    model = Family
    form_class = FamilyForm
    template_name = 'profile/ring/family_form.html'
    success_url = reverse_lazy('family_list')

@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class FamilyUpdateView(UpdateView):
    model = Family
    form_class = FamilyForm
    template_name = 'profile/ring/family_form.html'
    success_url = reverse_lazy('family_list')

@method_decorator(role_required('فرماندهی','ادمین_اصلی','نیرو_انسانی'), name='dispatch')
class FamilyDeleteView(DeleteView):
    model = Family
    template_name = 'profile/ring/family_confirm_delete.html'
    success_url = reverse_lazy('family_list')

def search_persons(request):
    query = request.GET.get('q', '')
    if query:
        # فیلتر بر اساس نام و نام خانوادگی از مدل Person
        persons = Person.objects.filter(
            Q(user__first_name__icontains=query) | Q(user__last_name__icontains=query)
        )
    else:
        persons = Person.objects.none()

    # ارسال داده‌ها به صورت JSON
    data = [{'id': person.id, 'text': f"{person.user.first_name} {person.user.last_name}"} for person in persons]
    return JsonResponse(data, safe=False)

def search_p(request):
    query = request.GET.get('q', '')
    if query:
        # فیلتر بر اساس نقش "خانواده" و جستجو در نام و نام خانوادگی
        persons = Person.objects.filter(
            Q(user__first_name__icontains=query) | Q(user__last_name__icontains=query),
            role__name="خانواده"  # نقش "خانواده"
        ).distinct()
    else:
        persons = Person.objects.none()

    # ارسال داده‌ها به صورت JSON
    data = [{'id': person.id, 'text': f"{person.user.first_name} {person.user.last_name}"} for person in persons]
    return JsonResponse(data, safe=False)
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from .models import Person

def user_list_report(request):
    """
    نمایش لیست کاربران بر اساس نقش کاربر وارد شده
    اگر نقشی نداشت، هدایت به صفحه کارنامه خود
    """
    # گرفتن شخص مرتبط با کاربر
    current_user_person = get_object_or_404(Person, user=request.user)

    # بررسی نقش کاربر
    if current_user_person.role.filter(name='فرماندهی').exists() or current_user_person.role.filter(name='ادمین_اصلی').exists() or current_user_person.role.filter(name='نیرو_انسانی').exists() or current_user_person.role.filter(name='حفاظت').exists():
        # اگر کاربر فرماندهی یا ادمین اصلی باشد، همه کاربران را مشاهده می‌کند
        persons = Person.objects.exclude(
    role__name__in=["فرماندهی", "جانشین", "ادمین_اصلی", "خانواده"]
).exclude(
    person_cultural__tarbyat_categories__in=["مربی", "شورا ی سیاست گذاری"]
)


    elif current_user_person.role.filter(name='سرگروه').exists():
        # اگر کاربر سرگروه باشد، فقط اعضای حلقه‌هایی که مسئولیت آنها را دارد
        rings = current_user_person.rings_major.all()
        persons = []
        for ring in rings:
            persons.extend(ring.members.all())  # جمع‌آوری اعضای هر حلقه
        return render(request, 'profile/reportcard/major_user_list.html', {'persons': persons})
    elif current_user_person.role.filter(name='خانواده').exists():
    # یافتن فرزندان مرتبط با خانواده
        children_ids = Family.objects.filter(individual=current_user_person).values_list('child__id', flat=True)
        persons = Person.objects.filter(id__in=children_ids)

        return render(request, 'profile/reportcard/family_user_list.html', {'persons': persons})
    else:
        # اگر کاربر هیچ‌کدام از نقش‌های بالا را نداشت، هدایت به صفحه کارنامه خود
        return redirect('user_report_cards', person_id=current_user_person.id)

    return render(request, 'profile/reportcard/user_list_report.html', {'persons': persons})

def user_report_cards(request, person_id):
    person = get_object_or_404(Person, id=person_id)
    report_cards = ReportCardFinaly.objects.filter(person=person).order_by('-created_at')  # مرتب‌سازی از جدیدترین به قدیمی‌ترین
    sardoshi = None

    if hasattr(person, 'person_cultural'):  
        sardoshi = person.person_cultural.sardoshi_categories

    return render(request, 'profile/reportcard/user_report_cards.html', {
        'person': person,
        'report_cards': report_cards,  # اصلاح نام متغیر
        'sardoshi': sardoshi,
    })

  
from django.shortcuts import render
from django.db.models import Avg
from django.db.models import Sum, F
from django.shortcuts import render, get_object_or_404
from django.db.models import Sum, F

def report_card_finaly(request, person_id):
    person = get_object_or_404(Person, id=person_id)
    card_id = request.GET.get('card_id')
    report_cards = ReportCardFinaly.objects.filter(person=person)

    if card_id:
        report_cards = report_cards.filter(id=card_id)

    total_score = 0
    total_weight = 0

    weights_continuous = {
        'sargroh': 10,
        'talimvatarbiat': 4,
        'elmivaamozeshi': 2,
        'varzeshivaordoee': 1,
        'farmandehi': 3,
        'emamjamaat': 1,
    }
    
    weights_final = {
        'sargroh': 10,
        'talimvatarbiat': 4,
        'elmivaamozeshi': 3,
        'varzeshivaordoee': 2,
        'syasatgozari': 7,
        'farmandehi': 4,
        'emamjamaat': 1,
    }

    for report_card in report_cards:
        if report_card.title.title == 'مستمر':
            weights = weights_continuous
        elif report_card.title.title == 'نهایی':
            weights = weights_final

        total_score += sum(
            (getattr(report_card, field, 0) or 0) * weights.get(field, 0)
            for field in weights
        )
        total_weight += sum(weights.values())

    average_score = total_score / total_weight if total_weight > 0 else 0

    if report_cards.exists():
        report_card_final = report_cards.first()
        title = report_card_final.title.title
        ring_name = report_card_final.title.ring.name if report_card_final.title and report_card_final.title.ring else "ندارد"
        major = report_card_final.title.ring.major if report_card_final.title and report_card_final.title.ring else "ندارد"
        date = report_card_final.title.date.start_date
        baze = report_card_final.title.date.title
        start_date = report_card_final.title.date.start_date
        end_date = report_card_final.title.date.end_date

    continuous_report_cards = []
    if title == 'نهایی':
        continuous_report_cards = ReportCardFinaly.objects.filter(
            person=person,
            title__title='مستمر',
            title__date__start_date=date
        )

    final_average_score = (
        ReportCardFinaly.objects.filter(person=person, title__title='نهایی')
        .aggregate(total_score=Sum(
            F('sargroh') + F('talimvatarbiat') + F('elmivaamozeshi') +
            F('varzeshivaordoee') + F('syasatgozari') + F('farmandehi') + F('emamjamaat')
        ))
    ).get('total_score', 0) or 0

    final_count = ReportCardFinaly.objects.filter(person=person, title__title='نهایی').count()
    final_average_score /= final_count if final_count > 0 else 1

    total_score = 0
    total_weight = 0
    regular_report_cards = ReportCardFinaly.objects.filter(person=person, title__title='مستمر')

    for report_card in regular_report_cards:
        total_score += sum(
            (getattr(report_card, field, 0) or 0) * weights_continuous.get(field, 0)
            for field in weights_continuous
        )
        total_weight += sum(weights_continuous.values())

    regular_average_score = total_score / total_weight if total_weight > 0 else 0

    regular_count = regular_report_cards.count()
    regular_average_score /= regular_count if regular_count > 0 else 1

    total_average_score = round((average_score + regular_average_score) / 2, 2)

    sardoshi = getattr(person, 'person_cultural', None)
    if sardoshi:
        sardoshi = sardoshi.sardoshi_categories

    show_upgrade_form = total_average_score >= 18
    show_upgrade_form1 = not ReportCardFinaly.objects.filter(person=person, upgrade_used=True).exists()

    return render(request, 'profile/reportcard/report_card_finaly.html', {
        'person': person,
        'report_cards': report_cards,
        'continuous_report_cards': continuous_report_cards,
        'average_score': average_score,
        'ring_name': ring_name,
        'major': major,
        'title': title,
        'show_upgrade_form': show_upgrade_form, 
        'date': date, 
        'sardoshi': sardoshi,
        'final_average_score': final_average_score,
        'regular_average_score': regular_average_score,
        'total_average_score': total_average_score, 
        'baze': baze,
        'show_upgrade_form1': show_upgrade_form1,
        'start_date': start_date,
        'end_date': end_date,
    })

def upgrade_sardoshi(request, person_id):
    if request.method == 'POST' and 'agree' in request.POST:
        person = get_object_or_404(Person, id=person_id)
        person_cultural = getattr(person, 'person_cultural', None)

        if not person_cultural or not person_cultural.sardoshi_categories:
            messages.error(request, 'سردوشی فعلی مشخص نیست.')
            return redirect('user_report_cards', person_id=person_id)

        # چک کردن کارنامه‌های نهایی
        final_report_card = ReportCardFinaly.objects.filter(person=person, upgrade_used=False).first()

        if not final_report_card:
            messages.error(request, 'هیچ کارنامه نهایی برای ارتقا موجود نیست یا قبلاً استفاده شده است.')
            return redirect('user_report_cards', person_id=person_id)

        # ترتیب سردوشی‌ها برای ارتقاء
        sardoshi_order = ['محب', 'صابر', 'خادم', 'جاهد', 'معین', 'شاهد']

        current_sardoshi = person_cultural.sardoshi_categories

        if current_sardoshi not in sardoshi_order:
            messages.error(request, 'سردوشی فعلی نامعتبر است.')
            return redirect('user_report_cards', person_id=person_id)

        current_index = sardoshi_order.index(current_sardoshi)
        if current_index == len(sardoshi_order) - 1:
            messages.info(request, 'فرد در بالاترین سردوشی قرار دارد و امکان ارتقاء وجود ندارد.')
            return redirect('user_report_cards', person_id=person_id)

        next_sardoshi = sardoshi_order[current_index + 1]

        # اعمال تغییرات
        person_cultural.sardoshi_categories = next_sardoshi
        person_cultural.save()

        # تغییر وضعیت استفاده از ارتقاء
        final_report_card.upgrade_used = True
        final_report_card.save()

        messages.success(request, f'سردوشی فرد با موفقیت به {next_sardoshi} ارتقاء یافت. منتظر تأیید حفاظت باشید.')
        return redirect('user_report_cards', person_id=person_id)

    messages.error(request, 'خطایی رخ داد. لطفاً دوباره تلاش کنید.')
    return redirect('user_report_cards', person_id=person_id)

@login_required
def get_user_avatar(request):
    person = get_object_or_404(Person, user=request.user)
    person_private_info = PersonPrivateInfo.objects.filter(person=person).first()
    avatar_url = person_private_info.pic.url if person_private_info and person_private_info.pic else None
    return JsonResponse({'avatar_url': avatar_url})