# -*- coding: utf-8 -*-
"""
Core Views Module

This module contains views for the core app including landing pages,
dashboard, error pages, and common functionality used across the application.
"""

from django.shortcuts import render
from django.views.generic import TemplateView, View
from django.contrib.auth.mixins import LoginRequiredMixin 
from django.http import JsonResponse
from django.urls import reverse_lazy, reverse
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page 
from django.core.cache import cache
from django.conf import settings
from django.utils.translation import gettext_lazy as _ 
from django.utils import timezone
from datetime import timedelta  

from apps.accounts.models import User, Role
from apps.authentication.models import LoginAttempt, UserSession 
from apps.common.utils import is_ajax_request

import logging

# Set up logging
logger = logging.getLogger(__name__)

class HomeView(TemplateView):
    """
    Landing page view for the application.
    
    Displays the main landing page with application information,
    features, and call-to-action elements for visitors.
    """
    
    template_name = "core/home.html"
    
    def get_context_data(self, **kwargs):
        """
        Add context data for the home page.
        
        Args:
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Context data for template rendering
        """
        context = super().get_context_data(**kwargs)
        
        # Add application statistics for landing page
        context.update({
            "title": _("Home"),
            "total_users": self.get_total_users(),
            "app_name": getattr(settings, "APP_NAME", "Django App"),
            "app_version": getattr(settings, "APP_VERSION", "1.0.0"),
            "features": self.get_app_features(),
            "testimonials": self.get_testimonials(),
        })
        
        return context
    
    def get_total_users(self):
        """
        Get total number of registered users.
        
        Returns:
            int: Total user count
        """
        try:
            return User.objects.filter(is_active=True).count()
        except Exception as e:
            logger.error(f"Error getting user count: {e}")
            return 0
    
    def get_app_features(self):
        """
        Get list of application features for display.
        
        Returns:
            list: List of feature dictionaries
        """
        return [
            {
                "title": _("User Management"),
                "description": _("Comprehensive user account management with roles and permissions"),
                "icon": "fas fa-users"
            },
            {
                "title": _("Secure Authentication"),
                "description": _("Advanced authentication with session management and security features"),
                "icon": "fas fa-shield-alt"
            },
            {
                "title": _("Role-Based Access"),
                "description": _("Dynamic role and permission system for flexible access control"),
                "icon": "fas fa-key"
            },
            {
                "title": _("Dashboard Analytics"),
                "description": _("Comprehensive dashboard with real-time analytics and insights"),
                "icon": "fas fa-chart-bar"
            }
        ]
    
    def get_testimonials(self):
        """
        Get testimonials for the landing page.
        
        Returns:
            list: List of testimonial dictionaries
        """
        return [
            {
                "name": "John Doe",
                "role": "Project Manager",
                "content": "This application has streamlined our user management process significantly.",
                "rating": 5
            },
            {
                "name": "Jane Smith",
                "role": "System Administrator",
                "content": "The security features and role management are exactly what we needed.",
                "rating": 5
            }
        ]


class AboutView(TemplateView):
    """
    About page view.
    
    Displays information about the application, team, and company.
    """
    
    template_name = "core/about.html"
    
    def get_context_data(self, **kwargs):
        """
        Add about page context data.
        
        Args:
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Context data for template rendering
        """
        context = super().get_context_data(**kwargs)
        
        context.update({
            "title": _("About Us"),
            "app_info": self.get_app_info(),
            "team_members": self.get_team_members(),
            "company_info": self.get_company_info(),
        })
        
        return context
    
    def get_app_info(self):
        """
        Get application information.
        
        Returns:
            dict: Application information
        """
        return {
            "name": getattr(settings, "APP_NAME", "Django Application"),
            "version": getattr(settings, "APP_VERSION", "1.0.0"),
            "description": "A professional Django application with user management and authentication.",
            "technologies": ["Django", "Python", "PostgreSQL", "Redis", "Bootstrap"],
            "launch_date": "2024"
        }
    
    def get_team_members(self):
        """
        Get team member information.
        
        Returns:
            list: List of team member dictionaries
        """
        return [
            {
                "name": "Senior Django Developer",
                "role": "Lead Developer",
                "bio": "Experienced Django developer with expertise in building scalable web applications.",
                "avatar": "/static/images/team/developer.jpg"
            }
        ]
    
    def get_company_info(self):
        """
        Get company information.
        
        Returns:
            dict: Company information
        """
        return {
            "name": "Your Company Name",
            "founded": "2024",
            "mission": "To provide excellent software solutions that help businesses grow.",
            "values": ["Innovation", "Quality", "Customer Focus", "Integrity"]
        }


class ContactView(TemplateView):
    """
    Contact page view.
    
    Displays contact information and contact form.
    """
    
    template_name = "core/contact.html"
    
    def get_context_data(self, **kwargs):
        """
        Add contact page context data.
        
        Args:
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Context data for template rendering
        """
        context = super().get_context_data(**kwargs)
        
        context.update({
            "contact_info": self.get_contact_info(),
            "office_locations": self.get_office_locations(),
            "title": "Contact Us",
        })
        
        return context
    
    def get_contact_info(self):
        """
        Get contact information.
        
        Returns:
            dict: Contact information
        """
        return {
            "email": "contact@yourcompany.com",
            "phone": "+1 (555) 123-4567",
            "address": "123 Business Street, City, State 12345",
            "business_hours": "Monday - Friday: 9:00 AM - 6:00 PM"
        }
    
    def get_office_locations(self):
        """
        Get office location information.
        
        Returns:
            list: List of office locations
        """
        return [
            {
                "name": "Main Office",
                "address": "123 Business Street, City, State 12345",
                "phone": "+1 (555) 123-4567",
                "email": "main@yourcompany.com"
            }
        ]


class PrivacyView(TemplateView):
    """
    Privacy policy page view.
    
    Displays the privacy policy and information about data protection.
    """
    template_name = "core/privacy.html"

    def get_context_data(self, **kwargs):
        """
        Add privacy page context data.
        
        Args:
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Context data for template rendering
        """
        context = super().get_context_data(**kwargs)
        
        context.update({
            "title": _("Privacy Policy"),
        })
        
        return context


class TOSView(TemplateView):
    """
    Terms of Service page view.
    
    Displays the terms and conditions for using the application.
    """
    template_name = "core/tos.html"

    def get_context_data(self, **kwargs):
        """
        Add terms of service page context data.
        """
        context = super().get_context_data(**kwargs)
        context.update({
            "title": _("Terms of Service"),
        })
        return context


class DashboardView(LoginRequiredMixin, TemplateView):
    """
    Main dashboard view for authenticated users.
    
    Displays user-specific dashboard with statistics, recent activity,
    and quick access to common functions.
    """
    
    template_name = "core/dashboard.html"
    login_url = reverse_lazy("auth:login")
    
    def get_context_data(self, **kwargs):
        """
        Add dashboard context data.
        
        Args:
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Context data for template rendering
        """
        context = super().get_context_data(**kwargs)
        user = self.request.user
        
        # Add dashboard statistics
        context.update({
            "title": _("Dashboard"),
            "user_stats": self.get_user_stats(user),
            "system_stats": self.get_system_stats(user),
            "recent_activity": self.get_recent_activity(user),
            "quick_actions": self.get_quick_actions(user),
            "notifications": self.get_user_notifications(user),
            "dashboard_widgets": self.get_dashboard_widgets(user),
        })
        
        return context
    
    def get_user_stats(self, user):
        """
        Get statistics specific to the current user.
        
        Args:
            user: Current user instance
            
        Returns:
            dict: User-specific statistics
        """
        try:
            # Get user"s login history
            login_attempts = LoginAttempt.objects.filter(
                user=user,
                is_successful=True,
                created_at__gte=timezone.now() - timedelta(days=30)
            ).count()
            
            # Get user"s active sessions
            active_sessions = UserSession.objects.filter(
                user=user,
                is_active=True
            ).count()
            
            return {
                "login_count_30_days": login_attempts,
                "active_sessions": active_sessions,
                "account_age_days": (timezone.now().date() - user.date_joined.date()).days,
                "roles_count": user.roles.count(),
                "last_login": user.last_login,
            }
        except Exception as e:
            logger.error(f"Error getting user stats: {e}")
            return {}
    
    def get_system_stats(self, user):
        """
        Get system-wide statistics (for admin users).
        
        Args:
            user: Current user instance
            
        Returns:
            dict: System statistics
        """
        if not user.is_staff:
            return {}
        
        try:
            # Calculate date ranges
            today = timezone.now().date()
            week_ago = today - timedelta(days=7)
            month_ago = today - timedelta(days=30)
            
            return {
                "total_users": User.objects.count(),
                "active_users": User.objects.filter(is_active=True).count(),
                "new_users_week": User.objects.filter(
                    date_joined__gte=week_ago
                ).count(),
                "new_users_month": User.objects.filter(
                    date_joined__gte=month_ago
                ).count(),
                "total_roles": Role.objects.count(),
                "failed_logins_today": LoginAttempt.objects.filter(
                    is_successful=False,
                    created_at__date=today
                ).count(),
            }
        except Exception as e:
            logger.error(f"Error getting system stats: {e}")
            return {}
    
    def get_recent_activity(self, user):
        """
        Get recent activity for the user.
        
        Args:
            user: Current user instance
            
        Returns:
            list: List of recent activity items
        """
        try:
            activities = []
            
            # Get recent login attempts
            recent_logins = LoginAttempt.objects.filter(
                user=user,
                created_at__gte=timezone.now() - timedelta(days=7)
            ).order_by("-created_at")[:5]
            
            for login in recent_logins:
                activities.append({
                    "type": "login",
                    "description": f"Logged in from {login.ip_address}",
                    "timestamp": login.created_at,
                    "success": login.is_successful
                })
            
            # Sort by timestamp
            activities.sort(key=lambda x: x["timestamp"], reverse=True)
            
            return activities[:10]  # Return last 10 activities
        except Exception as e:
            logger.error(f"Error getting recent activity: {e}")
            return []
    
    def get_quick_actions(self, user):
        """
        Get quick action buttons for the user.
        
        Args:
            user: Current user instance
            
        Returns:
            list: List of quick action dictionaries
        """
        actions = [
            {
                "title": _("Edit Profile"),
                "url": reverse("accounts:profile_edit"),
                "icon": "fas fa-user-edit",
                "color": "primary"
            },
            {
                "title": _("Account Settings"),
                "url": reverse("accounts:settings"),
                "icon": "fas fa-cog",
                "color": "secondary"
            }
        ]
        
        # Add admin actions for staff users
        if user.is_staff:
            actions.extend([
                {
                    "title": _("Manage Users"),
                    "url": reverse("accounts:user_list"),
                    "icon": "fas fa-users-cog",
                    "color": "info"
                },
                {
                    "title": _("Manage Roles"),
                    "url": reverse("accounts:role_list"),
                    "icon": "fas fa-user-tag",
                    "color": "warning"
                }
            ])
        
        return actions
    
    def get_user_notifications(self, user):
        """
        Get notifications for the user.
        
        Args:
            user: Current user instance
            
        Returns:
            list: List of notification dictionaries
        """
        notifications = []
        
        # Check if email is verified
        if not user.is_verified:
            notifications.append({
                "type": "warning",
                "title": _("Email Not Verified"),
                "message": _("Please verify your email address to access all features."),
                "action_url": reverse("accounts:resend_verification"),
                "action_text": _("Resend Verification")
            })
        
        # Check for security alerts
        recent_failed_logins = LoginAttempt.objects.filter(
            user=user,
            is_successful=False,
            created_at__gte=timezone.now() - timedelta(hours=24)
        ).count()
        
        if recent_failed_logins > 3:
            notifications.append({
                "type": "danger",
                "title": _("Security Alert"),
                "message": f"{recent_failed_logins} failed login attempts in the last 24 hours.",
                "action_url": reverse("auth:user_sessions"),
                "action_text": _("Review Sessions")
            })
        
        return notifications
    
    def get_dashboard_widgets(self, user):
        """
        Get dashboard widgets configuration.
        
        Args:
            user: Current user instance
            
        Returns:
            list: List of widget configurations
        """
        widgets = [
            {
                "id": "user_stats",
                "title": _("Account Statistics"),
                "type": "stats",
                "size": "col-md-6"
            },
            {
                "id": "recent_activity",
                "title": _("Recent Activity"),
                "type": "activity",
                "size": "col-md-6"
            }
        ]
        
        # Add admin widgets for staff users
        if user.is_staff:
            widgets.extend([
                {
                    "id": "system_stats",
                    "title": _("System Statistics"),
                    "type": "system_stats",
                    "size": "col-md-12"
                },
                {
                    "id": "user_chart",
                    "title": _("User Growth"),
                    "type": "chart",
                    "size": "col-md-6"
                },
                {
                    "id": "security_alerts",
                    "title": _("Security Alerts"),
                    "type": "security",
                    "size": "col-md-6"
                }
            ])
        
        return widgets


# Error Views
class Error404View(TemplateView):
    """
    Custom 404 error page view.
    
    Displays a user-friendly 404 error page with navigation options.
    """
    
    template_name = "errors/404.html"
    
    def get_context_data(self, **kwargs):
        """
        Add 404 error context data.
        
        Args:
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Context data for template rendering
        """
        context = super().get_context_data(**kwargs)
        
        context.update({
            "error_code": "404",
            "error_title": _("Page Not Found"),
            "error_message": _("The page you are looking for does not exist."),
            "suggestions": [
                {"text": _("Go to Homepage"), "url": reverse("core:home")},
                {"text": _("Go to Dashboard"), "url": reverse("core:dashboard")},
                {"text": _("Contact Support"), "url": reverse("core:contact")}
            ]
        })
        
        return context


class Error500View(TemplateView):
    """
    Custom 500 error page view.
    
    Displays a user-friendly 500 error page with support information.
    """
    
    template_name = "errors/500.html"
    
    def get_context_data(self, **kwargs):
        """
        Add 500 error context data.
        
        Args:
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Context data for template rendering
        """
        context = super().get_context_data(**kwargs)
        
        context.update({
            "error_code": "500",
            "error_title": _("Internal Server Error"),
            "error_message": _("Something went wrong on our end. Please try again later."),
            "support_email": "support@yourcompany.com"
        })
        
        return context


class Error403View(TemplateView):
    """
    Custom 403 error page view.
    
    Displays a user-friendly 403 error page for permission denied.
    """
    
    template_name = "errors/403.html"
    
    def get_context_data(self, **kwargs):
        """
        Add 403 error context data.
        
        Args:
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Context data for template rendering
        """
        context = super().get_context_data(**kwargs)
        
        context.update({
            "error_code": "403",
            "error_title": _("Access Forbidden"),
            "error_message": _("You do not have permission to access this resource."),
        })
        
        return context


@method_decorator(cache_page(60 * 15), name="dispatch")  # Cache for 15 minutes
class HealthCheckView(View):
    """
    Health check endpoint for monitoring.
    
    Returns application health status and basic metrics.
    """
    
    def get(self, request):
        """
        Handle GET request for health check.
        
        Args:
            request: HTTP request object
            
        Returns:
            JsonResponse: Health check data
        """
        try:
            # Check database connectivity
            user_count = User.objects.count()
            
            # Check cache connectivity
            cache_key = "health_check_test"
            cache.set(cache_key, "test", 60)
            cache_test = cache.get(cache_key)
            
            health_data = {
                "status": "healthy",
                "timestamp": timezone.now().isoformat(),
                "database": "connected",
                "cache": "connected" if cache_test == "test" else "disconnected",
                "user_count": user_count,
                "version": getattr(settings, "APP_VERSION", "1.0.0")
            }
            
            return JsonResponse(health_data)
        
        except Exception as e:
            logger.error(f"Health check failed: {e}")
            return JsonResponse({
                "status": "unhealthy",
                "error": str(e),
                "timestamp": timezone.now().isoformat()
            }, status=500)

# ============================================================================
# Error Views
# ============================================================================

# Utility Functions
def handler404(request, exception):
    """
    Custom 404 error handler.
    
    Args:
        request: HTTP request object
        exception: Exception that caused 404
        
    Returns:
        HttpResponse: 404 error page
    """
    # Check if the request is an AJAX request
    if is_ajax_request(request):
        return error_response(
            message=_('Page not found'),
            status=404
        ) 
    # render 404 page
    return render(request, "errors/404.html", status=404)


def handler500(request):
    """
    Custom 500 error handler.
    
    Args:
        request: HTTP request object
        
    Returns:
        HttpResponse: 500 error page
    """
    # Check if the request is an AJAX request
    if is_ajax_request(request):
        return error_response(
            message=_('Internal server error'),
            status=500
        ) 
    # render 500 page
    return render(request, "errors/500.html", status=500)


def handler403(request, exception):
    """
    Custom 403 error handler.
    
    Args:
        request: HTTP request object
        exception: Exception that caused 403
        
    Returns:
        HttpResponse: 403 error page
    """
    # Check if the request is an AJAX request
    if is_ajax_request(request):
        return error_response(
            message=_('Forbidden'),
            status=403
        )
    # render 403 page
    return render(request, "errors/403.html", status=403)


def handler400(request, exception):
    """
    Custom 400 error handler.
    
    Args:
        request: HTTP request object
        exception: Exception that caused 400
        
    Returns:
        HttpResponse: 400 error page
    """
    # Check if the request is an AJAX request
    if is_ajax_request(request):
        return error_response(
            message=_('Bad request'),
            status=400
        )
    # render 400 page
    return render(request, "errors/400.html", status=400)
