
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib import messages
from django.views.generic import ListView, CreateView, UpdateView, DeleteView, View
from django.urls import reverse_lazy
from django.db.models import Q, Count
from django.utils import timezone
from datetime import timedelta
from .models import NotificationTemplate, SMSLog, EmailLog
from .forms import NotificationTemplateForm, TestSMSForm, TestEmailForm
from .services import NotificationService

def has_admin_access(user):
    return user.is_authenticated and (user.is_superuser or user.groups.filter(name='Management').exists())

class NotificationDashboardView(LoginRequiredMixin, UserPassesTestMixin, View):
    def test_func(self):
        return has_admin_access(self.request.user)
    
    def get(self, request):
        # Get statistics
        total_templates = NotificationTemplate.objects.count()
        active_templates = NotificationTemplate.objects.filter(is_active=True).count()
        
        # SMS statistics
        sms_today = SMSLog.objects.filter(sent_at__date=timezone.now().date()).count()
        sms_this_week = SMSLog.objects.filter(sent_at__gte=timezone.now() - timedelta(days=7)).count()
        sms_success_rate = 0
        if SMSLog.objects.exists():
            sms_total = SMSLog.objects.count()
            sms_sent = SMSLog.objects.filter(status='sent').count()
            sms_success_rate = round((sms_sent / sms_total) * 100, 1) if sms_total > 0 else 0
        
        # Email statistics
        email_today = EmailLog.objects.filter(sent_at__date=timezone.now().date()).count()
        email_this_week = EmailLog.objects.filter(sent_at__gte=timezone.now() - timedelta(days=7)).count()
        email_success_rate = 0
        if EmailLog.objects.exists():
            email_total = EmailLog.objects.count()
            email_sent = EmailLog.objects.filter(status='sent').count()
            email_success_rate = round((email_sent / email_total) * 100, 1) if email_total > 0 else 0
        
        # Recent templates
        recent_templates = NotificationTemplate.objects.order_by('-updated_at')[:5]
        
        # Recent logs
        recent_sms = SMSLog.objects.order_by('-sent_at')[:5]
        recent_emails = EmailLog.objects.order_by('-sent_at')[:5]
        
        context = {
            'total_templates': total_templates,
            'active_templates': active_templates,
            'sms_today': sms_today,
            'sms_this_week': sms_this_week,
            'sms_success_rate': sms_success_rate,
            'email_today': email_today,
            'email_this_week': email_this_week,
            'email_success_rate': email_success_rate,
            'recent_templates': recent_templates,
            'recent_sms': recent_sms,
            'recent_emails': recent_emails,
        }
        return render(request, 'notifications/dashboard.html', context)

class NotificationTemplateListView(LoginRequiredMixin, UserPassesTestMixin, ListView):
    model = NotificationTemplate
    template_name = 'notifications/template_list.html'
    context_object_name = 'templates'
    paginate_by = 20
    
    def test_func(self):
        return has_admin_access(self.request.user)
    
    def get_queryset(self):
        queryset = NotificationTemplate.objects.all()
        search = self.request.GET.get('search')
        template_type = self.request.GET.get('type')
        status = self.request.GET.get('status')
        
        if search:
            queryset = queryset.filter(
                Q(name__icontains=search) | 
                Q(content__icontains=search) |
                Q(subject__icontains=search)
            )
        
        if template_type:
            queryset = queryset.filter(template_type=template_type)
        
        if status == 'active':
            queryset = queryset.filter(is_active=True)
        elif status == 'inactive':
            queryset = queryset.filter(is_active=False)
        
        return queryset.order_by('template_type', 'name')
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['template_types'] = NotificationTemplate.TEMPLATE_TYPES
        context['search'] = self.request.GET.get('search', '')
        context['selected_type'] = self.request.GET.get('type', '')
        context['selected_status'] = self.request.GET.get('status', '')
        return context

class NotificationTemplateCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
    model = NotificationTemplate
    form_class = NotificationTemplateForm
    template_name = 'notifications/template_form.html'
    success_url = reverse_lazy('notifications:template_list')
    
    def test_func(self):
        return has_admin_access(self.request.user)
    
    def form_valid(self, form):
        messages.success(self.request, f'Template "{form.instance.name}" created successfully!')
        return super().form_valid(form)

class NotificationTemplateUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = NotificationTemplate
    form_class = NotificationTemplateForm
    template_name = 'notifications/template_form.html'
    success_url = reverse_lazy('notifications:template_list')
    
    def test_func(self):
        return has_admin_access(self.request.user)
    
    def form_valid(self, form):
        messages.success(self.request, f'Template "{form.instance.name}" updated successfully!')
        return super().form_valid(form)

class NotificationTemplateDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    model = NotificationTemplate
    template_name = 'notifications/template_confirm_delete.html'
    success_url = reverse_lazy('notifications:template_list')
    
    def test_func(self):
        return has_admin_access(self.request.user)
    
    def delete(self, request, *args, **kwargs):
        template = self.get_object()
        messages.success(request, f'Template "{template.name}" deleted successfully!')
        return super().delete(request, *args, **kwargs)

class SMSLogListView(LoginRequiredMixin, UserPassesTestMixin, ListView):
    model = SMSLog
    template_name = 'notifications/sms_logs.html'
    context_object_name = 'logs'
    paginate_by = 50
    
    def test_func(self):
        return has_admin_access(self.request.user)
    
    def get_queryset(self):
        queryset = SMSLog.objects.all()
        search = self.request.GET.get('search')
        status = self.request.GET.get('status')
        
        if search:
            queryset = queryset.filter(
                Q(recipient_phone__icontains=search) | 
                Q(recipient_name__icontains=search) |
                Q(message__icontains=search)
            )
        
        if status:
            queryset = queryset.filter(status=status)
        
        return queryset.order_by('-sent_at')

class EmailLogListView(LoginRequiredMixin, UserPassesTestMixin, ListView):
    model = EmailLog
    template_name = 'notifications/email_logs.html'
    context_object_name = 'logs'
    paginate_by = 50
    
    def test_func(self):
        return has_admin_access(self.request.user)
    
    def get_queryset(self):
        queryset = EmailLog.objects.all()
        search = self.request.GET.get('search')
        status = self.request.GET.get('status')
        email_type = self.request.GET.get('email_type')
        
        if search:
            queryset = queryset.filter(
                Q(recipient_email__icontains=search) | 
                Q(recipient_name__icontains=search) |
                Q(subject__icontains=search) |
                Q(message__icontains=search)
            )
        
        if status:
            queryset = queryset.filter(status=status)
            
        if email_type:
            queryset = queryset.filter(email_type=email_type)
        
        return queryset.order_by('-sent_at')

class TestSMSView(LoginRequiredMixin, UserPassesTestMixin, View):
    def test_func(self):
        return has_admin_access(self.request.user)
    
    def get(self, request):
        form = TestSMSForm()
        return render(request, 'notifications/test_sms.html', {'form': form})
    
    def post(self, request):
        form = TestSMSForm(request.POST)
        if form.is_valid():
            phone = form.cleaned_data['phone']
            message = form.cleaned_data['message']
            
            try:
                service = NotificationService()
                success = service.send_sms(phone, message, recipient_name="Test User")
                if success:
                    messages.success(request, f'Test SMS sent successfully to {phone}')
                else:
                    messages.error(request, 'Failed to send test SMS. Please check your SMS settings.')
            except Exception as e:
                messages.error(request, f'Error sending test SMS: {str(e)}')
        
        return render(request, 'notifications/test_sms.html', {'form': form})

class TestEmailView(LoginRequiredMixin, UserPassesTestMixin, View):
    def test_func(self):
        return has_admin_access(self.request.user)
    
    def get(self, request):
        form = TestEmailForm()
        return render(request, 'notifications/test_email.html', {'form': form})
    
    def post(self, request):
        form = TestEmailForm(request.POST)
        if form.is_valid():
            email = form.cleaned_data['email']
            subject = form.cleaned_data['subject']
            message = form.cleaned_data['message']
            
            try:
                service = NotificationService()
                success = service.send_email(email, subject, message, recipient_name="Test User")
                if success:
                    messages.success(request, f'Test email sent successfully to {email}')
                else:
                    messages.error(request, 'Failed to send test email. Please check your email settings.')
            except Exception as e:
                messages.error(request, f'Error sending test email: {str(e)}')
        
        return render(request, 'notifications/test_email.html', {'form': form})
