"""
Django management command to sync all permissions and assign to OWNER/ADMIN roles.

Usage:
    python manage.py sync_permissions
    python manage.py sync_permissions --business-id=<uuid>
    python manage.py sync_permissions --all-businesses
"""

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

logger = logging.getLogger(__name__)


class Command(BaseCommand):
    help = 'Sync permissions and assign to OWNER/ADMIN roles'

    def add_arguments(self, parser):
        parser.add_argument(
            '--business-id',
            type=str,
            help='Specific business ID to sync permissions for',
        )
        parser.add_argument(
            '--all-businesses',
            action='store_true',
            help='Sync permissions for all businesses',
        )
        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')
        all_businesses = options.get('all_businesses')

        self.stdout.write(self.style.SUCCESS('Starting permission sync...'))

        # Step 1: Ensure all permissions exist
        self.stdout.write('Step 1: Creating/updating permissions...')
        permissions_created = self._ensure_permissions_exist(dry_run)
        self.stdout.write(self.style.SUCCESS(
            f'✓ {permissions_created} permissions ensured'
        ))

        # Step 2: Get businesses to update
        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
        elif all_businesses:
            businesses = Business.objects.all()
        else:
            self.stdout.write(self.style.WARNING(
                'No business specified. Use --business-id or --all-businesses'
            ))
            return

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

        # Step 3: Assign permissions to OWNER and ADMIN roles
        total_updated = 0
        for business in businesses:
            updated = self._sync_business_permissions(business, dry_run)
            total_updated += updated
            self.stdout.write(self.style.SUCCESS(
                f'✓ Business: {business.name} - {updated} roles updated'
            ))

        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_updated} roles updated across {businesses.count()} business(es)'
            ))

    def _ensure_permissions_exist(self, dry_run=False):
        """Ensure all permissions exist in database"""
        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', 'edit', 'Edit inventory items'),
            ('inventory', 'update', 'Update inventory items'),
            ('inventory', 'delete', 'Delete inventory items'),
            ('inventory', 'export', 'Export inventory data'),
            ('inventory', 'import', 'Import inventory data'),
            ('inventory', 'approve', 'Approve inventory changes'),
            ('inventory', 'restock', 'Restock inventory'),
            ('inventory', 'transfer', 'Transfer inventory between locations'),
            ('inventory', 'manage_categories', 'Manage categories'),
            ('inventory', 'manage_brands', 'Manage brands'),
            ('inventory', 'adjust_stock', 'Adjust stock levels'),
            ('inventory', 'cycle_count', 'Perform cycle counts'),
            ('inventory', 'view_reports', 'View inventory reports'),
            
            # Sales
            ('sales', 'view', 'View sales records'),
            ('sales', 'create', 'Create new sales'),
            ('sales', 'edit', 'Edit sales records'),
            ('sales', 'update', 'Update sales records'),
            ('sales', 'delete', 'Delete sales records'),
            ('sales', 'export', 'Export sales data'),
            ('sales', 'approve', 'Approve sales transactions'),
            ('sales', 'return', 'Process returns'),
            ('sales', 'cancel', 'Cancel sales'),
            ('sales', 'email', 'Email sales receipts'),
            ('sales', 'payment', 'Process payments'),
            ('sales', 'discount', 'Apply discounts'),
            ('sales', 'refund', 'Process refunds'),
            
            # Invoicing
            ('invoicing', 'view', 'View invoices and quotes'),
            ('invoicing', 'create', 'Create invoices and quotes'),
            ('invoicing', 'edit', 'Edit invoices and quotes'),
            ('invoicing', 'update', 'Update invoices and quotes'),
            ('invoicing', 'delete', 'Delete invoices and quotes'),
            ('invoicing', 'record_payment', 'Record payments on invoices'),
            ('invoicing', 'manage_templates', 'Manage invoice templates'),
            ('invoicing', 'manage_reminders', 'Manage payment reminders'),
            ('invoicing', 'view_reports', 'View invoicing reports'),
            ('invoicing', 'export', 'Export invoicing data'),
            ('invoicing', 'approve', 'Approve invoices'),
            
            # Customers
            ('customers', 'view', 'View customer information'),
            ('customers', 'create', 'Create new customers'),
            ('customers', 'edit', 'Edit customer information'),
            ('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', 'edit', 'Edit 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', 'edit', 'Edit warranty information'),
            ('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', 'edit', 'Edit accounting records'),
            ('accounting', 'update', 'Update accounting records'),
            ('accounting', 'delete', 'Delete accounting entries'),
            ('accounting', 'export', 'Export accounting data'),
            ('accounting', 'approve', 'Approve accounting transactions'),
            ('accounting.transactions', 'view', 'View transactions'),
            ('accounting.transactions', 'create', 'Create transactions'),
            ('accounting.commissions', 'view', 'View commissions'),
            ('accounting.commissions', 'create', 'Create commissions'),
            ('accounting.credit', 'view', 'View credit records'),
            ('accounting.reports', 'view', 'View accounting reports'),
            
            # Users
            ('users', 'view', 'View user accounts'),
            ('users', 'create', 'Create new users'),
            ('users', 'edit', 'Edit user accounts'),
            ('users', 'update', 'Update user accounts'),
            ('users', 'delete', 'Delete users'),
            
            # Settings
            ('settings', 'view', 'View system settings'),
            ('settings', 'edit', 'Edit system settings'),
            ('settings', 'update', 'Update system settings'),
        ]
        
        created_count = 0
        for resource, action, description in permission_definitions:
            if not dry_run:
                perm, created = Permission.objects.get_or_create(
                    resource=resource,
                    action=action,
                    defaults={'description': description}
                )
                if created:
                    created_count += 1
            else:
                exists = Permission.objects.filter(
                    resource=resource, action=action
                ).exists()
                if not exists:
                    created_count += 1
                    self.stdout.write(f'  Would create: {resource}.{action}')
        
        return created_count

    def _sync_business_permissions(self, business, dry_run=False):
        """Sync permissions for OWNER and ADMIN roles in a business"""
        updated_count = 0
        
        # Get all permissions
        all_permissions = Permission.objects.all()
        
        # Update OWNER role
        owner_role, created = Role.objects.get_or_create(
            name='OWNER',
            business=business,
            defaults={
                'display_name': 'Business Owner',
                'description': 'Full access to all business features',
            }
        )
        
        if not dry_run:
            # Clear existing permissions
            RolePermission.objects.filter(role=owner_role).delete()
            
            # Assign all permissions
            role_permissions = [
                RolePermission(role=owner_role, permission=perm)
                for perm in all_permissions
            ]
            RolePermission.objects.bulk_create(role_permissions, ignore_conflicts=True)
            
            perm_count = RolePermission.objects.filter(role=owner_role).count()
            self.stdout.write(f'    OWNER: {perm_count} permissions assigned')
            updated_count += 1
        else:
            self.stdout.write(f'    Would assign {all_permissions.count()} permissions to OWNER')
        
        # Update ADMIN role (same permissions as OWNER)
        admin_role, created = Role.objects.get_or_create(
            name='ADMIN',
            business=business,
            defaults={
                'display_name': 'Administrator',
                'description': 'Full access to all business features',
            }
        )
        
        if not dry_run:
            # Clear existing permissions
            RolePermission.objects.filter(role=admin_role).delete()
            
            # Assign all permissions
            role_permissions = [
                RolePermission(role=admin_role, permission=perm)
                for perm in all_permissions
            ]
            RolePermission.objects.bulk_create(role_permissions, ignore_conflicts=True)
            
            perm_count = RolePermission.objects.filter(role=admin_role).count()
            self.stdout.write(f'    ADMIN: {perm_count} permissions assigned')
            updated_count += 1
        else:
            self.stdout.write(f'    Would assign {all_permissions.count()} permissions to ADMIN')
        
        return updated_count

