"""
Permission-Aware Navigation Service
Generates dynamic navigation menus based on user roles and granular permissions
"""
from typing import Dict, List, Any, Optional
from django.urls import reverse, NoReverseMatch
from django.utils.html import format_html
from django.utils.safestring import mark_safe
import logging

logger = logging.getLogger(__name__)


class NavigationItem:
    """
    Represents a single navigation item with permission checking
    """
    
    def __init__(self, 
                 title: str,
                 url_name: str = None,
                 url: str = None,
                 icon: str = None,
                 permission_required: str = None,
                 role_required: List[str] = None,
                 children: List['NavigationItem'] = None,
                 badge_count: int = None,
                 badge_color: str = 'red',
                 description: str = None,
                 category: str = None,
                 order: int = 0,
                 is_divider: bool = False,
                 tooltip: str = None):
        
        self.title = title
        self.url_name = url_name
        self.url = url
        self.icon = icon
        self.permission_required = permission_required
        self.role_required = role_required or []
        self.children = children or []
        self.badge_count = badge_count
        self.badge_color = badge_color
        self.description = description
        self.category = category
        self.order = order
        self.is_divider = is_divider
        self.tooltip = tooltip
    
    def is_accessible(self, user) -> bool:
        """Check if this navigation item is accessible to the user"""
        try:
            # Check role requirements
            if self.role_required and user.role not in self.role_required:
                return False
            
            # Check permission requirements
            if self.permission_required:
                if hasattr(user, 'has_page_permission'):
                    # Parse permission string (format: "page_action")
                    if '_' in self.permission_required:
                        page, action = self.permission_required.split('_', 1)
                        return user.has_page_permission(page, action)
                    else:
                        # Fallback to old permission system
                        return user.has_perm(self.permission_required)
                else:
                    return user.has_perm(self.permission_required)
            
            return True
            
        except Exception as e:
            logger.error(f"Error checking navigation accessibility: {e}")
            return False
    
    def get_url(self) -> str:
        """Get the URL for this navigation item"""
        if self.url:
            return self.url
        elif self.url_name:
            try:
                return reverse(self.url_name)
            except NoReverseMatch:
                logger.warning(f"Could not reverse URL name: {self.url_name}")
                return "#"
        return "#"
    
    def get_accessible_children(self, user) -> List['NavigationItem']:
        """Get children that are accessible to the user"""
        return [child for child in self.children if child.is_accessible(user)]


class PermissionAwareNavigationService:
    """
    Service for generating permission-aware navigation menus
    """
    
    def __init__(self):
        self.navigation_items = self._define_navigation_structure()
    
    def _define_navigation_structure(self) -> List[NavigationItem]:
        """
        Define the complete navigation structure with permissions
        """
        return [
            # Dashboard
            NavigationItem(
                title="Dashboard",
                url_name="users:role_based_dashboard",
                icon="tachometer-alt",
                permission_required="dashboard_view",
                category="main",
                order=1,
                tooltip="View your personalized dashboard"
            ),
            
            # Clients Section
            NavigationItem(
                title="Clients",
                url_name="users:client_list",
                icon="users",
                permission_required="clients_view_list",
                category="main",
                order=2,
                tooltip="Manage client information and records",
                children=[
                    NavigationItem(
                        title="All Clients",
                        url_name="users:client_list",
                        icon="list",
                        permission_required="clients_view_list"
                    ),
                    NavigationItem(
                        title="Add New Client",
                        url_name="users:client_create",
                        icon="user-plus",
                        permission_required="clients_create_new"
                    ),
                    NavigationItem(
                        title="Pending Approvals",
                        url_name="users:pending_clients",
                        icon="clock",
                        permission_required="clients_view_pending"
                    ),
                    NavigationItem(
                        title="Rejected Clients",
                        url_name="users:rejected_clients",
                        icon="user-times",
                        permission_required="clients_view_rejected"
                    ),
                ]
            ),
            
            # Loans Section
            NavigationItem(
                title="Loans",
                url_name="loans:loans",
                icon="money-bill-wave",
                permission_required="loans_view_applications",
                category="main",
                order=3,
                tooltip="Manage loan applications and processing",
                children=[
                    NavigationItem(
                        title="All Loans",
                        url_name="loans:loans",
                        icon="list",
                        permission_required="loans_view_applications"
                    ),
                    NavigationItem(
                        title="New Application",
                        url_name="loans:create",
                        icon="plus-circle",
                        permission_required="loans_create_application"
                    ),
                    NavigationItem(
                        title="Pending Applications",
                        url_name="loans:pending_applications",
                        icon="hourglass-half",
                        permission_required="loans_view_pending"
                    ),
                    NavigationItem(
                        title="Active Loans",
                        url_name="loans:active_loans",
                        icon="check-circle",
                        permission_required="loans_view_active"
                    ),
                    NavigationItem(
                        title="Defaulted Loans",
                        url_name="loans:defaulted_loans",
                        icon="exclamation-triangle",
                        permission_required="loans_view_defaulted"
                    ),
                ]
            ),
            
            # Repayments Section
            NavigationItem(
                title="Repayments",
                url_name="loans:repayments",
                icon="hand-holding-usd",
                permission_required="repayments_view_list",
                category="main",
                order=4,
                tooltip="Manage loan repayments and collections",
                children=[
                    NavigationItem(
                        title="All Repayments",
                        url_name="loans:repayments",
                        icon="list",
                        permission_required="repayments_view_list"
                    ),
                    NavigationItem(
                        title="Record Payment",
                        url_name="payments:record_payment",
                        icon="plus",
                        permission_required="repayments_record_payment"
                    ),
                    NavigationItem(
                        title="Payment History",
                        url_name="payments:payment_history",
                        icon="history",
                        permission_required="repayments_view_history"
                    ),
                    NavigationItem(
                        title="M-Pesa Dashboard",
                        url_name="payments:dashboard",
                        icon="mobile-alt",
                        role_required=["admin", "team_leader"]
                    ),
                    NavigationItem(
                        title="SasaPay & SMS",
                        url_name="payments:sasapay_dashboard",
                        icon="credit-card",
                        role_required=["admin", "team_leader"]
                    ),
                    NavigationItem(
                        title="SMS Logs",
                        url_name="payments:sms_logs",
                        icon="sms",
                        role_required=["admin", "team_leader"]
                    ),
                    NavigationItem(
                        title="Developer Payments",
                        url_name="payments:developer_payments",
                        icon="code",
                        role_required=["admin"],
                    ),
                ]
            ),
            
            # Portfolio Section (for loan officers and team leaders)
            NavigationItem(
                title="Portfolio",
                url_name="users:portfolio_dashboard",
                icon="briefcase",
                permission_required="portfolio_view_dashboard",
                role_required=["admin", "team_leader", "loan_officer"],
                category="main",
                order=5,
                tooltip="View portfolio analytics and performance",
                children=[
                    NavigationItem(
                        title="Portfolio Dashboard",
                        url_name="users:portfolio_dashboard",
                        icon="tachometer-alt",
                        permission_required="portfolio_view_dashboard"
                    ),
                    NavigationItem(
                        title="Performance Analytics",
                        url_name="users:portfolio_analytics",
                        icon="chart-line",
                        permission_required="portfolio_view_analytics"
                    ),
                    NavigationItem(
                        title="Client Performance",
                        url_name="users:client_performance",
                        icon="user-chart",
                        permission_required="portfolio_view_client_performance"
                    ),
                ]
            ),
            
            # Expenses Section
            NavigationItem(
                title="Expenses",
                url_name="expenses:expenses_list",
                icon="receipt",
                role_required=["admin", "team_leader", "loan_officer", "secretary"],
                category="main",
                order=5.5,
                tooltip="Manage business expenses and approvals",
                children=[
                    NavigationItem(
                        title="All Expenses",
                        url_name="expenses:expenses_list",
                        icon="list",
                        role_required=["admin", "team_leader", "loan_officer", "secretary"]
                    ),
                    NavigationItem(
                        title="Add Expense",
                        url_name="expenses:add_expense",
                        icon="plus-circle",
                        role_required=["admin", "team_leader", "loan_officer", "secretary"]
                    ),
                    NavigationItem(
                        title="Pending Approvals",
                        url_name="expenses:pending_approvals",
                        icon="check-circle",
                        role_required=["admin", "team_leader"]
                    ),
                    NavigationItem(
                        title="Analytics",
                        url_name="expenses:expense_analytics",
                        icon="chart-bar",
                        role_required=["admin", "team_leader"]
                    ),
                ]
            ),
            
            # Reports Section
            NavigationItem(
                title="Reports & Analytics",
                icon="chart-bar",
                permission_required="reports_view_dashboard",
                category="reports",
                order=6,
                tooltip="Generate reports and view analytics",
                is_divider=True,
                children=[
                    NavigationItem(
                        title="Reports Dashboard",
                        url_name="reports:reports_dashboard",
                        icon="tachometer-alt",
                        permission_required="reports_view_dashboard"
                    ),
                    NavigationItem(
                        title="Loans Due Report",
                        url_name="reports:loans_due_report",
                        icon="calendar-day",
                        permission_required="reports_view_loans_due"
                    ),
                    NavigationItem(
                        title="Delinquent Loans",
                        url_name="reports:delinquent_loans_report",
                        icon="exclamation-triangle",
                        permission_required="reports_view_delinquent"
                    ),
                    NavigationItem(
                        title="Processing Fees",
                        url_name="reports:processing_fees_report",
                        icon="coins",
                        permission_required="reports_view_processing_fees"
                    ),
                    NavigationItem(
                        title="Interest Income",
                        url_name="reports:interest_income_report",
                        icon="percentage",
                        permission_required="reports_view_interest_income"
                    ),
                    NavigationItem(
                        title="Customer Requests",
                        url_name="reports:customer_requests_list",
                        icon="headset",
                        permission_required="reports_view_customer_requests"
                    ),
                ]
            ),
            
            # Documents Section
            NavigationItem(
                title="Documents",
                url_name="utils:documents",
                icon="file-alt",
                permission_required="documents_view_list",
                category="main",
                order=7,
                tooltip="Manage documents and files",
                children=[
                    NavigationItem(
                        title="All Documents",
                        url_name="utils:documents",
                        icon="folder",
                        permission_required="documents_view_list"
                    ),
                    NavigationItem(
                        title="Customer Documents",
                        url_name="utils:all_customer_documents",
                        icon="users-cog",
                        permission_required="documents_view_customer_documents"
                    ),
                    NavigationItem(
                        title="Upload Document",
                        url_name="utils:upload_document",
                        icon="upload",
                        permission_required="documents_upload"
                    ),
                ]
            ),
            
            # Payment Receipts
            NavigationItem(
                title="Payment Receipts",
                url_name="utils:receipts_list",
                icon="receipt",
                permission_required="receipts_view_list",
                category="main",
                order=8,
                tooltip="View and manage payment receipts"
            ),
            
            # Notifications
            NavigationItem(
                title="Notifications",
                url_name="utils:notifications",
                icon="bell",
                permission_required="notifications_view",
                category="main",
                order=9,
                tooltip="View system notifications and alerts"
            ),
            
            # Settings Section
            NavigationItem(
                title="Settings",
                icon="cog",
                category="settings",
                order=10,
                tooltip="System configuration and settings",
                is_divider=True,
                children=[
                    # Branch Management hidden — branches not in use currently
                    # NavigationItem(
                    #     title="Branch Management",
                    #     url_name="users:branch_list",
                    #     icon="building",
                    #     permission_required="settings_manage_branches"
                    # ),
                    NavigationItem(
                        title="System Settings",
                        url_name="utils:settings",
                        icon="cogs",
                        permission_required="settings_manage_system"
                    ),
                    NavigationItem(
                        title="User Preferences",
                        url_name="users:user_preferences",
                        icon="user-cog",
                        permission_required=None  # Always available
                    ),
                ]
            ),
            
            # Staff Management (Admin only)
            NavigationItem(
                title="Staff Management",
                url_name="users:admin_list",
                icon="users-cog",
                permission_required="users_manage_staff",
                role_required=["admin"],
                category="admin",
                order=11,
                tooltip="Manage staff members and permissions",
                children=[
                    NavigationItem(
                        title="All Staff",
                        url_name="users:admin_list",
                        icon="users",
                        permission_required="users_view_staff"
                    ),
                    NavigationItem(
                        title="Add Staff Member",
                        url_name="users:admin_create",
                        icon="user-plus",
                        permission_required="users_create_staff"
                    ),
                    NavigationItem(
                        title="Permission Templates",
                        url_name="users:permission_templates",
                        icon="shield-alt",
                        permission_required="users_manage_permissions"
                    ),
                    NavigationItem(
                        title="Audit Logs",
                        url_name="users:audit_logs",
                        icon="history",
                        permission_required="users_view_audit_logs"
                    ),
                ]
            ),
        ]
    
    def get_navigation_for_user(self, user, current_url: str = None) -> Dict[str, List[NavigationItem]]:
        """
        Get navigation items organized by category for a specific user
        """
        try:
            accessible_items = []
            
            for item in self.navigation_items:
                if item.is_accessible(user):
                    # Filter children based on permissions
                    accessible_children = item.get_accessible_children(user)
                    
                    # Only include parent if it has accessible children or is directly accessible
                    if accessible_children or not item.children:
                        # Create a copy with filtered children
                        filtered_item = NavigationItem(
                            title=item.title,
                            url_name=item.url_name,
                            url=item.url,
                            icon=item.icon,
                            permission_required=item.permission_required,
                            role_required=item.role_required,
                            children=accessible_children,
                            badge_count=item.badge_count,
                            badge_color=item.badge_color,
                            description=item.description,
                            category=item.category,
                            order=item.order,
                            is_divider=item.is_divider,
                            tooltip=item.tooltip
                        )
                        accessible_items.append(filtered_item)
            
            # Group by category and sort
            categorized_nav = {}
            for item in sorted(accessible_items, key=lambda x: x.order):
                category = item.category or 'main'
                if category not in categorized_nav:
                    categorized_nav[category] = []
                categorized_nav[category].append(item)
            
            return categorized_nav
            
        except Exception as e:
            logger.error(f"Error generating navigation for user {user.id}: {e}")
            return {}
    
    def get_breadcrumbs(self, user, current_url: str) -> List[Dict[str, str]]:
        """
        Generate breadcrumb navigation based on current URL
        """
        try:
            breadcrumbs = [{'title': 'Home', 'url': reverse('users:role_based_dashboard')}]
            
            # Find matching navigation item
            for item in self.navigation_items:
                if item.is_accessible(user):
                    item_url = item.get_url()
                    if current_url == item_url:
                        breadcrumbs.append({'title': item.title, 'url': item_url})
                        break
                    
                    # Check children
                    for child in item.children:
                        if child.is_accessible(user):
                            child_url = child.get_url()
                            if current_url == child_url:
                                breadcrumbs.append({'title': item.title, 'url': item_url})
                                breadcrumbs.append({'title': child.title, 'url': child_url})
                                break
            
            return breadcrumbs
            
        except Exception as e:
            logger.error(f"Error generating breadcrumbs: {e}")
            return [{'title': 'Home', 'url': '/'}]
    
    def get_quick_actions(self, user) -> List[NavigationItem]:
        """
        Get quick action items for the user based on their role and permissions
        """
        try:
            quick_actions = []
            
            # Role-specific quick actions
            role_actions = {
                'admin': [
                    NavigationItem(
                        title="Add Staff",
                        url_name="users:admin_create",
                        icon="user-plus",
                        permission_required="users_create_staff"
                    ),
                    NavigationItem(
                        title="System Settings",
                        url_name="utils:settings",
                        icon="cogs",
                        permission_required="settings_manage_system"
                    ),
                ],
                'team_leader': [
                    NavigationItem(
                        title="Team Performance",
                        url_name="users:team_performance",
                        icon="chart-line",
                        permission_required="team_view_performance"
                    ),
                    NavigationItem(
                        title="Approve Loans",
                        url_name="loans:pending_approvals",
                        icon="check-circle",
                        permission_required="loans_approve_loans"
                    ),
                ],
                'loan_officer': [
                    NavigationItem(
                        title="New Loan",
                        url_name="loans:create",
                        icon="plus-circle",
                        permission_required="loans_create_application"
                    ),
                    NavigationItem(
                        title="Record Payment",
                        url_name="payments:record_payment",
                        icon="money-bill-wave",
                        permission_required="repayments_record_payment"
                    ),
                ],
                'secretary': [
                    NavigationItem(
                        title="Add Client",
                        url_name="users:client_create",
                        icon="user-plus",
                        permission_required="clients_create_new"
                    ),
                    NavigationItem(
                        title="Upload Document",
                        url_name="utils:upload_document",
                        icon="upload",
                        permission_required="documents_upload"
                    ),
                ],
                'auditor': [
                    NavigationItem(
                        title="Audit Dashboard",
                        url_name="reports:audit_dashboard",
                        icon="search",
                        permission_required="audit_view_dashboard"
                    ),
                    NavigationItem(
                        title="Export Data",
                        url_name="reports:export_data",
                        icon="download",
                        permission_required="reports_export_data"
                    ),
                ]
            }
            
            if user.role in role_actions:
                for action in role_actions[user.role]:
                    if action.is_accessible(user):
                        quick_actions.append(action)
            
            return quick_actions
            
        except Exception as e:
            logger.error(f"Error getting quick actions for user {user.id}: {e}")
            return []


# Global navigation service instance
navigation_service = PermissionAwareNavigationService()