from django import forms
from django.contrib import admin,messages
from django.http import JsonResponse
from django.urls import path
from django.utils import timezone
from apps.accounts.models import User
from .models import *

def eligible_members(event):
 queryset=User.objects.filter(member_profile__status='ACTIVE').select_related('member_profile','campus').order_by('member_profile__first_name','member_profile__last_name')
 return queryset if event and event.scope==ServiceEvent.Scope.NATIONAL else queryset.filter(member_profile__campus=event.campus) if event else queryset.none()

class MemberChoiceField(forms.ModelChoiceField):
 def label_from_instance(self,user):
  member=user.member_profile;name=' '.join(part for part in (member.first_name,member.other_names,member.last_name) if part)
  return f'{name} · {member.primary_phone}'

class AttendanceAdminForm(forms.ModelForm):
 member=MemberChoiceField(queryset=User.objects.none(),help_text='Select an event first. Campus events show only members from that campus; national events show all members.')
 class Meta:model=Attendance;fields='__all__'
 def __init__(self,*args,**kwargs):
  super().__init__(*args,**kwargs);event=self.instance.event if self.instance.pk else None;event_id=self.data.get('event') or self.initial.get('event')
  if event_id and not event:event=ServiceEvent.objects.filter(pk=event_id).first()
  self.fields['member'].queryset=eligible_members(event)
 def clean(self):
  cleaned=super().clean();event=cleaned.get('event');member=cleaned.get('member')
  if event and member and event.scope==ServiceEvent.Scope.CAMPUS and member.member_profile.campus_id!=event.campus_id:self.add_error('member',f'Select a member from {event.campus}.')
  return cleaned

class ServiceEventAdminForm(forms.ModelForm):
 class Meta:model=ServiceEvent;fields='__all__'
 def clean(self):
  cleaned=super().clean()
  if cleaned.get('scope')==ServiceEvent.Scope.CAMPUS and not cleaned.get('campus'):self.add_error('campus','Campus is required for a campus event.')
  if cleaned.get('scope')==ServiceEvent.Scope.NATIONAL:cleaned['campus']=None
  return cleaned

@admin.register(Announcement)
class AnnouncementAdmin(admin.ModelAdmin):list_display=('title','audience','campus','pinned','published','published_at');list_filter=('published','pinned','audience','campus');search_fields=('title','body');list_editable=('pinned','published')
@admin.register(ForumTopic)
class ForumTopicAdmin(admin.ModelAdmin):list_display=('title','visibility','campus','author','allow_replies','pinned','updated_at');list_filter=('visibility','campus','allow_replies','pinned');search_fields=('title','body','author__first_name');list_editable=('allow_replies','pinned')
@admin.register(ForumReply)
class ForumReplyAdmin(admin.ModelAdmin):list_display=('topic','author','created_at');search_fields=('body','author__first_name','topic__title')
@admin.register(ServiceEvent)
class ServiceEventAdmin(admin.ModelAdmin):
 form=ServiceEventAdminForm;list_display=('title','event_type','scope','campus','starts_at','registration_open','attendance_total');list_filter=('scope','event_type','campus','registration_open');search_fields=('title','venue');date_hierarchy='starts_at'
 def attendance_total(self,o):return o.registrations.count()
@admin.register(Attendance)
class AttendanceAdmin(admin.ModelAdmin):
 form=AttendanceAdminForm;list_display=('member_display','event','event_campus','registered_at','checked_in');list_filter=('checked_in','event__event_type','event__scope','event__campus');search_fields=('member__member_profile__first_name','member__member_profile__last_name','member__phone_number','event__title');list_editable=('checked_in',);list_select_related=('member','member__member_profile','event','event__campus')
 @admin.display(description='Member',ordering='member__member_profile__first_name')
 def member_display(self,obj):return MemberChoiceField(queryset=User.objects.none()).label_from_instance(obj.member)
 @admin.display(description='Campus',ordering='event__campus__name')
 def event_campus(self,obj):return obj.event.campus or 'National'
 def get_urls(self):return [path('member-options/',self.admin_site.admin_view(self.member_options),name='engagement_attendance_member_options')]+super().get_urls()
 def member_options(self,request):
  event=ServiceEvent.objects.filter(pk=request.GET.get('event')).first();field=MemberChoiceField(queryset=User.objects.none())
  return JsonResponse({'members':[{'id':user.pk,'label':field.label_from_instance(user)} for user in eligible_members(event)]})
 class Media:js=('admin/js/attendance-member-filter.js',)
@admin.register(Sermon)
class SermonAdmin(admin.ModelAdmin):list_display=('title','preacher','preached_on','campus','published');list_filter=('published','campus','preached_on');search_fields=('title','preacher','scripture');list_editable=('published',)
@admin.register(GalleryItem)
class GalleryAdmin(admin.ModelAdmin):list_display=('title','campus','captured_at','published');list_filter=('published','campus');search_fields=('title','caption');list_editable=('published',)
@admin.register(Broadcast)
class BroadcastAdmin(admin.ModelAdmin):
 list_display=('title','audience','campus','status','recipient_count','created_at','sent_at');list_filter=('status','audience','campus');search_fields=('title','message');actions=('send_sms_broadcast',)
 @admin.action(description='Queue and send selected SMS broadcasts')
 def send_sms_broadcast(self,request,queryset):
  from apps.accounts.models import Member
  sent=0
  for item in queryset.exclude(status='SENT'):
   recipients=Member.objects.filter(status='ACTIVE');recipients=recipients.filter(campus=item.campus) if item.audience=='CAMPUS' else recipients
   for phone in recipients.values_list('primary_phone',flat=True):print(f'[SMS broadcast to {phone}] {item.message}')
   item.status='SENT';item.recipient_count=recipients.count();item.sent_at=timezone.now();item.save(update_fields=['status','recipient_count','sent_at']);sent+=1
  self.message_user(request,f'{sent} broadcast(s) processed.',messages.SUCCESS)
