"""Accounts Views

This module contains views for user authentication, registration,
profile management, and other user-related functionality.
"""

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
from django.contrib import messages
from django.views.generic import (
    CreateView, UpdateView, DetailView, ListView, TemplateView
)

from django.views.decorators.http import require_http_methods
from django.urls import reverse_lazy, reverse
from django.http import JsonResponse, HttpResponseRedirect
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.cache import never_cache
from django.contrib.auth.views import (
    LoginView as BaseLoginView,
    LogoutView as BaseLogoutView,
    PasswordChangeView as BasePasswordChangeView,
    PasswordResetView as BasePasswordResetView,
)
from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.response import Response

from .models import User, UserProfile, UserSession
from .forms import (
    UserRegistrationForm, UserProfileForm, CustomAuthenticationForm
)
from .serializers import UserSerializer, UserProfileSerializer
from apps.core.views import BaseView
from apps.core.permissions import IsOwnerOrReadOnly


class HomeView(TemplateView):
    """Home page view."""
    template_name = 'accounts/home.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['page_title'] = 'Welcome to Adtlas DAI'
        context['title'] = _('Welcome to Adtlas')
        return context


class LoginView(BaseLoginView):
    """Custom login view."""
    template_name = 'accounts/login.html'
    form_class = CustomAuthenticationForm
    redirect_authenticated_user = True
    
    def get_success_url(self):
        """Redirect to dashboard after successful login."""
        return reverse_lazy('accounts:dashboard')
    
    def form_valid(self, form):
        """Handle successful login."""
        response = super().form_valid(form)
        
        # Log the login session
        self._log_user_session()
        
        messages.success(
            self.request,
            _(f'Welcome back, {self.request.user.get_full_name()}!')
        )
        
        return response
    
    def _log_user_session(self):
        """Log user session for security tracking."""
        try:
            UserSession.objects.create(
                user=self.request.user,
                session_key=self.request.session.session_key,
                ip_address=self.request.META.get('REMOTE_ADDR', ''),
                user_agent=self.request.META.get('HTTP_USER_AGENT', ''),
                expires_at=self.request.session.get_expiry_date()
            )
        except Exception:
            # Don't fail login if session logging fails
            pass


class LogoutView(BaseLogoutView):
    """Custom logout view."""
    next_page = reverse_lazy('accounts:login')
    
    def dispatch(self, request, *args, **kwargs):
        """Handle logout and deactivate session."""
        if request.user.is_authenticated:
            # Deactivate user session
            try:
                session = UserSession.objects.get(
                    user=request.user,
                    session_key=request.session.session_key,
                    is_active=True
                )
                session.deactivate()
            except UserSession.DoesNotExist:
                pass
            
            messages.success(request, _('You have been successfully logged out.'))
        
        return super().dispatch(request, *args, **kwargs)


class RegisterView(CreateView):
    """User registration view."""
    model = User
    form_class = UserRegistrationForm
    template_name = 'accounts/register.html'
    success_url = reverse_lazy('accounts:login')
    
    def dispatch(self, request, *args, **kwargs):
        """Redirect authenticated users."""
        if request.user.is_authenticated:
            return redirect('accounts:dashboard')
        return super().dispatch(request, *args, **kwargs)
    
    def form_valid(self, form):
        """Handle successful registration."""
        response = super().form_valid(form)
        
        # Create user profile
        UserProfile.objects.create(user=self.object)
        
        messages.success(
            self.request,
            _('Registration successful! Please log in with your credentials.')
        )
        
        return response


class DashboardView(LoginRequiredMixin, TemplateView):
    """User dashboard view."""
    template_name = 'accounts/dashboard.html'
    login_url = reverse_lazy('accounts:login')
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update({
            'title': _('Dashboard'),
            'user_sessions': UserSession.objects.filter(
                user=self.request.user,
                is_active=True
            ).order_by('-created_at')[:5],
        })
        return context


class ProfileView(LoginRequiredMixin, DetailView):
    """User profile view."""
    model = User
    template_name = 'accounts/profile.html'
    context_object_name = 'profile_user'
    
    def get_object(self):
        """Get the user object."""
        pk = self.kwargs.get('pk')
        if pk:
            return get_object_or_404(User, pk=pk)
        return self.request.user
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = _(f'Profile - {self.object.get_full_name()}')
        context['is_own_profile'] = self.object == self.request.user
        return context


class ProfileEditView(LoginRequiredMixin, UpdateView):
    """Edit user profile view."""
    model = User
    form_class = UserProfileForm
    template_name = 'accounts/profile_edit.html'
    
    def get_object(self):
        """Get the current user."""
        return self.request.user
    
    def get_success_url(self):
        """Redirect to profile after successful update."""
        return reverse('accounts:profile')
    
    def form_valid(self, form):
        """Handle successful profile update."""
        response = super().form_valid(form)
        messages.success(self.request, _('Profile updated successfully!'))
        return response


class PasswordChangeView(LoginRequiredMixin, BasePasswordChangeView):
    """Custom password change view."""
    template_name = 'accounts/password_change.html'
    success_url = reverse_lazy('accounts:profile')
    
    def form_valid(self, form):
        """Handle successful password change."""
        response = super().form_valid(form)
        messages.success(self.request, _('Password changed successfully!'))
        return response


class PasswordResetView(BasePasswordResetView):
    """Custom password reset view."""
    template_name = 'accounts/password_reset.html'
    email_template_name = 'accounts/password_reset_email.html'
    success_url = reverse_lazy('accounts:password_reset_done')


# API Views
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def user_profile_api(request):
    """Get current user profile via API."""
    serializer = UserSerializer(request.user)
    return Response(serializer.data)


@api_view(['PUT', 'PATCH'])
@permission_classes([IsAuthenticated])
def update_profile_api(request):
    """Update user profile via API."""
    serializer = UserSerializer(
        request.user,
        data=request.data,
        partial=request.method == 'PATCH'
    )
    
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data)
    
    return Response(
        serializer.errors,
        status=status.HTTP_400_BAD_REQUEST
    )


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def user_sessions_api(request):
    """Get user sessions via API."""
    sessions = UserSession.objects.filter(
        user=request.user,
        is_active=True
    ).order_by('-created_at')
    
    data = []
    for session in sessions:
        data.append({
            'id': session.id,
            'ip_address': session.ip_address,
            'user_agent': session.user_agent,
            'created_at': session.created_at,
            'expires_at': session.expires_at,
            'is_current': session.session_key == request.session.session_key,
        })
    
    return Response(data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def terminate_session_api(request, session_id):
    """Terminate a user session via API."""
    try:
        session = UserSession.objects.get(
            id=session_id,
            user=request.user,
            is_active=True
        )
        session.deactivate()
        return Response({'message': _('Session terminated successfully.')})
    
    except UserSession.DoesNotExist:
        return Response(
            {'error': _('Session not found.')},
            status=status.HTTP_404_NOT_FOUND
        )


# Utility Views
@login_required
def check_username_availability(request):
    """Check if username is available (AJAX)."""
    username = request.GET.get('username', '')
    
    if not username:
        return JsonResponse({'available': False, 'message': _('Username is required.')})
    
    if username == request.user.username:
        return JsonResponse({'available': True, 'message': _('Current username.')})
    
    exists = User.objects.filter(username=username).exists()
    
    return JsonResponse({
        'available': not exists,
        'message': _('Username is available.') if not exists else _('Username is already taken.')
    })


@login_required
def check_email_availability(request):
    """Check if email is available (AJAX)."""
    email = request.GET.get('email', '')
    
    if not email:
        return JsonResponse({'available': False, 'message': _('Email is required.')})
    
    if email.lower() == request.user.email.lower():
        return JsonResponse({'available': True, 'message': _('Current email.')})
    
    exists = User.objects.filter(email__iexact=email).exists()
    
    return JsonResponse({
        'available': not exists,
        'message': _('Email is available.') if not exists else _('Email is already registered.')
    })


# Static Page Views
class AboutView(TemplateView):
    """About page view."""
    template_name = 'accounts/about.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['page_title'] = 'About Us'
        return context


class PrivacyView(TemplateView):
    """Privacy policy page view."""
    template_name = 'accounts/privacy.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['page_title'] = 'Privacy Policy'
        return context


class TermsView(TemplateView):
    """Terms of service page view."""
    template_name = 'accounts/terms.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['page_title'] = 'Terms of Service'
        return context


class ContactView(TemplateView):
    """Contact page view."""
    template_name = 'accounts/contact.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['page_title'] = 'Contact Us'
        return context


class SettingsView(LoginRequiredMixin, TemplateView):
    """User settings page view."""
    template_name = 'accounts/settings.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['page_title'] = 'Account Settings'
        context['user_sessions'] = UserSession.objects.filter(
            user=self.request.user,
            is_active=True
        ).order_by('-created_at')
        return context


class EmailVerificationView(TemplateView):
    """Email verification page view."""
    template_name = 'accounts/email_verification.html'
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['page_title'] = 'Email Verification'
        return context
    
    def get(self, request, *args, **kwargs):
        token = request.GET.get('token')
        if token:
            # Handle email verification logic here
            # This would typically verify the token and activate the user account
            context = self.get_context_data(**kwargs)
            context['verification_token'] = token
            return self.render_to_response(context)
        return super().get(request, *args, **kwargs)