"""
Role-Based Dashboard Customization Service
Provides dynamic dashboard widgets and quick actions based on user roles and permissions
"""
from django.db.models import Count, Sum, Avg, Q
from django.utils import timezone
from datetime import datetime, timedelta
from typing import Dict, List, Any, Optional
import logging

logger = logging.getLogger(__name__)


class RoleBasedDashboardService:
    """
    Service for generating role-specific dashboard content and widgets
    """
    
    def __init__(self, user):
        self.user = user
        self.role = user.role
        self.branch = user.branch
    
    def get_dashboard_context(self) -> Dict[str, Any]:
        """
        Get complete dashboard context based on user role and permissions
        
        Returns:
            Dictionary containing all dashboard data for the user
        """
        try:
            context = {
                'user': self.user,
                'quick_actions': self.get_quick_actions(),
                'recent_activities': self.get_recent_activities(),
                'notifications': self.get_notifications(),
                'unread_notifications_count': self.get_unread_notifications_count(),
                'contextual_help': self.get_contextual_help(),
            }
            
            # Add role-specific context
            if self.role == 'admin':
                context.update(self.get_admin_context())
            elif self.role == 'team_leader':
                context.update(self.get_team_leader_context())
            elif self.role == 'loan_officer':
                context.update(self.get_loan_officer_context())
            elif self.role == 'secretary':
                context.update(self.get_secretary_context())
            elif self.role == 'auditor':
                context.update(self.get_auditor_context())
            
            return context
            
        except Exception as e:
            logger.error(f"Error generating dashboard context for user {self.user.id}: {e}")
            return self.get_fallback_context()
    
    def get_quick_actions(self) -> List[Dict[str, Any]]:
        """
        Get role-specific quick actions based on user permissions
        """
        actions = []
        
        try:
            # Common actions for all roles
            base_actions = [
                {
                    'title': 'My Profile',
                    'description': 'Update profile',
                    'icon': 'user',
                    'color': 'blue',
                    'url': f'/users/profile/{self.user.id}/',
                    'permission_check': True  # Always available
                },
                {
                    'title': 'Notifications',
                    'description': 'View messages',
                    'icon': 'bell',
                    'color': 'yellow',
                    'url': '/utils/notifications/',
                    'permission_check': True  # Always available
                }
            ]
            
            # Role-specific actions
            role_actions = {
                'admin': [
                    {
                        'title': 'User Management',
                        'description': 'Manage staff',
                        'icon': 'users-cog',
                        'color': 'red',
                        'url': '/users/admin/',
                        'permission_check': self.user.has_page_permission('users', 'manage_staff')
                    },
                    {
                        'title': 'System Settings',
                        'description': 'Configure system',
                        'icon': 'cogs',
                        'color': 'gray',
                        'url': '/utils/settings/',
                        'permission_check': self.user.has_page_permission('settings', 'manage_system')
                    },
                    {
                        'title': 'Reports',
                        'description': 'System reports',
                        'icon': 'chart-bar',
                        'color': 'purple',
                        'url': '/reports/',
                        'permission_check': self.user.has_page_permission('reports', 'view_all')
                    },
                    {
                        'title': 'Audit Logs',
                        'description': 'View audit trail',
                        'icon': 'history',
                        'color': 'indigo',
                        'url': '/users/audit-logs/',
                        'permission_check': self.user.has_page_permission('audit', 'view_logs')
                    }
                ],
                'team_leader': [
                    {
                        'title': 'Team Performance',
                        'description': 'View team stats',
                        'icon': 'chart-line',
                        'color': 'blue',
                        'url': '/users/team-performance/',
                        'permission_check': self.user.has_page_permission('team', 'view_performance')
                    },
                    {
                        'title': 'Portfolio Analytics',
                        'description': 'Portfolio insights',
                        'icon': 'briefcase',
                        'color': 'green',
                        'url': '/users/portfolio-analytics/',
                        'permission_check': self.user.has_page_permission('portfolio', 'view_analytics')
                    },
                    {
                        'title': 'Loan Approvals',
                        'description': 'Approve loans',
                        'icon': 'check-circle',
                        'color': 'emerald',
                        'url': '/loans/approvals/',
                        'permission_check': self.user.has_page_permission('loans', 'approve_loans')
                    },
                    {
                        'title': 'Staff Management',
                        'description': 'Manage team',
                        'icon': 'users',
                        'color': 'cyan',
                        'url': '/users/team/',
                        'permission_check': self.user.has_page_permission('users', 'manage_team')
                    }
                ],
                'loan_officer': [
                    {
                        'title': 'My Clients',
                        'description': 'Manage clients',
                        'icon': 'address-book',
                        'color': 'green',
                        'url': '/users/my-clients/',
                        'permission_check': self.user.has_page_permission('clients', 'view_assigned')
                    },
                    {
                        'title': 'New Application',
                        'description': 'Create loan app',
                        'icon': 'plus-circle',
                        'color': 'blue',
                        'url': '/loans/create/',
                        'permission_check': self.user.has_page_permission('loans', 'create_application')
                    },
                    {
                        'title': 'Pending Tasks',
                        'description': 'View tasks',
                        'icon': 'tasks',
                        'color': 'orange',
                        'url': '/loans/pending/',
                        'permission_check': self.user.has_page_permission('loans', 'view_pending')
                    },
                    {
                        'title': 'Collections',
                        'description': 'Record payments',
                        'icon': 'money-bill-wave',
                        'color': 'emerald',
                        'url': '/payments/collections/',
                        'permission_check': self.user.has_page_permission('payments', 'record_payment')
                    }
                ],
                'secretary': [
                    {
                        'title': 'Document Center',
                        'description': 'Manage documents',
                        'icon': 'file-alt',
                        'color': 'purple',
                        'url': '/utils/documents/',
                        'permission_check': self.user.has_page_permission('documents', 'manage_documents')
                    },
                    {
                        'title': 'Client Registration',
                        'description': 'Register clients',
                        'icon': 'user-plus',
                        'color': 'green',
                        'url': '/users/register-client/',
                        'permission_check': self.user.has_page_permission('clients', 'create_client')
                    },
                    {
                        'title': 'Communication',
                        'description': 'Client messages',
                        'icon': 'comments',
                        'color': 'blue',
                        'url': '/utils/communication/',
                        'permission_check': self.user.has_page_permission('communication', 'manage_messages')
                    },
                    {
                        'title': 'Appointments',
                        'description': 'Schedule meetings',
                        'icon': 'calendar',
                        'color': 'indigo',
                        'url': '/utils/appointments/',
                        'permission_check': self.user.has_page_permission('appointments', 'manage_schedule')
                    }
                ],
                'auditor': [
                    {
                        'title': 'Audit Dashboard',
                        'description': 'Audit overview',
                        'icon': 'search',
                        'color': 'yellow',
                        'url': '/reports/audit-dashboard/',
                        'permission_check': self.user.has_page_permission('audit', 'view_dashboard')
                    },
                    {
                        'title': 'Compliance Reports',
                        'description': 'View compliance',
                        'icon': 'clipboard-check',
                        'color': 'green',
                        'url': '/reports/compliance/',
                        'permission_check': self.user.has_page_permission('reports', 'view_compliance')
                    },
                    {
                        'title': 'Risk Analysis',
                        'description': 'Analyze risks',
                        'icon': 'exclamation-triangle',
                        'color': 'red',
                        'url': '/reports/risk-analysis/',
                        'permission_check': self.user.has_page_permission('reports', 'view_risk')
                    },
                    {
                        'title': 'Data Export',
                        'description': 'Export data',
                        'icon': 'download',
                        'color': 'cyan',
                        'url': '/reports/export/',
                        'permission_check': self.user.has_page_permission('reports', 'export_data')
                    }
                ]
            }
            
            # Combine base actions with role-specific actions
            actions.extend(base_actions)
            if self.role in role_actions:
                actions.extend(role_actions[self.role])
            
            return actions
            
        except Exception as e:
            logger.error(f"Error generating quick actions for user {self.user.id}: {e}")
            return base_actions if 'base_actions' in locals() else []
    
    def get_admin_context(self) -> Dict[str, Any]:
        """Get admin-specific dashboard context"""
        try:
            from .models import CustomUser
            from utils.models import UserAccessLog
            
            # System statistics
            total_users = CustomUser.objects.count()
            active_users = CustomUser.objects.filter(is_active=True).count()
            new_users_this_month = CustomUser.objects.filter(
                date_joined__gte=timezone.now().replace(day=1)
            ).count()
            
            # Active sessions (approximate)
            active_sessions = UserAccessLog.objects.filter(
                accessed_at__gte=timezone.now() - timedelta(hours=1)
            ).values('user').distinct().count()
            
            # Permission statistics
            permission_stats = {}
            for role in ['admin', 'team_leader', 'loan_officer', 'secretary', 'auditor']:
                role_users = CustomUser.objects.filter(role=role)
                custom_overrides = 0  # This would need to be calculated based on UserPagePermission
                
                permission_stats[role] = {
                    'user_count': role_users.count(),
                    'custom_overrides': custom_overrides
                }
            
            return {
                'system_stats': {
                    'total_users': total_users,
                    'active_users': active_users,
                    'user_growth': round((new_users_this_month / max(total_users - new_users_this_month, 1)) * 100, 1),
                    'active_sessions': active_sessions,
                    'session_change': 0  # Would need historical data
                },
                'permission_stats': permission_stats
            }
            
        except Exception as e:
            logger.error(f"Error generating admin context: {e}")
            return {}
    
    def get_team_leader_context(self) -> Dict[str, Any]:
        """Get team leader-specific dashboard context"""
        try:
            from .models import CustomUser
            
            # Team statistics
            team_members = CustomUser.objects.filter(
                branch=self.branch,
                role__in=['loan_officer', 'secretary']
            ) if self.branch else CustomUser.objects.none()
            
            total_officers = team_members.filter(role='loan_officer').count()
            
            # Portfolio statistics (would need actual portfolio models)
            portfolio_stats = {
                'total_value': 0,  # Sum of all portfolio values
                'active_loans': 0,  # Count of active loans
                'collection_rate': 0  # Average collection rate
            }
            
            return {
                'team_stats': {
                    'total_officers': total_officers,
                    'total_members': team_members.count(),
                    'avg_performance': 85,  # Would calculate from actual performance data
                    'performance_change': 5.2
                },
                'portfolio_stats': portfolio_stats
            }
            
        except Exception as e:
            logger.error(f"Error generating team leader context: {e}")
            return {}
    
    def get_loan_officer_context(self) -> Dict[str, Any]:
        """Get loan officer-specific dashboard context"""
        try:
            # My portfolio statistics (would need actual models)
            my_portfolio = {
                'total_clients': 0,  # Count of assigned clients
                'portfolio_value': 0,  # Total portfolio value
                'client_growth': 0,  # Growth percentage
                'value_growth': 0   # Value growth percentage
            }
            
            # Pending tasks
            pending_tasks = [
                {
                    'title': 'Loan Applications',
                    'description': 'Pending review',
                    'icon': 'file-alt',
                    'color': 'blue',
                    'count': 5,
                    'priority': 'blue'
                },
                {
                    'title': 'Client Follow-ups',
                    'description': 'Due today',
                    'icon': 'phone',
                    'color': 'green',
                    'count': 3,
                    'priority': 'green'
                },
                {
                    'title': 'Overdue Payments',
                    'description': 'Requires attention',
                    'icon': 'exclamation-triangle',
                    'color': 'red',
                    'count': 2,
                    'priority': 'red'
                }
            ]
            
            return {
                'my_portfolio': my_portfolio,
                'pending_tasks': pending_tasks
            }
            
        except Exception as e:
            logger.error(f"Error generating loan officer context: {e}")
            return {}
    
    def get_secretary_context(self) -> Dict[str, Any]:
        """Get secretary-specific dashboard context"""
        try:
            # Document statistics (would need actual document models)
            document_stats = {
                'pending_review': 8,
                'processed_today': 12,
                'total_documents': 150
            }
            
            # Communication statistics
            communication_stats = {
                'unread_messages': 4,
                'scheduled_calls': 6,
                'followups_due': 3
            }
            
            return {
                'document_stats': document_stats,
                'communication_stats': communication_stats
            }
            
        except Exception as e:
            logger.error(f"Error generating secretary context: {e}")
            return {}
    
    def get_auditor_context(self) -> Dict[str, Any]:
        """Get auditor-specific dashboard context"""
        try:
            # Audit statistics
            audit_stats = {
                'pending_audits': 3,
                'compliance_issues': 1,
                'completed_audits': 15
            }
            
            # Compliance reports
            compliance_reports = [
                {
                    'name': 'Monthly Compliance Report',
                    'last_updated': '2 days ago',
                    'url': '/reports/compliance/monthly/'
                },
                {
                    'name': 'Risk Assessment Report',
                    'last_updated': '1 week ago',
                    'url': '/reports/risk-assessment/'
                },
                {
                    'name': 'Audit Trail Summary',
                    'last_updated': '3 days ago',
                    'url': '/reports/audit-trail/'
                }
            ]
            
            return {
                'audit_stats': audit_stats,
                'compliance_reports': compliance_reports
            }
            
        except Exception as e:
            logger.error(f"Error generating auditor context: {e}")
            return {}
    
    def get_recent_activities(self) -> List[Dict[str, Any]]:
        """Get recent activities relevant to the user"""
        try:
            from utils.models import UserAccessLog
            
            # Get recent activities for this user
            activities = UserAccessLog.objects.filter(
                user=self.user
            ).order_by('-accessed_at')[:5]
            
            activity_list = []
            for activity in activities:
                activity_list.append({
                    'description': f"Accessed {activity.page_accessed}",
                    'timestamp': activity.accessed_at,
                    'icon': 'eye',
                    'color': 'blue'
                })
            
            return activity_list
            
        except Exception as e:
            logger.error(f"Error getting recent activities: {e}")
            return []
    
    def get_notifications(self) -> List[Dict[str, Any]]:
        """Get user notifications"""
        try:
            # This would integrate with an actual notification system
            notifications = [
                {
                    'message': 'New loan application requires review',
                    'created_at': timezone.now() - timedelta(hours=2),
                    'is_read': False,
                    'icon': 'file-alt',
                    'type_color': 'blue'
                },
                {
                    'message': 'Client payment received',
                    'created_at': timezone.now() - timedelta(hours=4),
                    'is_read': True,
                    'icon': 'money-bill-wave',
                    'type_color': 'green'
                }
            ]
            
            return notifications[:5]  # Return latest 5
            
        except Exception as e:
            logger.error(f"Error getting notifications: {e}")
            return []
    
    def get_unread_notifications_count(self) -> int:
        """Get count of unread notifications"""
        try:
            # This would count actual unread notifications
            return len([n for n in self.get_notifications() if not n.get('is_read', True)])
        except Exception as e:
            logger.error(f"Error getting unread notifications count: {e}")
            return 0
    
    def get_contextual_help(self) -> List[Dict[str, str]]:
        """Get contextual help based on user role"""
        help_items = {
            'admin': [
                {
                    'title': 'User Management',
                    'description': 'Add, edit, and manage staff members and their permissions.'
                },
                {
                    'title': 'System Settings',
                    'description': 'Configure system-wide settings and preferences.'
                }
            ],
            'team_leader': [
                {
                    'title': 'Team Performance',
                    'description': 'Monitor your team\'s performance and productivity metrics.'
                },
                {
                    'title': 'Portfolio Management',
                    'description': 'Oversee portfolio performance and risk management.'
                }
            ],
            'loan_officer': [
                {
                    'title': 'Client Management',
                    'description': 'Manage your assigned clients and their loan applications.'
                },
                {
                    'title': 'Loan Processing',
                    'description': 'Process loan applications and manage repayments.'
                }
            ],
            'secretary': [
                {
                    'title': 'Document Management',
                    'description': 'Organize and manage client documents and files.'
                },
                {
                    'title': 'Client Communication',
                    'description': 'Handle client inquiries and schedule appointments.'
                }
            ],
            'auditor': [
                {
                    'title': 'Audit Reports',
                    'description': 'Generate and review audit reports and compliance data.'
                },
                {
                    'title': 'Risk Analysis',
                    'description': 'Analyze system risks and compliance issues.'
                }
            ]
        }
        
        return help_items.get(self.role, [])
    
    def get_fallback_context(self) -> Dict[str, Any]:
        """Get minimal fallback context in case of errors"""
        return {
            'user': self.user,
            'quick_actions': [
                {
                    'title': 'My Profile',
                    'description': 'Update profile',
                    'icon': 'user',
                    'color': 'blue',
                    'url': f'/users/profile/{self.user.id}/',
                    'permission_check': True
                }
            ],
            'recent_activities': [],
            'notifications': [],
            'unread_notifications_count': 0,
            'contextual_help': []
        }
    
    def refresh_dashboard_data(self) -> Dict[str, Any]:
        """
        Refresh dashboard data for AJAX updates
        Returns only the dynamic parts that need updating
        """
        try:
            return {
                'notifications': self.get_notifications(),
                'unread_notifications_count': self.get_unread_notifications_count(),
                'recent_activities': self.get_recent_activities(),
                # Add other dynamic data as needed
            }
        except Exception as e:
            logger.error(f"Error refreshing dashboard data: {e}")
            return {}


def get_dashboard_context(user) -> Dict[str, Any]:
    """
    Convenience function to get dashboard context for a user
    """
    service = RoleBasedDashboardService(user)
    return service.get_dashboard_context()