
from smtplib import SMTPException
from django.shortcuts import render, get_object_or_404, redirect
from django.views.decorators.csrf import csrf_exempt
from django.contrib.admin.views.decorators import staff_member_required
from django.db.models import Sum, Count
from django.contrib.auth.decorators import login_required
from django.urls import reverse
from django.conf import settings
from django.core.serializers.json import DjangoJSONEncoder
from django.core.exceptions import ValidationError
from django.http import JsonResponse
from django.http import HttpResponse
from .models import Project,Newsletter, UserAccount, tb_teams,tb_eventcate, Donation, UserLogin, UserProfile, ProjectType, ContactMessage, tb_actualitenews, dashboardpicture, tb_eventpostupdate, todolist
from .forms import ContactForm, createadForm, editadminForm, teamupForm, ProjectForm, DonationForm, ActualiteNewsForm, DashImageForm, EventspostForm, LoginForm, eventcateForm, todoForm
import paypalrestsdk, time, requests, json 
from venv import logger
from django.core.mail import send_mail
from django.core.mail import mail_admins
from bokeh.plotting import figure # type: ignore
from bokeh.embed import components
from bokeh.resources import CDN
from decimal import Decimal
from paypal.standard.forms import PayPalPaymentsForm
from datetime import datetime, date
from django.db.models import Prefetch, ProtectedError, Max, Min, Q, Sum, Count, F, OuterRef, Subquery, Exists, IntegerField, Value, When, Case
from django.contrib import messages
from django.views.generic import ListView, DetailView, CreateView, UpdateView, TemplateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.core.paginator import Paginator
from django.core.mail import EmailMultiAlternatives
from django.utils import timezone


 

# Create your views here.

def staff_login_required(view_func):
    def wrapper(request, *args, **kwargs):
        userid = request.session.get('logged_in_userid')
        if not userid:
            return redirect('staff_dash')

        try:
            request.user_obj = UserLogin.objects.get(userid=userid)
        except UserLogin.DoesNotExist:
            del request.session['logged_in_userid']
            return redirect('staff_dash')

        return view_func(request, *args, **kwargs)
    return wrapper

def homepage(request): 
    newsupdate = tb_actualitenews.objects.filter(title__isnull=False).exclude(Q(title__isnull=True) | Q(title__exact='')).order_by('-regdate')[:6]
    dashdatas = dashboardpicture.objects.filter(f_active=1).order_by('rank')[:5]
    event_update = tb_eventpostupdate.objects.all().order_by('-date')[:6]
    event_footer = tb_eventpostupdate.objects.all().order_by('-date')[:3]
    featured_projects = Project.objects.filter(is_active=True).order_by('-created_at')[:6]
    project_types = ProjectType.objects.all()[:6]
    
    projects = Project.objects.filter(current_amount__gt=0, is_active=True)

    labels = []
    current_data = []
    target_data = []

    for project in projects:
        labels.append(project.title)
        current_data.append(float(project.current_amount))  # convert Decimal to float
        target_data.append(float(project.target_amount))

    chart_data = {
        'labels': labels,
        'datasets': [
            {
                'label': 'Current Amount',
                'backgroundColor': '#3b82f6',
                'data': current_data
            },
            {
                'label': 'Target Amount',
                'backgroundColor': '#38bdf8',
                'data': target_data
            }
        ]
    }
    return render(request, 'src/index.html', {'newsupdate': newsupdate, 'dashdatas':dashdatas, 'event_update':event_update, 'featured_projects': featured_projects,
        'project_types': project_types,'event_footer':event_footer, 'chart_data': json.dumps(chart_data, cls=DjangoJSONEncoder)})


def subscribe_newsletter(request):
    if request.method == 'POST':
        email = request.POST.get('subscribe-email')

        if email:
            # Check if the email already exists
            if Newsletter.objects.filter(email=email).exists():
                messages.warning(request, "Vous êtes déjà inscrit à notre newsletter !")
            else:
                Newsletter.objects.create(name=email, email=email)
                messages.success(request, "Vous vous êtes inscrit avec succès à notre newsletter !")
            
            return redirect(request.META.get('HTTP_REFERER', '/'))
    return redirect('/')



def contactUs(request): 

    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]

    if request.method == 'POST':
        name = request.POST.get('name')
        email = request.POST.get('email')
        message = request.POST.get('message')

        send_mail(name, message, 'settings.EMAIL_HOST_USER',
                  [email], fail_silently=False)
        

        # 🔽 Your function logic here (e.g. save to DB, send email)

    return render(request, 'src/contactus.html', {'event_footer':event_footer}) 

def volunteer(request): 

    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]
    event_update = tb_eventpostupdate.objects.all().order_by('-date')[:6]
    if request.method == 'POST':
        name = request.POST.get('name')
        email = request.POST.get('email')
        message = request.POST.get('message')

        send_mail(name, message, 'settings.EMAIL_HOST_USER',
                  [email], fail_silently=False)
        

        # 🔽 Your function logic here (e.g. save to DB, send email)

    return render(request, 'src/volunteer.html', {'event_footer':event_footer,'event_update':event_update }) 

def ourcauses(request):
    featured_projects = Project.objects.all().order_by('-created_at') 
    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]
    return render(request, 'src/ourcauses.html',{'featured_projects':featured_projects,'event_footer':event_footer })

def events(request):

    events_all = tb_eventpostupdate.objects.filter(f_active=1).order_by('-date')

    event_1 = tb_eventcate.objects.filter(id=1)
    event_2 = tb_eventcate.objects.filter(id=2)
    event_3 = tb_eventcate.objects.filter(id=3)
    event_4 = tb_eventcate.objects.filter(id=4)
    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]

    return render(request, 'src/events.html', {'event_1':event_1,'event_2':event_2, 'event_3':event_3, 'event_4':event_4, 'event_footer':event_footer, 'events_all':events_all})


def footer(request):  
    event_footer = tb_eventpostupdate.objects.all().order_by('-date')[:3]
    return render(request, 'src/footer.html', {'event_footer':event_footer})

def donate_us(request):
    event_update = tb_eventpostupdate.objects.all().order_by('-date')[:2]
    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]
    featured_projects = Project.objects.filter(is_active=True).order_by('-created_at')[:4]
    project_types = ProjectType.objects.all()[:6]

    projects = Project.objects.filter(current_amount__gt=0, is_active=True)

    labels = []
    current_data = []
    target_data = []

    for project in projects:
        labels.append(project.title)
        current_data.append(float(project.current_amount))  # convert Decimal to float
        target_data.append(float(project.target_amount))

    chart_data = {
        'labels': labels,
        'datasets': [
            {
                'label': 'Current Amount',
                'backgroundColor': '#3b82f6',
                'data': current_data
            },
            {
                'label': 'Target Amount',
                'backgroundColor': '#38bdf8',
                'data': target_data
            }
        ]
    }
     
    return render(request, 'src/donate-us.html', {'event_update':event_update, 'featured_projects': featured_projects,'event_footer':event_footer,
        'project_types': project_types, 'chart_data': json.dumps(chart_data, cls=DjangoJSONEncoder)})

def event_details(request):  
    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]
    return render(request, 'src/event-details.html', {'event_footer':event_footer})

def about_us(request):  
    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]
    return render(request, 'src/about-us.html',{'event_footer':event_footer})

def user_dash(request):
    # event_update = tb_eventpostupdate.objects.all().order_by('-date') 
    featured_projects = Project.objects.filter(is_active=True).order_by('-created_at')[:4]
    project_types = ProjectType.objects.all()[:6]

    projects = Project.objects.filter(current_amount__gt=0, is_active=True)

    labels = []
    current_data = []
    target_data = []

    for project in projects:
        labels.append(project.title)
        current_data.append(float(project.current_amount))  # convert Decimal to float
        target_data.append(float(project.target_amount))

    chart_data = {
        'labels': labels,
        'datasets': [
            {
                'label': 'Current Amount',
                'backgroundColor': '#3b82f6',
                'data': current_data
            },
            {
                'label': 'Target Amount',
                'backgroundColor': '#38bdf8',
                'data': target_data
            }
        ]
    }

    return render(request, 'src/dashboard/home.html', {'featured_projects': featured_projects,
        'project_types': project_types, 'chart_data': json.dumps(chart_data, cls=DjangoJSONEncoder)})

def team(request):  
    position1="Administrateur Directeur Général"
    team_ceo = tb_teams.objects.filter(position=position1)
    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]

    return render(request, 'src/our-team.html', {'team_ceo': team_ceo, 'event_footer':event_footer})

def contact_view(request):
    if request.method == 'POST':
        upcoming_form = ContactForm(request.POST)
        if upcoming_form.is_valid():
            obj = upcoming_form.save(commit=False)
            obj.save()
            messages.success(request, 'Message Envoyee, un agent seras en contact avec vous')
            return redirect('contact_form')
        else:
            messages.error(request, 'Message non Envoyee, veuiller reessayer.')
            return redirect('contact_form')

    else:
        form = ContactForm()

    return render(request, 'src/contactus.html', {'form': form})

def news_detail(request,id):
    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]
    newsupdate_details = tb_actualitenews.objects.filter(id=id)
    newsupdate24 = get_object_or_404(tb_actualitenews, id=id)

    return render(request, 'src/event-details.html', {'newsupdate_details': newsupdate_details,'newsupdate24':newsupdate24, 'event_footer':event_footer})

def member_detail(request,id):

    memberdet = tb_teams.objects.filter(id=id)
    memberfulldet = get_object_or_404(tb_teams, id=id)
    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]

    return render(request, 'src/memberdetail.html', {'memberdet': memberdet,'memberfulldet':memberfulldet, 'event_footer':event_footer})

def past_newsdetail(request,id):

    newsupdate_details = tb_eventpostupdate.objects.filter(id=id)
    newsupdate24 = get_object_or_404(tb_eventpostupdate, id=id)
    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]

    return render(request, 'src/news-details.html', {'newsupdate_details': newsupdate_details,'newsupdate24':newsupdate24,'event_footer':event_footer })


def project_accom(request):  
    project = tb_eventpostupdate.objects.all().order_by('-date')[:3]
    return render(request, 'src/project_accom.html', {'project':project})


# @login_required(login_url='seconnecter')
def staffdash(request):  
        # Forms initialization
    actualite_form = ActualiteNewsForm()
    dashimage_form = DashImageForm()
    upcoming_form = EventspostForm()
    newmember_form = teamupForm()
    login_form = LoginForm()
    eventcate_form =eventcateForm()


    # Handle POST actions
    if request.method == 'POST':
        # Login check and submission
        if 'login' in request.POST:
            login_form = LoginForm(request.POST)
            if login_form.is_valid():
                userid = login_form.cleaned_data['userid']
                password = login_form.cleaned_data['password']
                try:
                    user = UserLogin.objects.get(userid=userid, password=password)
                    if user.is_active:
                        request.session['logged_in_userid'] = userid
                        return redirect('staff_dash')
                    else:
                        login_form.add_error(None, "Account is not active.")
                except UserLogin.DoesNotExist:
                    login_form.add_error(None, "Invalid userid or password.")

    # If logged in, show user info
    if 'logged_in_userid' in request.session:
        try:
            user = UserLogin.objects.get(userid=request.session['logged_in_userid'])
            context = {
                'user': user,
                'actualite_form': actualite_form,
                'dashimage_form': dashimage_form,
                'upcoming_form': upcoming_form,
                'newmember_form': newmember_form,
                'logged_in': True, 'eventcate_form':eventcate_form
            }
            return render(request, 'src/fnpssdash/index.html', context)
        except UserLogin.DoesNotExist:
            del request.session['logged_in_userid']
            return redirect('staff_dash')

    # If not logged in, show login form
    return render(request, 'src/fnpssdash/index.html', {
        'login_form': login_form,
        'logged_in': False
    })

def logout_view(request):
    request.session.flush()  # Clears all session data
    return redirect('home-page')


#payments views start

class ProjectTypeListView(ListView):
    model = ProjectType
    template_name = 'src/dashboard/project_types.html'
    context_object_name = 'project_types'
    paginate_by = 12
    
    def get_queryset(self):
        return ProjectType.objects.annotate(
            project_count=Count('projects')
        ).order_by('-project_count')

class ProjectListView(ListView):
    model = Project
    template_name = 'src/dashboard/project_list.html'
    context_object_name = 'projects'
    paginate_by = 9
    
    def get_queryset(self):
        queryset = super().get_queryset().filter(is_active=True)
        project_type_id = self.request.GET.get('type')
        if project_type_id:
            queryset = queryset.filter(project_type_id=project_type_id)
        return queryset.select_related('project_type')
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['project_types'] = ProjectType.objects.all()
        return context

class ProjectDetailView(DetailView):
    model = Project
    template_name = 'src/dashboard/project_detail.html'
    context_object_name = 'project'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['donations'] = Donation.objects.filter(project=self.object).order_by('-donation_date')[:5]
        context['total_donors'] = Donation.objects.filter(project=self.object).values('user').distinct().count()
        context['percentage_funded'] = (self.object.current_amount / self.object.target_amount) * 100
        return context

class DonateView(CreateView):
    model = Donation
    form_class = DonationForm
    #form = DonationForm
    template_name = 'src/dashboard/donate.html'
    
    def get_project(self):
        return get_object_or_404(Project, pk=self.kwargs['project_id'], is_active=True)
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['project'] = self.get_project()
        return context
    
    def form_valid(self, form):
        #if self.request.user.is_authenticated:
            request = self.request
            project = self.get_project()
            donation = form.save(commit=False)
            #donation.user = self.request.user
            donation.project = project
            donation.payment_status = 'pending'
            
            try:
                donation.save()  # This ensures the donation has an ID
                return donation_payment_handler(request, donation.id)  #return donation_payment_handler(self.request, donation.id)
                
            except Exception as e:
                # Only delete if the donation was saved (has an ID)
                if donation.pk:
                    try:
                        donation.delete()
                    except Exception as delete_error:
                        logger.error(f"Error deleting donation: {str(delete_error)}")
                
                messages.error(self.request, f'Error processing donation: {str(e)}')
                return self.form_invalid(form)
        #else:
        #    return redirect('account_login')

class CreateProjectView(LoginRequiredMixin, CreateView):
    model = Project
    form_class = ProjectForm
    template_name = 'src/dashboard/project_create.html'
    success_url = reverse_lazy('project_list')
    
    def form_valid(self, form):
        project = form.save(commit=False)
        project.save()
        messages.success(self.request, 'Project created successfully!')
        return super().form_valid(form)

class UpdateProjectView(LoginRequiredMixin, UpdateView):
    model = Project
    form_class = ProjectForm
    template_name = 'src/dashboard/project_update.html'
    
    def get_success_url(self):
        return reverse_lazy('project_detail', kwargs={'pk': self.object.pk})
    
    def form_valid(self, form):
        messages.success(self.request, 'Project updated successfully!')
        return super().form_valid(form)

def home(request):
    featured_projects = Project.objects.filter(is_active=True).order_by('-created_at')[:4]
    project_types = ProjectType.objects.all()[:6]

    projects = Project.objects.filter(current_amount__gt=0, is_active=True)

    labels = []
    current_data = []
    target_data = []

    for project in projects:
        labels.append(project.title)
        current_data.append(float(project.current_amount))  # convert Decimal to float
        target_data.append(float(project.target_amount))

    chart_data = {
        'labels': labels,
        'datasets': [
            {
                'label': 'Current Amount',
                'backgroundColor': '#3b82f6',
                'data': current_data
            },
            {
                'label': 'Target Amount',
                'backgroundColor': '#38bdf8',
                'data': target_data
            }
        ]
    }

    return render(request, 'src/dashboard/home.html', {
        'featured_projects': featured_projects,
        'project_types': project_types, 'chart_data': json.dumps(chart_data, cls=DjangoJSONEncoder)
    })

def donation_payment_handler(request, donation_id):  # donation_payment_handler(request, donation_id):
    try:
        donation = Donation.objects.get(id=donation_id)
        
        # Verify donation is still pending
        if donation.payment_status != 'pending':
            messages.error( 'This donation has already been processed')
            return redirect('project_detail', pk=donation.project.pk)
            
        # Route to the appropriate payment processor
        payment_method = donation.payment_method
        
        if payment_method == 'stripe':
            return stripe_payment(request, donation) #return stripe_payment(request, donation)
        elif payment_method == 'paypal':
            return paypal_payment(request, donation)
        elif payment_method == 'flutterwave':
            return flutterwave_payment(request, donation)
        elif payment_method == 'cinetpay':
            return cinetpay_payment(request, donation)
        else:
            raise ValueError(f"Unsupported payment method: {payment_method}")
            
    except Exception as e:
        # Only clean up if we have a valid donation
        if 'donation' in locals() and donation and donation.pk:
            try:
                project = donation.project
                donation.delete()
                update_project_funding(project)
            except Exception as cleanup_error:
                logger.error(f"Error during donation cleanup: {str(cleanup_error)}")
        
        messages.error( f'Payment processing failed: {str(e)}')
        return redirect('payment_failed', donation_id=donation_id if 'donation' in locals() and donation and donation.pk else 0)

# Stripe Payment
def stripe_payment(request, donation):
    try:
        import stripe
        stripe.api_key = settings.STRIPE_SECRET_KEY
        
        checkout_session = stripe.checkout.Session.create(
            payment_method_types=['card'],
            line_items=[{
                'price_data': {
                    'currency': 'usd',
                    'product_data': {
                        'name': donation.project.title,
                    },
                    'unit_amount': int(donation.amount * 100),
                },
                'quantity': 1,
            }],
            mode='payment',
            success_url=request.build_absolute_uri(
                reverse('payment_success', kwargs={'donation_id': donation.id})
            ),
            cancel_url=request.build_absolute_uri(
                reverse('payment_cancel', kwargs={'donation_id': donation.id})
            ),
            metadata={
                'donation_id': str(donation.id),
                'project_id': str(donation.project.id),
            },
            customer_email=  donation.donator_mail #request.user.email,
        )
        
        return redirect(checkout_session.url)
        
    except Exception as e:
        if donation and donation.pk:
            try:
                project = donation.project
                donation.delete()
                update_project_funding(project)
            except Exception as delete_error:
                logger.error(f"Error cleaning up donation: {str(delete_error)}")
        
        messages.error( f'Failed to process Stripe payment: {str(e)}')
        return redirect('payment_failed', donation_id=donation.id if donation and donation.pk else 0)

# PayPal Payment
def paypal_payment(request, donation):
    try:
        # Get PayPal access token
        auth_response = requests.post(
            f'https://api-m.{"" if settings.PAYPAL_ENVIRONMENT == "live" else "sandbox."}paypal.com/v1/oauth2/token',
            auth=(settings.PAYPAL_CLIENT_ID, settings.PAYPAL_SECRET),
            headers={'Content-Type': 'application/x-www-form-urlencoded'},
            data={'grant_type': 'client_credentials'},
            timeout=10
        )
        auth_response.raise_for_status()
        
        access_token = auth_response.json()['access_token']
        
        # Create PayPal order
        order_data = {
            'intent': 'CAPTURE',
            'purchase_units': [{
                'amount': {
                    'currency_code': 'USD',
                    'value': str(donation.amount)
                },
                'description': f'Donation to {donation.project.title}',
                'custom_id': f'donation_{donation.id}'
            }],
            'application_context': {
                'return_url': request.build_absolute_uri(
                    reverse('payment_success', kwargs={'donation_id': donation.id})
                ),
                'cancel_url': request.build_absolute_uri(
                    reverse('payment_cancel', kwargs={'donation_id': donation.id})
                )
            }
        }
        
        headers = {
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {access_token}'
        }
        
        response = requests.post(
            f'https://api-m.{"" if settings.PAYPAL_ENVIRONMENT == "live" else "sandbox."}paypal.com/v2/checkout/orders',
            headers=headers,
            data=json.dumps(order_data),
            timeout=10
        )
        response.raise_for_status()
        
        for link in response.json()['links']:
            if link['rel'] == 'approve':
                return redirect(link['href'])
                
        raise Exception('No approval link found')
        
    except Exception as e:
        # Clean up on failure
        project = donation.project
        donation.delete()
        update_project_funding(project)
        
        messages.error( 'Failed to process PayPal payment')
        return redirect('payment_failed', donation_id=donation.id)

# Flutterwave Payment
def flutterwave_payment(request, donation):
    try:
        tx_ref = f'donation_{donation.id}_{int(time.time())}'
        headers = {
            'Authorization': f'Bearer {settings.FLUTTERWAVE_SECRET_KEY}',
            'Content-Type': 'application/json'
        }
        
        payload = {
            'tx_ref': tx_ref,
            'amount': str(donation.amount),
            'currency': 'USD',
            'payment_options': 'card,account,ussd',
            'redirect_url': request.build_absolute_uri(
                reverse('flutterwave_callback', kwargs={'donation_id': donation.id})
            ),
            'customer': {
                'email': donation.donator_mail, #request.user.email,
                'name':  donation.donator_name, #request.user.get_full_name() or request.user.username,
            },
            'customizations': {
                'title': donation.project.title,
                'description': f'Donation to {donation.project.title}',
            }
        }
        
        response = requests.post(
            'https://api.flutterwave.com/v3/payments',
            headers=headers,
            json=payload,
            timeout=10
        )
        response.raise_for_status()
        
        donation.transaction_reference = tx_ref
        donation.save()
        
        return redirect(response.json()['data']['link'])
        
    except Exception as e:
        # Clean up on failure
        if donation and donation.pk:
            try:
                project = donation.project
                donation.delete()
                update_project_funding(project)
                return redirect('payment_failed', donation_id=donation.id)
            except Exception as cleanup_error:
                logger.error(f"Error during donation cleanup: {str(cleanup_error)}")
        
        messages.error(request, 'Failed to process Flutterwave payment')
        return redirect('payment_failed', donation_id=0)  # Use 0 if no valid donation ID

# CinetPay Payment
def cinetpay_payment(request, donation):
    try:
        import hashlib
        import time
        
        # 1. Validate CinetPay settings
        if not settings.CINETPAY_API_KEY or not settings.CINETPAY_SITE_ID:
            raise Exception("CinetPay API key or site ID missing")

        # 2. Generate a unique transaction ID
        transaction_id = f"don_{donation.id}_{int(time.time())}"

        # 3. Format amount based on currency
        if settings.CINETPAY_CURRENCY == "XOF":
            amount = int(float(donation.amount))  # XOF must be integer
        else:
            amount = int(donation.amount)

        # 4. Validate phone number (required for mobile money)
        #phone = request.user.tel or "+225000000000"  # Default fallback
        #if not phone.startswith("+"):
        #    phone = f"+225{phone.lstrip('225')}"  # Force Ivory Coast format

        # 5. Generate the SHA-256 signature (MUST BE IN THIS ORDER)
        signature_data = f"{settings.CINETPAY_API_KEY}{settings.CINETPAY_SITE_ID}{transaction_id}{amount}{settings.CINETPAY_CURRENCY}"
        signature = hashlib.sha256(signature_data.encode()).hexdigest()

        # 6. Build the payload (all required fields)
        payload = {
            "apikey": settings.CINETPAY_API_KEY,
            "site_id": settings.CINETPAY_SITE_ID,
            "transaction_id": transaction_id,
            "amount": amount,
            "currency": settings.CINETPAY_CURRENCY,
            "description": f"Donation to {donation.project.title}",
            "return_url": request.build_absolute_uri(
                reverse("cinetpay_callback", kwargs={"donation_id": donation.id})
            ),
            "notify_url": request.build_absolute_uri(reverse("cinetpay_webhook")),
            "customer_name":  donation.donator_name, #request.user.fullname or request.user.username,
            "customer_email": donation.donator_mail,#request.user.email,
            "customer_phone_number": donation.donator_tel, # phone,  # Must be valid
            "customer_address": "Not provided",
            "customer_city": "Not provided",
            "customer_country": "CD",  # Default to Ivory Coast
            "channels": "ALL",  # Allow all payment methods
            "metadata": json.dumps({"donation_id": str(donation.id)}),  # THIS IS THE FIX
            "signature": signature,
        }

        # 7. Make the API request
        headers = {"Content-Type": "application/json"}
        response = requests.post(
            "https://api-checkout.cinetpay.com/v2/payment",
            json=payload,
            headers=headers,
            timeout=30,
        )

        # 8. Check for HTTP errors (400, 500, etc.)
        response.raise_for_status()
        data = response.json()

        # 9. Verify CinetPay's response code
        if data.get("code") != "201":
            error_msg = data.get("message", "Unknown CinetPay error")
            raise Exception(f"CinetPay API error: {error_msg}")

        # 10. Update donation record
        donation.transaction_reference = transaction_id
        donation.payment_metadata = {
            "request_payload": payload,
            "api_response": data,
        }
        donation.save()

        # 11. Redirect to CinetPay payment page
        return redirect(data["data"]["payment_url"])

    except requests.exceptions.HTTPError as e:
        logger.error(f"CinetPay HTTP Error: {e.response.text}")
        error_msg = "CinetPay rejected the request (check logs)"
    except Exception as e:
        logger.error(f"CinetPay Error: {str(e)}", exc_info=True)
        error_msg = str(e)

    # Clean up failed donation
    if donation.pk:
        donation.delete()

    messages.error( f"Payment failed: {error_msg}")
    return redirect("payment_failed", donation_id=donation.id if donation.pk else 0)

# Callback and Webhook Handlers
@csrf_exempt
def stripe_webhook(request):
    payload = request.body
    sig_header = request.META.get('HTTP_STRIPE_SIGNATURE')
    event = None

    try:
        import stripe
        stripe.api_key = settings.STRIPE_SECRET_KEY
        
        event = stripe.Webhook.construct_event(
            payload, sig_header, settings.STRIPE_WEBHOOK_SECRET
        )
    except ValueError as e:
        # Invalid payload
        return HttpResponse(status=400)
    except stripe.error.SignatureVerificationError as e:
        # Invalid signature
        return HttpResponse(status=400)
    except Exception as e:
        return HttpResponse(status=400)

    # Handle the checkout.session.completed event
    if event['type'] == 'checkout.session.completed':
        session = event['data']['object']
        
        try:
            donation_id = session['metadata']['donation_id']
            donation = Donation.objects.get(id=donation_id)
            
            # Verify payment is successful
            if session.payment_status == 'paid':
                donation.payment_status = 'completed'
                donation.transaction_reference = session.payment_intent
                donation.save()
                update_project_funding(donation.project)
        except Donation.DoesNotExist:
            pass
        except Exception as e:
            logger.error(f"Error processing Stripe webhook: {str(e)}")

    return HttpResponse(status=200)

@csrf_exempt
def flutterwave_callback(request, donation_id):
    """Handle Flutterwave payment callback (user redirect back to site)"""
    try:
        donation = Donation.objects.get(id=donation_id)
        transaction_id = request.GET.get('transaction_id')
        
        if not transaction_id:
            raise Exception('No transaction ID provided in callback')

        # Verify transaction with Flutterwave
        headers = {
            'Authorization': f'Bearer {settings.FLUTTERWAVE_SECRET_KEY}',
            'Content-Type': 'application/json'
        }

        response = requests.get(
            f'https://api.flutterwave.com/v3/transactions/{transaction_id}/verify',
            headers=headers,
            timeout=15
        )
        
        logger.info(f"Flutterwave Verification Response: {response.text}")
        response.raise_for_status()
        verification = response.json()

        # Successful payment
        if verification['data']['status'] == 'successful':
            # Verify amount matches
            if Decimal(str(verification['data']['amount'])) != Decimal(str(donation.amount)):
                raise Exception(f"Amount mismatch: Expected {donation.amount}, got {verification['data']['amount']}")

            donation.payment_status = 'completed'
            donation.transaction_reference = transaction_id
            donation.payment_metadata = json.dumps(verification)
            donation.save()
            update_project_funding(donation.project)
            return redirect('payment_success', donation_id=donation.id)
        
        # Payment failed or pending - delete donation
        error_msg = verification.get('message', verification['data'].get('processor_response', 'Payment failed'))
        logger.warning(f"Flutterwave payment not confirmed: {error_msg}")
        
        project = donation.project
        donation.delete()
        update_project_funding(project)
        messages.error(request, f"Payment failed: {error_msg}")
        return redirect('project_detail', pk=project.pk)

    except Donation.DoesNotExist:
        logger.error(f"Donation {donation_id} not found")
        messages.error(request, "Donation record not found")
        return redirect('home')
        
    except requests.exceptions.RequestException as e:
        logger.error(f"Flutterwave API request failed: {str(e)}")
        if 'donation' in locals() and donation.pk:
            project = donation.project
            donation.delete()
            update_project_funding(project)
        messages.error(request, "Payment verification failed. Please contact support.")
        return redirect('project_detail', pk=project.pk if 'project' in locals() else 0)
        
    except Exception as e:
        logger.error(f"Flutterwave callback error: {str(e)}", exc_info=True)
        if 'donation' in locals() and donation.pk:
            project = donation.project
            donation.delete()
            update_project_funding(project)
        messages.error(request, "An unexpected error occurred during payment processing")
        return redirect('project_detail', pk=project.pk if 'project' in locals() else 0)


@csrf_exempt
def flutterwave_webhook(request):
    """Handle Flutterwave server-to-server webhook notifications"""
    if request.method != 'POST':
        return HttpResponse(status=405)

    try:
        payload = json.loads(request.body.decode('utf-8'))
        logger.info(f"Flutterwave Webhook Payload: {payload}")

        # Verify webhook signature for security
        secret_hash = settings.FLUTTERWAVE_WEBHOOK_HASH
        signature = request.headers.get('verif-hash')
        
        if secret_hash and signature != secret_hash:
            logger.error("Invalid webhook signature")
            return HttpResponse(status=401)

        # Required fields validation
        required_fields = ['id', 'tx_ref', 'status', 'amount']
        if not all(field in payload for field in required_fields):
            logger.error("Missing required fields in webhook payload")
            return HttpResponse(status=400)

        transaction_id = payload['id']
        transaction_ref = payload['tx_ref']
        status = payload['status']
        amount = payload['amount']

        # Find donation by transaction reference (stored in donation.transaction_reference)
        try:
            donation = Donation.objects.get(
                transaction_reference=transaction_ref,
                payment_status='pending'
            )
        except Donation.DoesNotExist:
            logger.error(f"Donation not found for transaction: {transaction_ref}")
            return HttpResponse(status=404)

        # Successful payment
        if status == 'successful':
            # Verify amount matches
            if Decimal(str(payload['amount'])) != Decimal(str(donation.amount)):
                logger.error(f"Amount mismatch for donation {donation.id}")
                return HttpResponse(status=400)

            donation.payment_status = 'completed'
            donation.payment_metadata = json.dumps(payload)
            donation.save()
            update_project_funding(donation.project)
            logger.info(f"Payment completed for donation {donation.id}")
            return HttpResponse(status=200)
        
        # Payment failed - delete donation
        logger.warning(f"Payment failed for donation {donation.id}")
        donation.delete()
        update_project_funding(donation.project)
        return HttpResponse(status=200)

    except json.JSONDecodeError:
        logger.error("Invalid JSON in webhook payload")
        return HttpResponse(status=400)
        
    except Donation.DoesNotExist:
        logger.error("Donation not found during webhook processing")
        return HttpResponse(status=404)
        
    except requests.exceptions.RequestException as e:
        logger.error(f"Request error during verification: {str(e)}")
        return HttpResponse(status=502)
        
    except Exception as e:
        logger.error(f"Webhook processing error: {str(e)}", exc_info=True)
        return HttpResponse(status=500)

@csrf_exempt
def cinetpay_callback(request, donation_id):
    """Handle CinetPay payment callback (user redirect back to site)"""
    try:
        donation = Donation.objects.get(id=donation_id)
        transaction_id = request.GET.get('cpm_trans_id') or request.POST.get('cpm_trans_id')
        
        if not transaction_id:
            raise Exception('No transaction ID provided in callback')

        # Verify transaction with CinetPay
        verification_data = {
            "apikey": settings.CINETPAY_API_KEY,
            "site_id": settings.CINETPAY_SITE_ID,
            "transaction_id": transaction_id
        }

        headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
            'Authorization': f'Bearer {settings.CINETPAY_API_KEY}'
        }

        response = requests.post(
            'https://api-checkout.cinetpay.com/v2/transaction/check',
            headers=headers,
            json=verification_data,
            timeout=30
        )
        
        logger.info(f"CinetPay Verification Response: {response.text}")
        response.raise_for_status()
        verification = response.json()

        # Successful payment
        if verification.get('code') == '00' and verification['data']['status'] == 'ACCEPTED':
            donation.payment_status = 'completed'
            donation.transaction_reference = transaction_id
            donation.payment_metadata = json.dumps(verification)
            donation.save()
            update_project_funding(donation.project)
            return redirect('payment_success', donation_id=donation.id)
        
        # Payment failed or pending - delete donation
        error_msg = verification.get('message', 'Payment not confirmed')
        logger.warning(f"CinetPay payment not confirmed: {error_msg}")
        
        project = donation.project
        donation.delete()
        update_project_funding(project)
        messages.error(request, f"Payment failed: {error_msg}")
        return redirect('project_detail', pk=project.pk)

    except Donation.DoesNotExist:
        logger.error(f"Donation {donation_id} not found")
        messages.error(request, "Donation record not found")
        return redirect('home')
        
    except requests.exceptions.RequestException as e:
        logger.error(f"CinetPay API request failed: {str(e)}")
        if 'donation' in locals() and donation.pk:
            project = donation.project
            donation.delete()
            update_project_funding(project)
        messages.error(request, "Payment verification failed. Please contact support.")
        return redirect('project_detail', pk=project.pk if 'project' in locals() else 0)
        
    except Exception as e:
        logger.error(f"CinetPay callback error: {str(e)}", exc_info=True)
        if 'donation' in locals() and donation.pk:
            project = donation.project
            donation.delete()
            update_project_funding(project)
        messages.error(request, "An unexpected error occurred during payment processing")
        return redirect('project_detail', pk=project.pk if 'project' in locals() else 0)


@csrf_exempt
def cinetpay_webhook(request):
    """Handle CinetPay server-to-server webhook notifications"""
    if request.method != 'POST':
        return HttpResponse(status=405)

    try:
        payload = json.loads(request.body.decode('utf-8'))
        logger.info(f"CinetPay Webhook Payload: {payload}")

        # Required fields validation
        required_fields = ['cpm_trans_id', 'cpm_site_id', 'cpm_result', 'cpm_amount', 'cpm_currency']
        if not all(field in payload for field in required_fields):
            logger.error("Missing required fields in webhook payload")
            return HttpResponse(status=400)

        transaction_id = payload['cpm_trans_id']
        site_id = payload['cpm_site_id']
        status = payload['cpm_result']
        amount = payload['cpm_amount']
        currency = payload['cpm_currency']

        if site_id != settings.CINETPAY_SITE_ID:
            logger.error(f"Invalid site ID in webhook: {site_id}")
            return HttpResponse(status=400)

        # Find donation
        try:
            donation = Donation.objects.get(
                transaction_reference=transaction_id,
                payment_status='pending'
            )
        except Donation.DoesNotExist:
            logger.error(f"Donation not found for transaction: {transaction_id}")
            return HttpResponse(status=404)

        # Verify transaction with CinetPay
        verification_data = {
            "apikey": settings.CINETPAY_API_KEY,
            "site_id": settings.CINETPAY_SITE_ID,
            "transaction_id": transaction_id
        }

        headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
            'Authorization': f'Bearer {settings.CINETPAY_API_KEY}'
        }

        response = requests.post(
            'https://api-checkout.cinetpay.com/v2/transaction/check',
            headers=headers,
            json=verification_data,
            timeout=30
        )
        
        logger.info(f"CinetPay Webhook Verification: {response.text}")
        response.raise_for_status()
        verification = response.json()

        # Successful payment
        if verification.get('code') == '00' and verification['data']['status'] == 'ACCEPTED':
            donation.payment_status = 'completed'
            donation.payment_metadata = json.dumps({
                'webhook': payload,
                'verification': verification
            })
            donation.save()
            update_project_funding(donation.project)
            logger.info(f"Payment completed for donation {donation.id}")
            return HttpResponse(status=200)
        
        # Payment failed - delete donation
        logger.warning(f"Payment failed for donation {donation.id}")
        donation.delete()
        update_project_funding(donation.project)
        return HttpResponse(status=200)

    except json.JSONDecodeError:
        logger.error("Invalid JSON in webhook payload")
        return HttpResponse(status=400)
        
    except Donation.DoesNotExist:
        logger.error("Donation not found during webhook processing")
        return HttpResponse(status=404)
        
    except requests.exceptions.RequestException as e:
        logger.error(f"Request error during verification: {str(e)}")
        return HttpResponse(status=502)
        
    except Exception as e:
        logger.error(f"Webhook processing error: {str(e)}", exc_info=True)
        return HttpResponse(status=500)

def update_project_funding(project):
    project.current_amount = Donation.objects.filter(
        project=project, 
        payment_status='completed'
    ).aggregate(total=Sum('amount'))['total'] or 0
    project.save()

class PaymentSuccessView(DetailView):
    model = Donation
    template_name = 'src/dashboard/success.html'
    context_object_name = 'donation'
    
    def get_object(self):
        donation = get_object_or_404(Donation, id=self.kwargs['donation_id'])
        
        # For PayPal IPN which might not have updated status yet
        if donation.payment_status != 'completed':
            donation.payment_status = 'completed'
            donation.save()
            # Update project funding
            self.update_project_funding(donation.project)
        
        return donation
    
    def update_project_funding(self, project):
        project.current_amount = Donation.objects.filter(
            project=project, 
            payment_status='completed'
        ).aggregate(total=Sum('amount'))['total'] or 0
        project.save()

class PaymentFailedView(DetailView):
    model = Donation
    template_name = 'src/dashboard/failed.html'
    context_object_name = 'donation'
    
    def get_object(self):
        try:
            donation_id = self.kwargs.get('donation_id')
            if donation_id and donation_id != '0':
                return get_object_or_404(Donation, id=donation_id)
            return None
        except Exception:
            return None
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['error_message'] = self.request.GET.get('error', 'Payment processing failed')
        return context

class PaymentCancelView(DetailView):
    model = Donation
    template_name = 'src/dashboard/cancel.html'
    context_object_name = 'donation'
    
    def get_object(self):
        donation = get_object_or_404(Donation, id=self.kwargs['donation_id'])
        
        # Only update status if still pending
        if donation.payment_status == 'pending':
            donation.payment_status = 'canceled'
            donation.save()
        
        return donation
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['cancel_reason'] = self.request.GET.get('reason', 'Payment was canceled by user')
        return context

class UserProfileView(LoginRequiredMixin, TemplateView):
    template_name = 'src/dashboard/profile.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        user = self.request.user
        
        # Get all donations by this user with related projects
        donations = Donation.objects.filter(
            user=user,
            payment_status='completed'
        ).select_related('project').order_by('-donation_date')
        
        # Calculate total donated amount
        total_donated = donations.aggregate(total=Sum('amount'))['total'] or 0
        total_points = (donations.aggregate(total=Sum('amount'))['total'] or 0) / 80
        
        # Group donations by project with amounts
        projects_donated = {}
        for donation in donations:
            if donation.project.id not in projects_donated:
                projects_donated[donation.project.id] = {
                    'project': donation.project,
                    'total_donated': Decimal('0'),
                    'donations': []
                }
            projects_donated[donation.project.id]['total_donated'] += donation.amount
            projects_donated[donation.project.id]['donations'].append(donation)
        
        # Get most recent project (could be any project, not necessarily one they donated to)
        recent_project = Project.objects.filter(is_active=True).order_by('-created_at').first()
        
        context.update({
            'user': user,
            'total_donated': total_donated,
            'total_points': total_points,
            'projects_donated': projects_donated.values(),
            'recent_project': recent_project
        })
        return context
    
class yenu(LoginRequiredMixin, TemplateView):
    template_name = 'src/dashboard/yenu.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        user = self.request.user
        
        # Get all donations by this user with related projects
        donations = Donation.objects.filter(
            user=user,
            payment_status='completed'
        ).select_related('project').order_by('-donation_date')
        
        # Calculate total donated amount
        total_donated = donations.aggregate(total=Sum('amount'))['total'] or 0
        total_points = (donations.aggregate(total=Sum('amount'))['total'] or 0) / 80
        
        # Group donations by project with amounts
        projects_donated = {}
        for donation in donations:
            if donation.project.id not in projects_donated:
                projects_donated[donation.project.id] = {
                    'project': donation.project,
                    'total_donated': Decimal('0'),
                    'donations': []
                }
            projects_donated[donation.project.id]['total_donated'] += donation.amount
            projects_donated[donation.project.id]['donations'].append(donation)
        
        # Get most recent project (could be any project, not necessarily one they donated to)
        recent_project = Project.objects.filter(is_active=True).order_by('-created_at').first()
        
        context.update({
            'user': user,
            'total_donated': total_donated,
            'total_points': total_points,
            'projects_donated': projects_donated.values(),
            'recent_project': recent_project
        })
        return context

def searchany(request):
    query = ""
    projects = Project.objects.none()
    events = tb_eventpostupdate.objects.none()

    if request.method == "POST":
        query = request.POST.get("search-field", "").strip()

        if query:
            # split input into words
            keywords = query.split()

            project_q = Q()
            event_q = Q()

            for word in keywords:
                project_q |= (
                    Q(title__icontains=word) |
                    Q(description__icontains=word)
                )

                event_q |= (
                    Q(title__icontains=word) |
                    Q(textdisplay1__icontains=word) |
                    Q(textdisplay2__icontains=word) |
                    Q(textdisplay3__icontains=word) |
                    Q(textdisplay4__icontains=word)
                )

            projects = Project.objects.filter(project_q)
            events = tb_eventpostupdate.objects.filter(event_q)
            
    return render(request, "src/search_result.html", {
        "query": query,
        "projects": projects,
        "events": events,
    })

@staff_login_required
def dash_events(request):
    user = request.user_obj  
    event_display = tb_eventpostupdate.objects.filter(f_active=True).order_by('-id')
    return render(request, 'src/fnpssdash/events.html', {'user': user,'logged_in': True,'event_display':event_display})

@staff_login_required
def makevents(request):
    user = request.user_obj

    if 'saveupcoming' in request.POST:
        upcoming_form = EventspostForm(request.POST, request.FILES)
        if upcoming_form.is_valid():
            max_rank = tb_eventpostupdate.objects.aggregate(Max('rank'))['rank__max'] or 0
            obj = upcoming_form.save(commit=False)
            obj.rank = max_rank + 1
            obj.save()
            messages.success(request, 'Données enregistrées avec succès')
            return redirect('dash_events')
        else:
            messages.error(request, 'Données non enregistrées, veuillez réessayer')
            return redirect('staff_dash')

    else:
        form = EventspostForm()

    return render(request, 'src/fnpssdash/create-an-event.html', {'form': form, 'user': user,'logged_in': True})

@staff_login_required
def modifyevents(request, id):

    eventproject = get_object_or_404(tb_eventpostupdate, id=id)
    user = request.user_obj

    if 'saveupcoming' in request.POST:
        upcoming_form = EventspostForm(request.POST, request.FILES, instance=eventproject)
        if upcoming_form.is_valid():
            max_rank = tb_eventpostupdate.objects.aggregate(Max('rank'))['rank__max'] or 0
            obj = upcoming_form.save(commit=False)
            obj.rank = max_rank + 1
            obj.save()
            messages.success(request, 'Données enregistrées avec succès')
            return redirect('dash_events')
        else:
            messages.error(request, 'Données non enregistrées, veuillez réessayer')
            return redirect('staff_dash')

    else:
        form = EventspostForm(instance=eventproject)

    return render(request, 'src/fnpssdash/edit-an-event.html', {'user': user,'logged_in': True,'form': form})
@staff_login_required
def dash_event_details(request,id):
    user = request.user_obj
    newsupdate_details = tb_eventpostupdate.objects.filter(id=id)
    newsupdate24 = get_object_or_404(tb_eventpostupdate, id=id)
    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]

    return render(request, 'src/fnpssdash/event-details.html', {'user': user,'logged_in': True,'newsupdate_details': newsupdate_details,'newsupdate24':newsupdate24,'event_footer':event_footer })

@staff_login_required
def dash_contact(request): 
    user = request.user_obj 
    message_display = ContactMessage.objects.all().order_by('-id')
    return render(request, 'src/fnpssdash/inbox.html', {'message_display':message_display, 'user': user,'logged_in': True})


@staff_login_required
def dash_read_message(request,id):
    user = request.user_obj
    mail_details = ContactMessage.objects.filter(id=id)
    newsupdate24 = get_object_or_404(tb_eventpostupdate, id=id)
    event_footer = tb_eventpostupdate.objects.order_by('-date')[:3]

    return render(request, 'src/fnpssdash/read-email.html', {'user': user,'logged_in': True,'mail_details': mail_details,'newsupdate24':newsupdate24,'event_footer':event_footer })

@staff_login_required
def dash_contactDonors(request): 
    user = request.user_obj 
    donor_display = Donation.objects.all().order_by('-id')
    return render(request, 'src/fnpssdash/contacts.html', {'donor_display':donor_display, 'user': user,'logged_in': True})

@staff_login_required
def createadmin(request):
    user = request.user_obj

    if 'createadmin' in request.POST:
        upcoming_form = createadForm(request.POST)
        role = request.POST.get('adminsrole')

        if upcoming_form.is_valid():
            obj = upcoming_form.save(commit=False)
            obj.role = role
            obj.save()
            messages.success(request, 'Données enregistrées avec succès')
            return redirect('dash_userlist')
        else:
            messages.error(request, 'Données non enregistrées, veuillez réessayer')
            return redirect('createadmin')

    else:
        form = createadForm()

    return render(request, 'src/fnpssdash/add-user.html', {'form': form, 'user': user,'logged_in': True})

@staff_login_required
def dash_userlist(request):
    user = request.user_obj  
    donor_display = UserLogin.objects.all().order_by('-id')
    return render(request, 'src/fnpssdash/users-list.html', {'donor_display':donor_display, 'user': user,'logged_in': True})



@staff_login_required
def makemployee(request):

    user = request.user_obj

    if 'makemployee' in request.POST:
        upcoming_form = teamupForm(request.POST, request.FILES)
        department = request.POST.get('department')
        position = request.POST.get('position')

        if upcoming_form.is_valid():
            obj = upcoming_form.save(commit=False)
            obj.department = department
            obj.position = position
            obj.save()
            messages.success(request, 'Données enregistrées avec succès')
            return redirect('dash_employeelist')
        else:
            messages.error(request, 'Données non enregistrées, veuillez réessayer')
            return redirect('makemployee')

    else:
        form = teamupForm()

    return render(request, 'src/fnpssdash/add-new-employee.html', {'form': form, 'user': user,'logged_in': True})

@staff_login_required
def editemployee(request, id):

    eventproject = get_object_or_404(tb_teams, id=id)
    user = request.user_obj

    if 'makemployee' in request.POST:
        upcoming_form = teamupForm(request.POST,  request.FILES, instance=eventproject)
        department = request.POST.get('department')
        position = request.POST.get('position')

        if upcoming_form.is_valid():
            obj = upcoming_form.save(commit=False)
            obj.department = department
            obj.position = position
            obj.save()
            messages.success(request, 'Données enregistrées avec succès')
            return redirect('dash_employeelist')
        else:
            messages.error(request, 'Données non enregistrées, veuillez réessayer')
            return redirect('editemployee')

    else:
        form = teamupForm(instance=eventproject)

    return render(request, 'src/fnpssdash/edit-new-employee.html', {'form': form, 'user': user,'logged_in': True})


@staff_login_required
def dash_employeelist(request): 
    user = request.user_obj 
    donor_display = tb_teams.objects.all().order_by('-id')
    return render(request, 'src/fnpssdash/employee-list.html', {'donor_display':donor_display, 'user': user,'logged_in': True})

@staff_login_required
def dash_policy(request): 
    user = request.user_obj 
    donor_display = tb_teams.objects.all().order_by('-id')
    return render(request, 'src/fnpssdash/privacy-policy.html', {'donor_display':donor_display, 'user': user,'logged_in': True})

@staff_login_required
def dash_todolist(request): 
    user = request.user_obj 
    donor_display = todolist.objects.filter(is_active=True).order_by('-id')
    form = todoForm()
    return render(request, 'src/fnpssdash/to-do-list.html', {'form':form, 'donor_display':donor_display, 'user': user,'logged_in': True})


@staff_login_required
def editadmin(request, id):
    user = request.user_obj
    eventproject = get_object_or_404(UserLogin, id=id)

    if 'createadmin' in request.POST:
        upcoming_form = editadminForm(request.POST, instance=eventproject)
        #role = request.POST.get('adminsrole')
        if upcoming_form.is_valid():
            obj = upcoming_form.save(commit=False)
            obj.save()
            messages.success(request, 'Données enregistrées avec succès')
            return redirect('dash_userlist')
        else:
            messages.error(request, 'Données non enregistrées, veuillez réessayer')
            return redirect('createadmin')

    else:
        form = editadminForm(instance=eventproject)

    return render(request, 'src/fnpssdash/edit-user.html', {'form': form, 'user': user,'logged_in': True})


@staff_login_required
def maketodo(request):

    user = request.user_obj

    if 'registertodo' in request.POST:
        upcoming_form = todoForm(request.POST, request.FILES)
        priority = request.POST.get('priority')
        status = request.POST.get('status')

        if upcoming_form.is_valid():
            obj = upcoming_form.save(commit=False)
            obj.priority = priority
            obj.status = status
            obj.adminid = UserLogin(user.id)
            obj.save()
            messages.success(request, 'Données enregistrées avec succès')
            return redirect('dash_todolist')
        else:
            messages.error(request, 'Données non enregistrées, veuillez réessayer')
            return redirect('dash_todolist')

    else:
        form = todoForm()

    return render(request, 'src/fnpssdash/to-do-list.html', {'form': form, 'user': user,'logged_in': True})

@staff_login_required
def delete_event(request, id):
    user = request.user_obj
    obj = get_object_or_404(tb_eventpostupdate, id=id)

    obj.f_active = False
    obj.his_delete_date = timezone.now()
    obj.delete_userid = UserAccount(user.id)  # if you're using custom user
    obj.save()

    return redirect('dash_events')  # change this


def delete_todo(request, id):
    obj = get_object_or_404(todolist, id=id)

    obj.is_active = False
    obj.save()

    return redirect('dash_todolist')

def update_todo_both(request, id):
    if request.method == "POST":
        obj = get_object_or_404(todolist, id=id)

        obj.status = request.POST.get('status')
        obj.priority = request.POST.get('priority')

        obj.save()

    return redirect('dash_todolist')

def update_admin_role(request, id):
    if request.method == "POST":
        obj = get_object_or_404(UserLogin, id=id)

        obj.role = request.POST.get('role')
        obj.save()
    
    else:
        messages.error(request, 'Données non enregistrées, veuillez réessayer')
        return redirect('dash_userlist')

    return redirect('dash_userlist')

