from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib.auth.forms import UserCreationForm
from django.contrib import messages, auth
from django.db.models import Count, Q, Sum
from tasks.models import Task
from appointments.models import Appointment, Service, StaffMember, AppointmentNote
from users.models import User, Department
from django.utils import timezone
from datetime import timedelta


def is_staff_user(user):
    return user.is_authenticated and user.is_staff

def register(request):
    """Register a new user"""
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            auth.login(request, user)
            messages.success(request, 'Registration successful!')
            return redirect('home')
        else:
            for field, errors in form.errors.items():
                for error in errors:
                    messages.error(request, f"{field}: {error}")
    else:
        form = UserCreationForm()
    
    return render(request, 'registration/register.html', {'form': form})

@login_required
def admin_dashboard(request):
    """Admin dashboard view with statistics and overview"""
    if not request.user.is_staff:
        return redirect('home')  # Redirect non-staff users to home
    
    # Calculate stats
    today = timezone.now().date()
    thirty_days_ago = today - timedelta(days=30)
    
    from appointments.models import Appointment, StaffMember, AppointmentNote
    from users.models import UserRole, Department
    
    # Check user permissions for actions
    if request.user.is_superuser:
        can_manage_users = True
        can_manage_roles = True
    else:
        can_manage_users = hasattr(request.user, 'role') and request.user.role and \
                         request.user.role.name in ['president', 'minister', 'director']
        can_manage_roles = hasattr(request.user, 'role') and request.user.role and \
                          request.user.role.name == 'president'
    
    # Get user role for display
    user_role = request.user.role.name if hasattr(request.user, 'role') and request.user.role else 'admin'
    
    # User statistics
    total_users = User.objects.count()
    active_users = User.objects.filter(is_active=True).count()
    
    # Department statistics
    department_count = Department.objects.count()
    
    # Task statistics
    from tasks.models import Task
    total_tasks = Task.objects.count()
    pending_task_count = Task.objects.filter(status__in=['todo', 'in_progress']).count()
    completed_tasks = Task.objects.filter(status='completed').count()
    
    # Appointment statistics
    stats = {
        'total_users': total_users,
        'active_user_count': active_users,
        'total_departments': department_count,
        'total_tasks': total_tasks,
        'pending_tasks': pending_task_count,
        'completed_tasks': completed_tasks,
        'total_appointments': Appointment.objects.count(),
        'pending_appointments': Appointment.objects.filter(status='pending').count(),
        'total_staff': StaffMember.objects.count(),
        'total_revenue': Appointment.objects.filter(
            status='completed',
            start_time__date__gte=thirty_days_ago
        ).aggregate(total=Sum('service__price'))['total'] or 0,
    }
    
    # Get upcoming appointments (next 7 days)
    upcoming_appointments = Appointment.objects.filter(
        start_time__date__gte=today,
        start_time__lte=today + timedelta(days=7),
        status__in=['pending', 'confirmed']
    ).order_by('start_time')[:5]
    
    # Get recent users
    recent_users = User.objects.order_by('-date_joined')[:5]
    
    # Get recent departments
    recent_departments = Department.objects.order_by('-id')[:5]
    
    # Get recent tasks
    recent_tasks = Task.objects.select_related('assigned_to', 'created_by').order_by('-created_at')[:5]
    
    # Generate recent activities
    recent_activities = []
    
    # Add recent users
    for user in recent_users:
        recent_activities.append({
            'title': f"New user registered: {user.get_full_name() or user.email}",
            'description': f"Role: {user.role.name if user.role else 'No Role'}",
            'timestamp': user.date_joined,
            'icon': 'fa-user-plus',
            'type': 'user',
            'link': reverse('users:user_detail', args=[user.id])
        })
    
    # Add recent departments
    for dept in recent_departments:
        recent_activities.append({
            'title': f"New department created: {dept.name}",
            'description': f"Parent: {dept.parent.name if dept.parent else 'None'}",
            'timestamp': timezone.now(),  # Note: Add created_at field to Department model for accurate timestamp
            'icon': 'fa-building',
            'type': 'department',
            'link': reverse('departments:department_detail', args=[dept.id])
        })
    
    # Add recent tasks
    for task in recent_tasks:
        recent_activities.append({
            'title': f"New task: {task.title}",
            'description': f"Status: {task.get_status_display()}, Priority: {task.get_priority_display()}",
            'timestamp': task.created_at,
            'icon': 'fa-tasks',
            'type': 'task',
            'link': reverse('tasks:task-detail', args=[task.id])
        })
    
    # Add recent appointments
    for appt in upcoming_appointments:
        recent_activities.append({
            'title': f"Upcoming appointment: {appt.service.name if appt.service else 'No Service'}",
            'description': f"With: {appt.staff_member.user.get_full_name() if appt.staff_member else 'No Staff'}",
            'timestamp': appt.start_time,
            'icon': 'fa-calendar-alt',
            'type': 'appointment',
            'link': reverse('appointments:appointment_detail', args=[appt.id])
        })
    
    # Sort activities by timestamp
    recent_activities.sort(key=lambda x: x['timestamp'], reverse=True)
    recent_activities = recent_activities[:10]  # Limit to 10 most recent
    
    context = {
        'stats': stats,
        'upcoming_appointments': upcoming_appointments,
        'recent_activities': recent_activities,
        'can_manage_users': can_manage_users,
        'can_manage_roles': can_manage_roles,
        'user_role': user_role,
        'total_users': total_users,
        'active_user_count': active_users,
        'department_count': department_count,
        'total_tasks': total_tasks,
        'pending_task_count': pending_task_count,
        'completed_tasks': completed_tasks,
        'recent_users': recent_users,
        'recent_departments': recent_departments,
        'recent_tasks': recent_tasks,
    }
    return render(request, 'admin_dashboard.html', context)

def home(request):
    """Home page view - shows different content based on user authentication and role"""
    # If user is not authenticated, show the public home page
    if not request.user.is_authenticated:
        return render(request, 'home.html')
        
    # Redirect superusers to admin dashboard
    if request.user.is_superuser:
        return redirect('admin_dashboard')
    
    # For authenticated users, prepare context with user-specific data
    context = {}
    
    # Get user's tasks
    tasks = Task.objects.filter(
        Q(created_by=request.user) | Q(assigned_to=request.user)
    ).order_by('-created_at')[:5]
    
    # Get upcoming appointments
    now = timezone.now()
    upcoming_appointments = Appointment.objects.filter(
        client=request.user,
        start_time__gte=now,
        status__in=['pending', 'confirmed']
    ).order_by('start_time')[:5]
    
    # Get task counts for the dashboard
    task_counts = Task.objects.filter(
        Q(created_by=request.user) | Q(assigned_to=request.user)
    ).values('status').annotate(count=Count('status'))
    
    # Format task counts for the chart
    status_order = ['todo', 'in_progress', 'in_review', 'done']
    task_status_data = []
    status_map = {item['status']: item['count'] for item in task_counts}
    
    for status in status_order:
        task_status_data.append(status_map.get(status, 0))
    
    context.update({
        'tasks': tasks,
        'upcoming_appointments': upcoming_appointments,
        'task_status_data': task_status_data,
    })
    
    # Render the home page with user-specific context
    return render(request, 'home.html', context)
    
    return render(request, 'home.html', context)

@login_required
def profile(request):
    """User profile page"""
    from django.utils import timezone
    from appointments.models import Appointment
    from tasks.models import Task
    
    # Get user's upcoming appointments (next 7 days)
    upcoming_appointments = Appointment.objects.filter(
        client=request.user,
        start_time__gte=timezone.now(),
        start_time__lte=timezone.now() + timezone.timedelta(days=7)
    ).order_by('start_time')
    
    # Get recent activities (placeholder - you can customize this)
    recent_activities = []
    
    # Add appointments to activities
    for appt in Appointment.objects.filter(client=request.user).order_by('-created_at')[:5]:
        recent_activities.append({
            'title': f'Appointment: {appt.service.name}',
            'description': f'Scheduled for {appt.start_time.strftime("%B %d, %Y at %I:%M %p")}',
            'timestamp': appt.created_at,
            'link': appt.get_absolute_url()
        })
    
    # Add tasks to activities
    for task in Task.objects.filter(assigned_to=request.user).order_by('-created_at')[:5]:
        recent_activities.append({
            'title': f'Task: {task.title}',
            'description': f'Status: {task.get_status_display()}',
            'timestamp': task.created_at,
            'link': reverse('tasks:task-detail', kwargs={'pk': task.pk})
        })
    
    # Sort activities by timestamp (newest first)
    recent_activities.sort(key=lambda x: x['timestamp'], reverse=True)
    recent_activities = recent_activities[:5]  # Limit to 5 most recent
    
    context = {
        'upcoming_appointments': upcoming_appointments,
        'recent_activities': recent_activities,
    }
    
    return render(request, 'profile.html', context)

def handler404(request, exception):
    """Custom 404 error handler"""
    return render(request, '404.html', status=404)

def handler500(request):
    """Custom 500 error handler"""
    return render(request, '500.html', status=500)

def handler403(request, exception):
    """Custom 403 error handler"""
    return render(request, '403.html', status=403)

def handler400(request, exception):
    """Custom 400 error handler"""
    return render(request, '400.html', status=400)
