"""
Management command to fix permissions for existing users.

Usage:
    python manage.py fix_user_permissions
    python manage.py fix_user_permissions --email user@example.com
    python manage.py fix_user_permissions --all-owners
"""
from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from django.db import transaction
from apps.authentication.models import Role, Permission, RolePermission
from apps.business.models import Business, BusinessMembership

User = get_user_model()


class Command(BaseCommand):
    help = 'Fix permissions for users - ensure all owners have full permissions'

    def add_arguments(self, parser):
        parser.add_argument(
            '--email',
            type=str,
            help='Fix permissions for specific user email',
        )
        parser.add_argument(
            '--all-owners',
            action='store_true',
            help='Fix permissions for all business owners',
        )
        parser.add_argument(
            '--all-users',
            action='store_true',
            help='Fix permissions for all users',
        )

    def handle(self, *args, **options):
        self.stdout.write(self.style.SUCCESS('Starting permission fix...'))
        
        # Step 1: Ensure all permissions exist
        self.stdout.write('Step 1: Creating all necessary permissions...')
        all_permissions = self._create_all_permissions()
        self.stdout.write(self.style.SUCCESS(
            f'✓ {all_permissions.count()} permissions verified'
        ))
        
        # Step 2: Fix users based on options
        if options['email']:
            self._fix_user_by_email(options['email'], all_permissions)
        elif options['all_owners']:
            self._fix_all_owners(all_permissions)
        elif options['all_users']:
            self._fix_all_users(all_permissions)
        else:
            self.stdout.write(self.style.WARNING(
                'No target specified. Use --email, --all-owners, or --all-users'
            ))
            return
        
        self.stdout.write(self.style.SUCCESS('\n✓ Permission fix complete!'))

    def _create_all_permissions(self):
        """Create all necessary permissions"""
        permission_definitions = [
            # Dashboard
            ('dashboard', 'view', 'View dashboard and analytics'),
            ('dashboard', 'create', 'Create dashboard widgets'),
            ('dashboard', 'update', 'Update dashboard settings'),
            
            # Inventory
            ('inventory', 'view', 'View inventory items'),
            ('inventory', 'create', 'Create new inventory items'),
            ('inventory', 'update', 'Update inventory items'),
            ('inventory', 'delete', 'Delete inventory items'),
            ('inventory', 'export', 'Export inventory data'),
            ('inventory', 'approve', 'Approve inventory changes'),
            
            # Sales
            ('sales', 'view', 'View sales records'),
            ('sales', 'create', 'Create new sales'),
            ('sales', 'update', 'Update sales records'),
            ('sales', 'delete', 'Delete sales records'),
            ('sales', 'export', 'Export sales data'),
            ('sales', 'approve', 'Approve sales transactions'),
            
            # Customers
            ('customers', 'view', 'View customer information'),
            ('customers', 'create', 'Create new customers'),
            ('customers', 'update', 'Update customer information'),
            ('customers', 'delete', 'Delete customers'),
            ('customers', 'export', 'Export customer data'),
            
            # Transfers
            ('transfers', 'view', 'View transfer records'),
            ('transfers', 'create', 'Create new transfers'),
            ('transfers', 'update', 'Update transfers'),
            ('transfers', 'delete', 'Delete transfers'),
            ('transfers', 'approve', 'Approve transfers'),
            
            # Warranty
            ('warranty', 'view', 'View warranty information'),
            ('warranty', 'create', 'Create warranty records'),
            ('warranty', 'update', 'Update warranty information'),
            ('warranty', 'delete', 'Delete warranty records'),
            
            # Reports
            ('reports', 'view', 'View reports'),
            ('reports', 'create', 'Create custom reports'),
            ('reports', 'export', 'Export reports'),
            
            # Accounting
            ('accounting', 'view', 'View accounting records'),
            ('accounting', 'create', 'Create accounting entries'),
            ('accounting', 'update', 'Update accounting records'),
            ('accounting', 'delete', 'Delete accounting entries'),
            ('accounting', 'export', 'Export accounting data'),
            ('accounting', 'approve', 'Approve accounting transactions'),
            
            # Users
            ('users', 'view', 'View user accounts'),
            ('users', 'create', 'Create new users'),
            ('users', 'update', 'Update user accounts'),
            ('users', 'delete', 'Delete users'),
            
            # Settings
            ('settings', 'view', 'View system settings'),
            ('settings', 'update', 'Update system settings'),
        ]
        
        created_count = 0
        for resource, action, description in permission_definitions:
            _, created = Permission.objects.get_or_create(
                resource=resource,
                action=action,
                defaults={'description': description}
            )
            if created:
                created_count += 1
        
        if created_count > 0:
            self.stdout.write(f'  Created {created_count} new permissions')
        
        return Permission.objects.all()

    def _fix_user_by_email(self, email, all_permissions):
        """Fix permissions for specific user"""
        try:
            user = User.objects.get(email=email)
            self.stdout.write(f'\nFixing permissions for: {user.email}')
            
            memberships = BusinessMembership.objects.filter(
                user=user,
                status='ACTIVE'
            ).select_related('business', 'role')
            
            for membership in memberships:
                self._fix_role_permissions(
                    membership.role,
                    membership.business,
                    all_permissions
                )
            
            self.stdout.write(self.style.SUCCESS(
                f'✓ Fixed permissions for {user.email}'
            ))
            
        except User.DoesNotExist:
            self.stdout.write(self.style.ERROR(
                f'✗ User not found: {email}'
            ))

    def _fix_all_owners(self, all_permissions):
        """Fix permissions for all business owners"""
        self.stdout.write('\nFixing permissions for all business owners...')
        
        # Get all OWNER roles
        owner_roles = Role.objects.filter(name='OWNER')
        
        fixed_count = 0
        for role in owner_roles:
            self._fix_role_permissions(role, role.business, all_permissions)
            fixed_count += 1
        
        self.stdout.write(self.style.SUCCESS(
            f'✓ Fixed {fixed_count} owner roles'
        ))

    def _fix_all_users(self, all_permissions):
        """Fix permissions for all users"""
        self.stdout.write('\nFixing permissions for all users...')
        
        memberships = BusinessMembership.objects.filter(
            status='ACTIVE'
        ).select_related('user', 'business', 'role')
        
        fixed_count = 0
        for membership in memberships:
            self._fix_role_permissions(
                membership.role,
                membership.business,
                all_permissions
            )
            fixed_count += 1
        
        self.stdout.write(self.style.SUCCESS(
            f'✓ Fixed {fixed_count} user roles'
        ))

    @transaction.atomic
    def _fix_role_permissions(self, role, business, all_permissions):
        """Assign all permissions to a role"""
        # Delete existing permissions
        deleted_count = RolePermission.objects.filter(role=role).count()
        RolePermission.objects.filter(role=role).delete()
        
        # Create new permissions
        role_permissions = []
        for permission in all_permissions:
            role_permissions.append(
                RolePermission(role=role, permission=permission)
            )
        
        RolePermission.objects.bulk_create(role_permissions, ignore_conflicts=True)
        
        # Verify
        new_count = RolePermission.objects.filter(role=role).count()
        
        self.stdout.write(
            f'  {role.display_name} ({business.name}): '
            f'{deleted_count} → {new_count} permissions'
        )