# -*- coding: utf-8 -*-
"""
Authentication Views Module

This module contains views for handling authentication and authorization
including login, logout, registration, password reset, email verification,
and session management.

Author: Senior Django Developer
Date: 2024
"""

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.core.mail import send_mail
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from django.views.generic import (
    View, TemplateView, FormView, ListView, DetailView
)
from django.http import (
    JsonResponse, HttpResponse, HttpResponseRedirect, Http404
)
from django.urls import reverse_lazy, reverse
from django.template.loader import render_to_string
from django.utils.html import strip_tags
from django.contrib.auth import get_user_model
from django.db.models import Q, Count
from django.core.paginator import Paginator
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from django.utils.decorators import method_decorator
from django.contrib.auth.forms import (
    AuthenticationForm, PasswordResetForm, SetPasswordForm
)
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 rest_framework.views import APIView
from rest_framework.authtoken.models import Token
from rest_framework.authtoken.views import ObtainAuthToken
from datetime import timedelta
import json
import logging

from .models import (
    LoginAttempt,
    PasswordResetToken,
    EmailVerificationToken,
    UserSession
)
from .utils import (
    get_client_ip,
    get_user_agent_info,
    get_location_from_ip,
    is_safe_url
)



# from django.contrib.auth import login
# from django.contrib.auth.views import (
#     LoginView, LogoutView, PasswordResetView,
#     PasswordResetConfirmView, PasswordChangeView, PasswordChangeDoneView,
#     PasswordResetDoneView
# )
# from django.views.generic import CreateView, TemplateView
# from django.contrib.auth import get_user_model
# from django.urls import reverse_lazy

# from .forms import RegistrationForm



# Get the custom user model
User = get_user_model()

# Set up logging
logger = logging.getLogger(__name__)


class CustomLoginView(FormView):
    """
    Custom login view with enhanced security features.
    
    Features:
    - Login attempt tracking
    - Account lockout protection
    - IP-based suspicious activity detection
    - Session management
    - Device tracking
    """
    
    template_name = 'auth/login.html'
    form_class = AuthenticationForm
    success_url = reverse_lazy('core:dashboard')
    
    def dispatch(self, request, *args, **kwargs):
        """
        Check if user is already authenticated.
        
        Args:
            request: HTTP request object
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            HttpResponse: Response object
        """
        # Redirect authenticated users to dashboard
        if request.user.is_authenticated:
            return redirect(self.get_success_url())
        return super().dispatch(request, *args, **kwargs)
    
    def get_context_data(self, **kwargs):
        """
        Add additional context data to the template.
        
        Args:
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            dict: Context data for template
        """
        context = super().get_context_data(**kwargs)
        context['title'] = _('Login')
        context['page_description'] = _('Sign in to your account')
        return context
    
    def form_valid(self, form):
        """
        Handle valid form submission.
        
        Args:
            form: Valid authentication form
            
        Returns:
            HttpResponse: Response object
        """
        # Get form data
        email = form.cleaned_data.get('username')
        password = form.cleaned_data.get('password')
        
        # Get client information
        ip_address = get_client_ip(self.request)
        user_agent = self.request.META.get('HTTP_USER_AGENT', '')
        user_agent_info = get_user_agent_info(user_agent)
        location_info = get_location_from_ip(ip_address)
        
        # Check for account lockout
        failed_attempts = LoginAttempt.get_failed_attempts_count(email, since_hours=1)
        if failed_attempts >= 5:  # Max 5 failed attempts per hour
            # Log the lockout attempt
            LoginAttempt.objects.create(
                attempted_email=email,
                ip_address=ip_address,
                user_agent=user_agent,
                is_successful=False,
                failure_reason='account_locked',
                country=location_info.get('country', ''),
                city=location_info.get('city', '')
            )
            
            messages.error(
                self.request,
                _('Account temporarily locked due to multiple failed login attempts. Please try again later.')
            )
            return self.form_invalid(form)
        
        # Check for suspicious IP
        if LoginAttempt.is_ip_suspicious(ip_address):
            # Log the suspicious attempt
            LoginAttempt.objects.create(
                attempted_email=email,
                ip_address=ip_address,
                user_agent=user_agent,
                is_successful=False,
                failure_reason='suspicious_ip',
                country=location_info.get('country', ''),
                city=location_info.get('city', '')
            )
            
            messages.error(
                self.request,
                _('Login blocked due to suspicious activity. Please contact support.')
            )
            return self.form_invalid(form)
        
        # Authenticate user
        user = authenticate(
            self.request,
            username=email,
            password=password
        )
        
        if user is not None:
            # Check if user account is active
            if not user.is_active:
                # Log failed attempt
                LoginAttempt.objects.create(
                    user=user,
                    attempted_email=email,
                    ip_address=ip_address,
                    user_agent=user_agent,
                    is_successful=False,
                    failure_reason='account_inactive',
                    country=location_info.get('country', ''),
                    city=location_info.get('city', '')
                )
                
                messages.error(
                    self.request,
                    _('Your account is inactive. Please contact support.')
                )
                return self.form_invalid(form)
            
            # Check if email is verified
            if not user.is_verified:
                # Log failed attempt
                LoginAttempt.objects.create(
                    user=user,
                    attempted_email=email,
                    ip_address=ip_address,
                    user_agent=user_agent,
                    is_successful=False,
                    failure_reason='email_not_verified',
                    country=location_info.get('country', ''),
                    city=location_info.get('city', '')
                )
                
                messages.error(
                    self.request,
                    _('Please verify your email address before logging in.')
                )
                return redirect('auth:resend_verification', user_id=user.id)
            
            # Successful login
            login(self.request, user)
            
            # Log successful attempt
            LoginAttempt.objects.create(
                user=user,
                attempted_email=email,
                ip_address=ip_address,
                user_agent=user_agent,
                is_successful=True,
                country=location_info.get('country', ''),
                city=location_info.get('city', '')
            )
            
            # Create or update user session
            session_key = self.request.session.session_key
            if session_key:
                UserSession.objects.update_or_create(
                    session_key=session_key,
                    defaults={
                        'user': user,
                        'ip_address': ip_address,
                        'user_agent': user_agent,
                        'device_type': user_agent_info.get('device_type', ''),
                        'browser': user_agent_info.get('browser', ''),
                        'operating_system': user_agent_info.get('os', ''),
                        'is_active': True,
                        'expires_at': timezone.now() + timedelta(days=30),
                        'country': location_info.get('country', ''),
                        'city': location_info.get('city', '')
                    }
                )
            
            # Update user's last login
            user.last_login = timezone.now()
            user.save(update_fields=['last_login'])
            
            # Success message
            messages.success(
                self.request,
                _(f'Welcome back, {user.get_full_name() or user.email}!')
            )
            
            # Redirect to next URL if provided
            next_url = self.request.GET.get('next')
            if next_url and is_safe_url(next_url, self.request.get_host()):
                return redirect(next_url)
            
            return super().form_valid(form)
        
        else:
            # Failed authentication
            try:
                user = User.objects.get(email=email)
            except User.DoesNotExist:
                user = None
            
            # Log failed attempt
            LoginAttempt.objects.create(
                user=user,
                attempted_email=email,
                ip_address=ip_address,
                user_agent=user_agent,
                is_successful=False,
                failure_reason='invalid_credentials',
                country=location_info.get('country', ''),
                city=location_info.get('city', '')
            )
            
            messages.error(
                self.request,
                _('Invalid email or password. Please try again.')
            )
            return self.form_invalid(form)
    
    def form_invalid(self, form):
        """
        Handle invalid form submission.
        
        Args:
            form: Invalid authentication form
            
        Returns:
            HttpResponse: Response object
        """
        # Add error message if not already added
        if not messages.get_messages(self.request):
            messages.error(
                self.request,
                _('Please correct the errors below.')
            )
        return super().form_invalid(form)


class CustomLogoutView(View):
    """
    Custom logout view with session cleanup.
    
    Features:
    - Session invalidation
    - Security logging
    - Cleanup of user sessions
    """
    
    def post(self, request, *args, **kwargs):
        """
        Handle logout POST request.
        
        Args:
            request: HTTP request object
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            HttpResponse: Response object
        """
        if request.user.is_authenticated:
            # Get session information
            session_key = request.session.session_key
            
            # Invalidate user session in database
            if session_key:
                try:
                    user_session = UserSession.objects.get(
                        session_key=session_key,
                        user=request.user
                    )
                    user_session.invalidate()
                except UserSession.DoesNotExist:
                    pass
            
            # Log the logout
            logger.info(
                f'User {request.user.email} logged out from IP {get_client_ip(request)}'
            )
            
            # Logout user
            logout(request)
            
            # Success message
            messages.success(
                request,
                _('You have been successfully logged out.')
            )
        
        return redirect('auth:login')
    
    def get(self, request, *args, **kwargs):
        """
        Handle logout GET request (redirect to POST).
        
        Args:
            request: HTTP request object
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            HttpResponse: Response object
        """
        return self.post(request, *args, **kwargs)


class RegisterView(FormView):
    """
    User registration view.
    
    Features:
    - User account creation
    - Email verification
    - Security logging
    - Input validation
    """
    
    template_name = 'auth/register.html'
    success_url = reverse_lazy('auth:login')
    
    def get_form_class(self):
        """Return the form class for registration."""
        from django import forms
        from django.contrib.auth.forms import UserCreationForm
        
        class CustomUserCreationForm(UserCreationForm):
            email = forms.EmailField(required=True)
            first_name = forms.CharField(max_length=30, required=True)
            last_name = forms.CharField(max_length=30, required=True)
            
            class Meta:
                model = User
                fields = ('email', 'first_name', 'last_name', 'password1', 'password2')
            
            def save(self, commit=True):
                user = super().save(commit=False)
                user.email = self.cleaned_data['email']
                user.first_name = self.cleaned_data['first_name']
                user.last_name = self.cleaned_data['last_name']
                if commit:
                    user.save()
                return user
        
        return CustomUserCreationForm
    
    def dispatch(self, request, *args, **kwargs):
        """Check if user is already authenticated."""
        if request.user.is_authenticated:
            return redirect('core:dashboard')
        return super().dispatch(request, *args, **kwargs)
    
    def get_context_data(self, **kwargs):
        """Add additional context data."""
        context = super().get_context_data(**kwargs)
        context['title'] = _('Register')
        context['page_description'] = _('Create your account')
        return context
    
    def form_valid(self, form):
        """Handle valid form submission."""
        # Create user
        user = form.save()
        
        # Log registration
        ip_address = get_client_ip(self.request)
        logger.info(f'New user registered: {user.email} from IP {ip_address}')
        
        # Success message
        messages.success(
            self.request,
            _('Account created successfully! You can now log in.')
        )
        
        return super().form_valid(form)
    
    def form_invalid(self, form):
        """Handle invalid form submission."""
        messages.error(
            self.request,
            _('Please correct the errors below.')
        )
        return super().form_invalid(form)


class PasswordResetRequestView(FormView):
    """
    Password reset request view.
    
    Handles password reset token generation and email sending.
    """
    
    template_name = 'auth/password_reset_request.html'
    form_class = PasswordResetForm
    success_url = reverse_lazy('auth:password_reset_sent')
    
    def get_context_data(self, **kwargs):
        """
        Add additional context data to the template.
        
        Args:
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            dict: Context data for template
        """
        context = super().get_context_data(**kwargs)
        context['title'] = _('Reset Password')
        context['page_description'] = _('Enter your email to reset your password')
        return context
    
    def form_valid(self, form):
        """
        Handle valid form submission.
        
        Args:
            form: Valid password reset form
            
        Returns:
            HttpResponse: Response object
        """
        email = form.cleaned_data['email']
        
        try:
            user = User.objects.get(email=email, is_active=True)
            
            # Create password reset token
            reset_token = PasswordResetToken.objects.create(
                user=user,
                requested_ip=get_client_ip(self.request)
            )
            
            # Send password reset email
            self.send_password_reset_email(user, reset_token)
            
            # Log the password reset request
            logger.info(
                f'Password reset requested for user {user.email} from IP {get_client_ip(self.request)}'
            )
            
        except User.DoesNotExist:
            # Don't reveal if email exists or not for security
            pass
        
        return super().form_valid(form)
    
    def send_password_reset_email(self, user, reset_token):
        """
        Send password reset email to user.
        
        Args:
            user: User instance
            reset_token: PasswordResetToken instance
        """
        # Generate reset URL
        reset_url = self.request.build_absolute_uri(
            reverse('auth:password_reset_confirm', kwargs={
                'token': reset_token.token
            })
        )
        
        # Render email template
        html_message = render_to_string(
            'auth/emails/password_reset.html',
            {
                'user': user,
                'reset_url': reset_url,
                'site_name': getattr(settings, 'SITE_NAME', 'Our Site'),
                'expires_at': reset_token.expires_at
            }
        )
        
        plain_message = strip_tags(html_message)
        
        # Send email
        send_mail(
            subject=_('Password Reset Request'),
            message=plain_message,
            from_email=settings.DEFAULT_FROM_EMAIL,
            recipient_list=[user.email],
            html_message=html_message,
            fail_silently=False
        )


class PasswordResetConfirmView(FormView):
    """
    Password reset confirmation view.
    
    Handles password reset using the token.
    """
    
    template_name = 'auth/password_reset_confirm.html'
    form_class = SetPasswordForm
    success_url = reverse_lazy('auth:password_reset_complete')
    
    def dispatch(self, request, *args, **kwargs):
        """
        Validate token before processing request.
        
        Args:
            request: HTTP request object
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            HttpResponse: Response object
        """
        self.token = kwargs.get('token')
        
        try:
            self.reset_token = PasswordResetToken.objects.get(
                token=self.token
            )
            
            if not self.reset_token.is_valid():
                messages.error(
                    request,
                    _('This password reset link is invalid or has expired.')
                )
                return redirect('auth:password_reset_request')
                
        except PasswordResetToken.DoesNotExist:
            messages.error(
                request,
                _('This password reset link is invalid.')
            )
            return redirect('auth:password_reset_request')
        
        return super().dispatch(request, *args, **kwargs)
    
    def get_form_kwargs(self):
        """
        Add user to form kwargs.
        
        Returns:
            dict: Form kwargs
        """
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.reset_token.user
        return kwargs
    
    def get_context_data(self, **kwargs):
        """
        Add additional context data to the template.
        
        Args:
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            dict: Context data for template
        """
        context = super().get_context_data(**kwargs)
        context['title'] = _('Set New Password')
        context['page_description'] = _('Enter your new password')
        context['user'] = self.reset_token.user
        return context
    
    def form_valid(self, form):
        """
        Handle valid form submission.
        
        Args:
            form: Valid set password form
            
        Returns:
            HttpResponse: Response object
        """
        # Save new password
        user = form.save()
        
        # Mark token as used
        self.reset_token.use_token(get_client_ip(self.request))
        
        # Log the password reset
        logger.info(
            f'Password reset completed for user {user.email} from IP {get_client_ip(self.request)}'
        )
        
        # Invalidate all user sessions for security
        UserSession.objects.filter(user=user, is_active=True).update(
            is_active=False
        )
        
        messages.success(
            self.request,
            _('Your password has been reset successfully. Please log in with your new password.')
        )
        
        return super().form_valid(form)


class EmailVerificationView(View):
    """
    Email verification view.
    
    Handles email verification using tokens.
    """
    
    def get(self, request, token, *args, **kwargs):
        """
        Handle email verification GET request.
        
        Args:
            request: HTTP request object
            token: Verification token
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            HttpResponse: Response object
        """
        try:
            verification_token = EmailVerificationToken.objects.get(
                token=token
            )
            
            if verification_token.is_valid():
                # Verify the email
                verification_token.verify_email(get_client_ip(request))
                
                # Log the verification
                logger.info(
                    f'Email verified for user {verification_token.user.email} from IP {get_client_ip(request)}'
                )
                
                messages.success(
                    request,
                    _('Your email has been verified successfully!')
                )
                
                # Redirect to login if user is not authenticated
                if not request.user.is_authenticated:
                    return redirect('auth:login')
                else:
                    return redirect('core:dashboard')
            
            else:
                messages.error(
                    request,
                    _('This email verification link is invalid or has expired.')
                )
                
        except EmailVerificationToken.DoesNotExist:
            messages.error(
                request,
                _('This email verification link is invalid.')
            )
        
        return redirect('auth:login')


class ResendVerificationView(View):
    """
    Resend email verification view.
    
    Handles resending email verification tokens.
    """
    
    def get(self, request, user_id, *args, **kwargs):
        """
        Handle resend verification GET request.
        
        Args:
            request: HTTP request object
            user_id: User ID to resend verification for
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            HttpResponse: Response object
        """
        try:
            user = get_object_or_404(User, id=user_id)
            
            # Check if user is already verified
            if user.is_verified:
                messages.info(
                    request,
                    _('Your email is already verified.')
                )
                return redirect('auth:login')
            
            context = {
                'user': user,
                'title': _('Resend Email Verification')
            }
            
            return render(request, 'auth/resend_verification.html', context)
            
        except User.DoesNotExist:
            messages.error(
                request,
                _('User not found.')
            )
            return redirect('auth:login')
    
    def post(self, request, user_id, *args, **kwargs):
        """
        Handle resend verification POST request.
        
        Args:
            request: HTTP request object
            user_id: User ID to resend verification for
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            HttpResponse: Response object
        """
        try:
            user = get_object_or_404(User, id=user_id)
            
            # Check if user is already verified
            if user.is_verified:
                messages.info(
                    request,
                    _('Your email is already verified.')
                )
                return redirect('auth:login')
            
            # Check for existing unused tokens
            existing_token = EmailVerificationToken.objects.filter(
                user=user,
                is_used=False,
                expires_at__gt=timezone.now()
            ).first()
            
            if existing_token:
                # Use existing token
                verification_token = existing_token
            else:
                # Create new verification token
                import secrets
                token = secrets.token_urlsafe(32)
                
                verification_token = EmailVerificationToken.objects.create(
                    user=user,
                    token=token,
                    email=user.email,
                    expires_at=timezone.now() + timedelta(hours=24)
                )
            
            # Send verification email
            self.send_verification_email(user, verification_token)
            
            messages.success(
                request,
                _('Verification email has been sent to your email address.')
            )
            
            logger.info(
                f'Verification email resent for user {user.email} from IP {get_client_ip(request)}'
            )
            
            return redirect('auth:resend_verification', user_id=user.id)
            
        except User.DoesNotExist:
            messages.error(
                request,
                _('User not found.')
            )
            return redirect('auth:login')
        except Exception as e:
            logger.error(f'Error resending verification email: {str(e)}')
            messages.error(
                request,
                _('An error occurred while sending the verification email. Please try again.')
            )
            return redirect('auth:resend_verification', user_id=user_id)
    
    def send_verification_email(self, user, verification_token):
        """
        Send email verification email to user.
        
        Args:
            user: User instance
            verification_token: EmailVerificationToken instance
        """
        # Generate verification URL
        verification_url = self.request.build_absolute_uri(
            reverse('auth:verify_email', kwargs={
                'token': verification_token.token
            })
        )
        
        # Prepare email content
        subject = _('Verify Your Email Address')
        
        # Create a simple HTML message since we don't have the email template
        html_message = f"""
        <html>
        <body>
            <h2>Email Verification</h2>
            <p>Hello {user.first_name or user.email},</p>
            <p>Please click the link below to verify your email address:</p>
            <p><a href="{verification_url}" style="background-color: #007bff; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">Verify Email</a></p>
            <p>Or copy and paste this link in your browser:</p>
            <p>{verification_url}</p>
            <p>This link will expire in 24 hours.</p>
            <p>If you didn't request this verification, please ignore this email.</p>
        </body>
        </html>
        """
        
        plain_message = f"""
        Email Verification
        
        Hello {user.first_name or user.email},
        
        Please visit the following link to verify your email address:
        {verification_url}
        
        This link will expire in 24 hours.
        
        If you didn't request this verification, please ignore this email.
        """
        
        # Send email
        try:
            send_mail(
                subject=subject,
                message=plain_message,
                from_email=settings.DEFAULT_FROM_EMAIL,
                recipient_list=[user.email],
                html_message=html_message,
                fail_silently=False
            )
        except Exception as e:
            logger.error(f'Failed to send verification email: {str(e)}')
            raise


@login_required
def user_sessions_view(request):
    """
    View for managing user sessions.
    
    Args:
        request: HTTP request object
        
    Returns:
        HttpResponse: Response object
    """
    # Get active sessions for the current user
    sessions = UserSession.get_active_sessions_for_user(request.user)
    
    # Get current session
    current_session_key = request.session.session_key
    
    context = {
        'title': _('Active Sessions'),
        'sessions': sessions,
        'current_session_key': current_session_key,
    }
    
    return render(request, 'auth/user_sessions.html', context)


@login_required
@require_http_methods(["POST"])
def invalidate_session_view(request, session_id):
    """
    View for invalidating a specific user session.
    
    Args:
        request: HTTP request object
        session_id: Session ID to invalidate
        
    Returns:
        HttpResponse: Response object
    """
    try:
        session = UserSession.objects.get(
            id=session_id,
            user=request.user,
            is_active=True
        )
        
        # Don't allow invalidating current session
        if session.session_key == request.session.session_key:
            messages.error(
                request,
                _('You cannot invalidate your current session.')
            )
        else:
            session.invalidate()
            messages.success(
                request,
                _('Session invalidated successfully.')
            )
            
    except UserSession.DoesNotExist:
        messages.error(
            request,
            _('Session not found or already invalidated.')
        )
    
    return redirect('auth:user_sessions')


# API Views for REST API endpoints

class CustomAuthTokenView(ObtainAuthToken):
    """
    Custom API authentication view.
    
    Extends the default token authentication with additional features.
    """
    
    def post(self, request, *args, **kwargs):
        """
        Handle token authentication request.
        
        Args:
            request: HTTP request object
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            Response: API response
        """
        serializer = self.serializer_class(
            data=request.data,
            context={'request': request}
        )
        
        if serializer.is_valid():
            user = serializer.validated_data['user']
            token, created = Token.objects.get_or_create(user=user)
            
            # Log successful API authentication
            LoginAttempt.objects.create(
                user=user,
                attempted_email=user.email,
                ip_address=get_client_ip(request),
                user_agent=request.META.get('HTTP_USER_AGENT', ''),
                is_successful=True
            )
            
            return Response({
                'token': token.key,
                'user_id': user.pk,
                'email': user.email,
                'first_name': user.first_name,
                'last_name': user.last_name
            })
        
        # Log failed API authentication
        email = request.data.get('username', '')
        LoginAttempt.objects.create(
            attempted_email=email,
            ip_address=get_client_ip(request),
            user_agent=request.META.get('HTTP_USER_AGENT', ''),
            is_successful=False,
            failure_reason='invalid_api_credentials'
        )
        
        return Response(
            serializer.errors,
            status=status.HTTP_400_BAD_REQUEST
        )


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def api_logout_view(request):
    """
    API logout view.
    
    Args:
        request: HTTP request object
        
    Returns:
        Response: API response
    """
    try:
        # Delete the user's token
        request.user.auth_token.delete()
        
        return Response(
            {'message': _('Successfully logged out.')},
            status=status.HTTP_200_OK
        )
    except Exception as e:
        return Response(
            {'error': _('Logout failed.')},
            status=status.HTTP_400_BAD_REQUEST
        )


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_user_sessions_view(request):
    """
    API view for getting user sessions.
    
    Args:
        request: HTTP request object
        
    Returns:
        Response: API response with user sessions
    """
    sessions = UserSession.get_active_sessions_for_user(request.user)
    
    sessions_data = []
    for session in sessions:
        sessions_data.append({
            'id': session.id,
            'ip_address': session.ip_address,
            'device_type': session.device_type,
            'browser': session.browser,
            'operating_system': session.operating_system,
            'country': session.country,
            'city': session.city,
            'last_activity': session.last_activity,
            'is_current': session.session_key == request.session.session_key
        })
    
    return Response({
        'sessions': sessions_data
    }, status=status.HTTP_200_OK)


# Template Views

class PasswordResetSentView(TemplateView):
    """
    Password reset email sent confirmation view.
    """
    template_name = 'auth/password_reset_sent.html'
    
    def get_context_data(self, **kwargs):
        """
        Add additional context data to the template.
        
        Args:
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            dict: Context data for template
        """
        context = super().get_context_data(**kwargs)
        context['title'] = _('Password Reset Email Sent')
        return context


class PasswordResetCompleteView(TemplateView):
    """
    Password reset complete confirmation view.
    """
    template_name = 'auth/password_reset_complete.html'
    
    def get_context_data(self, **kwargs):
        """
        Add additional context data to the template.
        
        Args:
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            dict: Context data for template
        """
        context = super().get_context_data(**kwargs)
        context['title'] = _('Password Reset Complete')
        return context




# class LoginView(LoginView):
#     template_name = 'auth/login.html'
#     redirect_authenticated_user = True
#     extra_context = {'title': 'Login'}
    
#     def get_success_url(self):
#         return reverse_lazy('core:dashboard')


# class LogoutView(LogoutView):
#     template_name = 'auth/logout.html'
#     extra_context = {'title': 'Logout'}


# class RegistrationView(CreateView):
#     template_name = 'auth/register.html'
#     extra_context = {'title': 'Register'}
#     model = User
#     fields = ['username', 'email', 'password']

#     def get_success_url(self):
#         return reverse_lazy('auth:login')
    
#     def form_valid(self, form):
#         response = super().form_valid(form)
#         login(self.request, self.object)
#         return response


# class PasswordResetView(PasswordResetView):
#     template_name = 'auth/password_reset.html'
#     extra_context = {'title': 'Reset Password'}
#     email_template_name = 'auth/password_reset_email.html'
#     subject_template_name = 'auth/password_reset_subject.txt'
#     success_url = reverse_lazy('auth:password_reset_done')

#     def form_valid(self, form):
#         response = super().form_valid(form)
#         return response

#     def form_invalid(self, form):
#         response = super().form_invalid(form)
#         return response


# class PasswordResetConfirmView(PasswordResetConfirmView):
#     template_name = 'auth/password_reset_confirm.html'
#     extra_context = {'title': 'Reset Password'}
#     success_url = reverse_lazy('auth:password_change_done')

#     def form_valid(self, form):
#         response = super().form_valid(form)
#         return response

#     def form_invalid(self, form):
#         response = super().form_invalid(form)
#         return response


# class PasswordChangeView(PasswordChangeView):
#     template_name = 'auth/password_change.html'
#     extra_context = {'title': 'Change Password'}
#     success_url = reverse_lazy('auth:password_change_done')

#     def form_valid(self, form):
#         response = super().form_valid(form)
#         return response

#     def form_invalid(self, form):
#         response = super().form_invalid(form)
#         return response


# class PasswordChangeDoneView(PasswordChangeDoneView):
#     template_name = 'auth/password_change_done.html'
#     extra_context = {'title': 'Change Password'}


# class PasswordResetDoneView(PasswordResetDoneView):
#     template_name = 'auth/password_reset_done.html'
#     extra_context = {'title': 'Reset Password'}


# class ActivationView(TemplateView):
#     template_name = 'auth/activation.html'
#     extra_context = {'title': 'Activate Account'}


# class ResendActivationView(TemplateView):
#     template_name = 'auth/resend_activation.html'
#     extra_context = {'title': 'Resend Activation'}



# from django.views import View
# from django.contrib import messages
# from django.shortcuts import render, redirect
# from django.http import HttpResponseNotAllowed
# from django.contrib.auth.mixins import LoginRequiredMixin
# from django.contrib.auth import authenticate, login, logout

# from apps.accounts.models import Account

# # Create your views here.

# class LoginView(View): 
    
#     # Handle GET request logic.
#     def get(self, request, *args, **kwargs):
#         # If user is already authenticated, redirect to the dashboard.
#         if request.user.is_authenticated:
#             return redirect("core:dashboard") 
#         template = "authentication/login.html"
#         context={}
#         # Render the login form for GET requests. 
#         return render(request, template, context)  
    
#     # Handle POST request logic.    
#     def post(self, request, *args, **kwargs):  
#         # Extract username (email) and password from the POST data.
#         email = request.POST.get("email")
#         password = request.POST.get("password")  
#         # Check if both email and password are provided.
#         if email and password:
#             # Fetch the user based on the provided email.
#             user = Account.objects.filter(email=email).first() 
#             # If a user with the provided email exists.
#             if user:
#                 # Check if the user is not active and not a superuser.
#                 if not user.is_active and not user.is_superuser: 
#                     # Redirect to the login page with the appropriate message. 
#                     messages.error(request, "Your account is not active.")
#                     return redirect("authentication:login") 
#                 # Check if the provided password is correct.
#                 if not user.check_password(password): 
#                     # Redirect to the login page with the appropriate message.  
#                     messages.error(request, "Invalid password.")
#                     return redirect("authentication:login")  
#                 # Authenticate the user.
#                 user = authenticate(request, email=email, password=password)
#                 # If the user is authenticated.
#                 if user is not None:
#                     # Login the user.
#                     login(request, user) 
#                     # Redirect to the dashboard or desired page.
#                     return redirect("core:dashboard") 
#                 else: 
#                     # Redirect to the login page with the appropriate message.  
#                     messages.error(request, "Authentication failed.")
#                     return redirect("authentication:login")  
#             else: 
#                 # Redirect to the login page with the appropriate message.  
#                 messages.error(request, "User with this email does not exist.")
#                 return redirect("authentication:login")   
#         else: 
#             # Redirect to the login page with the appropriate message.  
#             messages.error(request, "Please provide both email and password.")
#             return redirect("authentication:login")   
        
#     # Handle other HTTP methods using dispatch method
#     def dispatch(self, request, *args, **kwargs):
#         if request.method not in ["GET", "POST"]:
#             return HttpResponseNotAllowed(["GET", "POST"])
#         return super().dispatch(request, *args, **kwargs)

# class LogoutView(LoginRequiredMixin, View):  
    
#     # Handle GET request logic. 
#     def get(self, request, *args, **kwargs):
#         logout(request)
#         self.request.session.flush()
#         return redirect("authentication:login") 
    
#     # Handle POST request logic. 
#     def post(self, request, *args, **kwargs):
#         logout(request)
#         self.request.session.flush()
#         return redirect("authentication:login") 
    
#     # Handle other HTTP methods using dispatch method
#     def dispatch(self, request, *args, **kwargs):
#         if request.method not in ["GET", "POST"]:
#             return HttpResponseNotAllowed(["GET", "POST"])
#         return super().dispatch(request, *args, **kwargs)