"""
Django management command to setup roles with permissions for all businesses.

Usage:
    python manage.py setup_roles
    python manage.py setup_roles --business-id=<uuid>
    python manage.py setup_roles --reset  # Delete and recreate all roles
"""

from django.core.management.base import BaseCommand
from django.db import transaction
from apps.authentication.models import Permission, Role, RolePermission
from apps.authentication.services import PermissionService
from apps.business.models import Business
import logging

logger = logging.getLogger(__name__)


class Command(BaseCommand):
    help = 'Setup standard roles with permissions for businesses'

    def add_arguments(self, parser):
        parser.add_argument(
            '--business-id',
            type=str,
            help='Specific business ID to setup roles for',
        )
        parser.add_argument(
            '--reset',
            action='store_true',
            help='Delete existing roles and recreate them',
        )
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Show what would be done without making changes',
        )

    @transaction.atomic
    def handle(self, *args, **options):
        dry_run = options['dry_run']
        business_id = options.get('business_id')
        reset = options.get('reset')

        self.stdout.write(self.style.SUCCESS('Starting role setup...'))

        # Step 1: Ensure all permissions exist
        self.stdout.write('Step 1: Ensuring all permissions exist...')
        permissions_created = PermissionService.ensure_all_permissions_exist()
        self.stdout.write(self.style.SUCCESS(
            f'✓ {permissions_created} new permissions created'
        ))

        # Step 2: Get businesses to process
        if business_id:
            businesses = Business.objects.filter(id=business_id)
            if not businesses.exists():
                self.stdout.write(self.style.ERROR(
                    f'Business with ID {business_id} not found'
                ))
                return
        else:
            businesses = Business.objects.all()

        self.stdout.write(f'Step 2: Processing {businesses.count()} business(es)...')

        # Step 3: Setup roles for each business
        total_roles_created = 0
        for business in businesses:
            roles_created = self._setup_business_roles(business, reset, dry_run)
            total_roles_created += roles_created
            self.stdout.write(self.style.SUCCESS(
                f'✓ Business: {business.name} - {roles_created} roles setup'
            ))

        if dry_run:
            self.stdout.write(self.style.WARNING(
                '✓ DRY RUN COMPLETE - No changes were made'
            ))
        else:
            self.stdout.write(self.style.SUCCESS(
                f'✓ COMPLETE - {total_roles_created} roles setup across {businesses.count()} business(es)'
            ))

    def _setup_business_roles(self, business, reset=False, dry_run=False):
        """Setup all standard roles for a business"""
        roles_created = 0

        # Define standard roles with their permission sets
        role_definitions = {
            'OWNER': {
                'display_name': 'Business Owner',
                'description': 'Full access to all business features and data',
                'permissions': None,  # None = all permissions
            },
            'ADMIN': {
                'display_name': 'Administrator',
                'description': 'Full access to all business features and data',
                'permissions': None,  # None = all permissions
            },
            'MANAGER': {
                'display_name': 'Manager',
                'description': 'Manage inventory, sales, and view reports',
                'permissions': [
                    # Dashboard
                    'dashboard.view',
                    
                    # Inventory - Full access
                    'inventory.view',
                    'inventory.create',
                    'inventory.edit',
                    'inventory.update',
                    'inventory.delete',
                    'inventory.export',
                    'inventory.approve',
                    
                    # Sales - Full access
                    'sales.view',
                    'sales.create',
                    'sales.edit',
                    'sales.update',
                    'sales.delete',
                    'sales.export',
                    'sales.approve',
                    
                    # Invoicing - Full access
                    'invoicing.view',
                    'invoicing.create',
                    'invoicing.edit',
                    'invoicing.update',
                    'invoicing.delete',
                    'invoicing.record_payment',
                    'invoicing.manage_templates',
                    'invoicing.manage_reminders',
                    'invoicing.view_reports',
                    'invoicing.export',
                    'invoicing.approve',
                    
                    # Customers - Full access
                    'customers.view',
                    'customers.create',
                    'customers.edit',
                    'customers.update',
                    'customers.delete',
                    'customers.export',
                    
                    # Transfers
                    'transfers.view',
                    'transfers.create',
                    'transfers.edit',
                    'transfers.update',
                    'transfers.approve',
                    
                    # Warranty
                    'warranty.view',
                    'warranty.create',
                    'warranty.edit',
                    
                    # Reports
                    'reports.view',
                    'reports.create',
                    'reports.export',
                    
                    # Accounting - View only
                    'accounting.view',
                    'accounting.export',
                    
                    # Settings - View only
                    'settings.view',
                ],
            },
            'SALES_AGENT': {
                'display_name': 'Sales Agent',
                'description': 'Process sales, manage customers, view inventory',
                'permissions': [
                    # Dashboard
                    'dashboard.view',
                    
                    # Inventory - View only
                    'inventory.view',
                    
                    # Sales - Create and view
                    'sales.view',
                    'sales.create',
                    
                    # Invoicing - Create and view
                    'invoicing.view',
                    'invoicing.create',
                    'invoicing.record_payment',
                    
                    # Customers - Full access
                    'customers.view',
                    'customers.create',
                    'customers.edit',
                    'customers.update',
                    
                    # Warranty
                    'warranty.view',
                    'warranty.create',
                    
                    # Reports - View only
                    'reports.view',
                ],
            },
            'INVENTORY_CLERK': {
                'display_name': 'Inventory Clerk',
                'description': 'Manage inventory, stock levels, and transfers',
                'permissions': [
                    # Dashboard
                    'dashboard.view',
                    
                    # Inventory - Full access except delete
                    'inventory.view',
                    'inventory.create',
                    'inventory.edit',
                    'inventory.update',
                    'inventory.export',
                    
                    # Transfers
                    'transfers.view',
                    'transfers.create',
                    'transfers.edit',
                    
                    # Reports
                    'reports.view',
                ],
            },
            'ACCOUNTANT': {
                'display_name': 'Accountant',
                'description': 'Manage accounting, view financial reports',
                'permissions': [
                    # Dashboard
                    'dashboard.view',
                    
                    # Accounting - Full access
                    'accounting.view',
                    'accounting.create',
                    'accounting.edit',
                    'accounting.update',
                    'accounting.delete',
                    'accounting.export',
                    'accounting.approve',
                    
                    # Sales - View only
                    'sales.view',
                    'sales.export',
                    
                    # Invoicing - View and payment
                    'invoicing.view',
                    'invoicing.record_payment',
                    'invoicing.view_reports',
                    'invoicing.export',
                    
                    # Customers - View only
                    'customers.view',
                    'customers.export',
                    
                    # Reports
                    'reports.view',
                    'reports.create',
                    'reports.export',
                ],
            },
            'VIEWER': {
                'display_name': 'Viewer',
                'description': 'Read-only access to view business data',
                'permissions': [
                    # Dashboard
                    'dashboard.view',
                    
                    # View-only access
                    'inventory.view',
                    'sales.view',
                    'invoicing.view',
                    'invoicing.view_reports',
                    'customers.view',
                    'transfers.view',
                    'warranty.view',
                    'reports.view',
                    'accounting.view',
                ],
            },
        }

        for role_name, role_config in role_definitions.items():
            if dry_run:
                self.stdout.write(f'  Would create/update role: {role_name}')
                continue

            try:
                # Check if role exists
                role = Role.objects.filter(
                    name=role_name,
                    business=business
                ).first()

                if role and reset:
                    # Delete existing role and recreate
                    role.delete()
                    role = None
                    self.stdout.write(f'  Deleted existing role: {role_name}')

                if role:
                    # Update existing role
                    role.display_name = role_config['display_name']
                    role.description = role_config['description']
                    role.save()
                    self.stdout.write(f'  Updated role: {role_name}')
                else:
                    # Create new role
                    role = Role.objects.create(
                        name=role_name,
                        business=business,
                        display_name=role_config['display_name'],
                        description=role_config['description'],
                        is_system_role=False
                    )
                    self.stdout.write(f'  Created role: {role_name}')
                    roles_created += 1

                # Assign permissions
                if role_config['permissions'] is None:
                    # Assign all permissions
                    assigned_count = PermissionService.assign_all_permissions_to_role(role)
                    self.stdout.write(f'    ✓ Assigned ALL ({assigned_count}) permissions to {role_name}')
                else:
                    # Assign specific permissions
                    assigned_count = self._assign_permissions_to_role(
                        role,
                        role_config['permissions']
                    )
                    self.stdout.write(
                        f'    ✓ Assigned {assigned_count}/{len(role_config["permissions"])} permissions to {role_name}'
                    )

            except Exception as e:
                self.stdout.write(self.style.ERROR(
                    f'  ✗ Error setting up role {role_name}: {str(e)}'
                ))
                logger.exception(f"Error setting up role {role_name}")

        return roles_created

    def _assign_permissions_to_role(self, role, permission_list):
        """Assign specific permissions to a role"""
        # Delete existing permissions
        RolePermission.objects.filter(role=role).delete()

        # Create new permissions
        role_permissions = []
        assigned_count = 0
        
        for perm_string in permission_list:
            try:
                # Validate format
                if perm_string.count('.') != 1:
                    self.stdout.write(self.style.WARNING(
                        f'      ⚠ Invalid permission format: {perm_string} - must be "resource.action"'
                    ))
                    continue
                
                resource, action = perm_string.split('.')
                permission = Permission.objects.get(resource=resource, action=action)
                role_permissions.append(RolePermission(role=role, permission=permission))
                assigned_count += 1
                
            except ValueError as e:
                self.stdout.write(self.style.WARNING(
                    f'      ⚠ Invalid permission format: {perm_string} - {e}'
                ))
            except Permission.DoesNotExist:
                self.stdout.write(self.style.WARNING(
                    f'      ⚠ Permission not found: {perm_string} - ensure it exists in database'
                ))

        if role_permissions:
            RolePermission.objects.bulk_create(role_permissions, ignore_conflicts=True)
        
        return assigned_count