from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib import messages
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from django.http import Http404, JsonResponse
from django.db.models import Q
from django.utils import timezone
from .models import Person, Referral, ActivityLog, ContactMessage
from .forms import (
    PersonRegistrationForm, CustomAuthenticationForm, 
    WorkerProfileForm, ClientProfileForm, ReferralForm, ContactForm, PersonAdminForm
)


def log_activity(person, action_type, description='', request=None):
    """Helper function to log user activity"""
    ip_address = None
    if request:
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip_address = x_forwarded_for.split(',')[0]
        else:
            ip_address = request.META.get('REMOTE_ADDR')
    
    ActivityLog.objects.create(
        person=person,
        action_type=action_type,
        description=description,
        ip_address=ip_address
    )


# ============ Home & Static Pages ============

def home(request):
    """Home page with map and worker listings"""
    featured_workers = Person.objects.filter(
        role='worker', 
        is_active=True, 
        is_available=True,
        is_featured=True
    )[:3]
    
    all_workers = Person.objects.filter(
        role='worker', 
        is_active=True, 
        is_available=True
    )[:12]
    
    # Get workers with coordinates for map
    workers_for_map = Person.objects.filter(
        role='worker',
        is_active=True,
        is_available=True,
        latitude__isnull=False,
        longitude__isnull=False
    ).values('id', 'profile_name', 'latitude', 'longitude', 'city')
    
    context = {
        'featured_workers': featured_workers,
        'all_workers': all_workers,
        'workers_for_map': list(workers_for_map),
    }
    return render(request, 'core/home.html', context)


def about(request):
    """About page"""
    return render(request, 'core/about.html')


def touring_girls(request):
    """Touring girls page"""
    touring_workers = Person.objects.filter(
        role='worker',
        is_active=True,
        is_touring=True
    )[:3]
    return render(request, 'core/touring_girls.html', {'touring_workers': touring_workers})


def etiquette(request):
    """Etiquette and glossary page"""
    return render(request, 'core/etiquette.html')


def resources(request):
    """Resources page"""
    return render(request, 'core/resources.html')


def advertise(request):
    """Advertise with us page"""
    return render(request, 'core/advertise.html')


def photographers(request):
    """Photographers page"""
    return render(request, 'core/photographers.html')


def contact(request):
    """Contact page"""
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, 'Your message has been sent. We will get back to you soon!')
            return redirect('contact')
    else:
        form = ContactForm()
    return render(request, 'core/contact.html', {'form': form})


def terms_conditions(request):
    """Terms and conditions page"""
    return render(request, 'core/terms.html')


def privacy_policy(request):
    """Privacy policy page"""
    return render(request, 'core/privacy.html')


def disclaimer(request):
    """Disclaimer page"""
    return render(request, 'core/disclaimer.html')


def glossary(request):
    """Glossary page"""
    return render(request, 'core/glossary.html')


# ============ Authentication ============

def register(request):
    """User registration"""
    if request.user.is_authenticated:
        return redirect('home')
    
    if request.method == 'POST':
        form = PersonRegistrationForm(request.POST)
        if form.is_valid():
            user = form.save()
            log_activity(user, 'profile_create', 'Account created', request)
            login(request, user)
            messages.success(request, 'Welcome to Confidant! Please complete your profile.')
            return redirect('profile_edit')
    else:
        form = PersonRegistrationForm()
    return render(request, 'core/register.html', {'form': form})


def user_login(request):
    """User login"""
    if request.user.is_authenticated:
        return redirect('home')
    
    if request.method == 'POST':
        form = CustomAuthenticationForm(request, data=request.POST)
        if form.is_valid():
            user = form.get_user()
            login(request, user)
            log_activity(user, 'login', 'User logged in', request)
            messages.success(request, f'Welcome back, {user.display_name}!')
            next_url = request.GET.get('next', 'home')
            return redirect(next_url)
    else:
        form = CustomAuthenticationForm()
    return render(request, 'core/login.html', {'form': form})


@login_required
def user_logout(request):
    """User logout"""
    log_activity(request.user, 'logout', 'User logged out', request)
    logout(request)
    messages.info(request, 'You have been logged out.')
    return redirect('home')


# ============ Profile Views ============

@login_required
def profile_edit(request):
    """Edit own profile"""
    user = request.user
    
    if user.role == 'worker':
        FormClass = WorkerProfileForm
    else:
        FormClass = ClientProfileForm
    
    if request.method == 'POST':
        form = FormClass(request.POST, request.FILES, instance=user)
        if form.is_valid():
            form.save()
            log_activity(user, 'profile_update', 'Profile updated', request)
            messages.success(request, 'Your profile has been updated.')
            return redirect('profile_view', pk=user.pk)
    else:
        form = FormClass(instance=user)
    
    return render(request, 'core/profile_edit.html', {'form': form})


def profile_view(request, pk):
    """View a profile"""
    person = get_object_or_404(Person, pk=pk)
    
    # If viewing a worker profile
    if person.role == 'worker':
        # Anyone can see worker profiles but with different info levels
        is_owner = request.user.is_authenticated and request.user.pk == pk
        is_admin = request.user.is_authenticated and request.user.role == 'admin'
        
        # Get activity logs only for admin or owner
        activity_logs = None
        if is_owner or is_admin:
            activity_logs = person.activity_logs.all()[:20]
        
        context = {
            'person': person,
            'is_owner': is_owner,
            'is_admin': is_admin,
            'activity_logs': activity_logs,
        }
        return render(request, 'core/profile_view.html', context)
    
    # If viewing a client profile
    elif person.role == 'client':
        # Only admin can view client profiles
        if not request.user.is_authenticated:
            raise Http404("Profile not found")
        if request.user.role != 'admin' and request.user.pk != pk:
            raise Http404("Profile not found")
        
        is_owner = request.user.pk == pk
        is_admin = request.user.role == 'admin'
        activity_logs = person.activity_logs.all()[:20] if is_admin else None
        
        context = {
            'person': person,
            'is_owner': is_owner,
            'is_admin': is_admin,
            'activity_logs': activity_logs,
        }
        return render(request, 'core/profile_view.html', context)
    
    else:
        raise Http404("Profile not found")


@login_required
def my_profile(request):
    """Redirect to own profile"""
    return redirect('profile_view', pk=request.user.pk)


# ============ People Management (Admin) ============

class AdminRequiredMixin(UserPassesTestMixin):
    """Mixin to require admin role"""
    def test_func(self):
        return self.request.user.is_authenticated and self.request.user.role == 'admin'


class PersonListView(LoginRequiredMixin, AdminRequiredMixin, ListView):
    """List all people (admin only)"""
    model = Person
    template_name = 'core/person_list.html'
    context_object_name = 'people'
    paginate_by = 20
    
    def get_queryset(self):
        queryset = Person.objects.all()
        role = self.request.GET.get('role')
        search = self.request.GET.get('search')
        
        if role:
            queryset = queryset.filter(role=role)
        if search:
            queryset = queryset.filter(
                Q(first_name__icontains=search) |
                Q(last_name__icontains=search) |
                Q(email__icontains=search) |
                Q(profile_name__icontains=search)
            )
        return queryset


class PersonCreateView(LoginRequiredMixin, AdminRequiredMixin, CreateView):
    """Create a new person (admin only)"""
    model = Person
    form_class = PersonAdminForm
    template_name = 'core/person_form.html'
    success_url = reverse_lazy('person_list')
    
    def form_valid(self, form):
        response = super().form_valid(form)
        # Set a default password
        self.object.set_password('ChangeMe123!')
        self.object.save()
        messages.success(self.request, f'Person created. Default password: ChangeMe123!')
        return response


class PersonUpdateView(LoginRequiredMixin, AdminRequiredMixin, UpdateView):
    """Update a person (admin only)"""
    model = Person
    form_class = PersonAdminForm
    template_name = 'core/person_form.html'
    
    def get_success_url(self):
        return reverse_lazy('profile_view', kwargs={'pk': self.object.pk})
    
    def form_valid(self, form):
        response = super().form_valid(form)
        messages.success(self.request, 'Person updated successfully.')
        return response


class PersonDeleteView(LoginRequiredMixin, AdminRequiredMixin, DeleteView):
    """Delete a person (admin only)"""
    model = Person
    template_name = 'core/person_confirm_delete.html'
    success_url = reverse_lazy('person_list')
    
    def delete(self, request, *args, **kwargs):
        messages.success(request, 'Person deleted successfully.')
        return super().delete(request, *args, **kwargs)


# ============ Referrals ============

class ReferralListView(LoginRequiredMixin, ListView):
    """List all referrals"""
    model = Referral
    template_name = 'core/referral_list.html'
    context_object_name = 'referrals'
    paginate_by = 20
    
    def get_queryset(self):
        if self.request.user.role == 'admin':
            return Referral.objects.all()
        return Referral.objects.filter(
            Q(person=self.request.user) | Q(referrer=self.request.user)
        )


class ReferralCreateView(LoginRequiredMixin, CreateView):
    """Create a new referral"""
    model = Referral
    form_class = ReferralForm
    template_name = 'core/referral_form.html'
    success_url = reverse_lazy('referral_list')
    
    def form_valid(self, form):
        form.instance.referrer = self.request.user
        response = super().form_valid(form)
        log_activity(self.request.user, 'referral_create', f'Created referral for {form.instance.person}', self.request)
        messages.success(self.request, 'Referral created successfully.')
        return response


class ReferralUpdateView(LoginRequiredMixin, UpdateView):
    """Update a referral"""
    model = Referral
    form_class = ReferralForm
    template_name = 'core/referral_form.html'
    success_url = reverse_lazy('referral_list')
    
    def get_queryset(self):
        if self.request.user.role == 'admin':
            return Referral.objects.all()
        return Referral.objects.filter(referrer=self.request.user)
    
    def form_valid(self, form):
        response = super().form_valid(form)
        messages.success(self.request, 'Referral updated successfully.')
        return response


class ReferralDeleteView(LoginRequiredMixin, DeleteView):
    """Delete a referral"""
    model = Referral
    template_name = 'core/referral_confirm_delete.html'
    success_url = reverse_lazy('referral_list')
    
    def get_queryset(self):
        if self.request.user.role == 'admin':
            return Referral.objects.all()
        return Referral.objects.filter(referrer=self.request.user)
    
    def delete(self, request, *args, **kwargs):
        messages.success(request, 'Referral deleted successfully.')
        return super().delete(request, *args, **kwargs)


# ============ API Endpoints ============

def api_workers_map(request):
    """API endpoint for workers on map"""
    workers = Person.objects.filter(
        role='worker',
        is_active=True,
        is_available=True,
        latitude__isnull=False,
        longitude__isnull=False
    ).values('id', 'profile_name', 'latitude', 'longitude', 'city', 'hourly_rate')
    
    return JsonResponse({'workers': list(workers)})


def api_search_workers(request):
    """API endpoint for searching workers"""
    query = request.GET.get('q', '')
    city = request.GET.get('city', '')
    
    workers = Person.objects.filter(
        role='worker',
        is_active=True,
        is_available=True
    )
    
    if query:
        workers = workers.filter(
            Q(profile_name__icontains=query) |
            Q(bio__icontains=query) |
            Q(interests__icontains=query)
        )
    
    if city:
        workers = workers.filter(city__icontains=city)
    
    workers = workers.values(
        'id', 'profile_name', 'city', 'hourly_rate', 'bio'
    )[:20]
    
    return JsonResponse({'workers': list(workers)})
