"""
Django Management Command: Create Trial Subscriptions for All Businesses

Usage: 
  python manage.py create_all_trial_subscriptions
  python manage.py create_all_trial_subscriptions --days=30  # Custom trial duration
  python manage.py create_all_trial_subscriptions --skip-existing  # Only create for businesses without subscriptions
"""

from django.core.management.base import BaseCommand
from apps.business.models import Business, BusinessSubscription, SubscriptionPlan
from django.utils import timezone
from datetime import timedelta
from django.db import transaction


class Command(BaseCommand):
    help = 'Create trial subscriptions for all businesses that don\'t have one'

    def add_arguments(self, parser):
        parser.add_argument(
            '--days',
            type=int,
            default=14,
            help='Number of days for trial period (default: 14)'
        )
        parser.add_argument(
            '--skip-existing',
            action='store_true',
            help='Skip businesses that already have subscriptions'
        )
        parser.add_argument(
            '--plan-name',
            type=str,
            default='Trial',
            help='Name of the trial plan to use (default: Trial)'
        )
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Show what would be done without making changes'
        )

    def handle(self, *args, **options):
        trial_days = options['days']
        skip_existing = options['skip_existing']
        plan_name = options['plan_name']
        dry_run = options['dry_run']
        
        self.stdout.write(self.style.SUCCESS('\n' + '='*70))
        self.stdout.write(self.style.SUCCESS('  CREATE TRIAL SUBSCRIPTIONS FOR ALL BUSINESSES'))
        self.stdout.write(self.style.SUCCESS('='*70 + '\n'))
        
        if dry_run:
            self.stdout.write(self.style.WARNING('🔍 DRY RUN MODE - No changes will be made\n'))
        
        # Get or create trial plan
        trial_plan = self._get_or_create_trial_plan(plan_name, dry_run)
        
        if not trial_plan and not dry_run:
            self.stdout.write(self.style.ERROR('\n✗ Failed to get/create trial plan'))
            return
        
        # Get all active businesses
        businesses = Business.objects.filter(is_active=True).prefetch_related(
            'locations',
            'memberships'
        )
        
        total_businesses = businesses.count()
        self.stdout.write(f'Found {total_businesses} active business(es)\n')
        
        created_count = 0
        skipped_count = 0
        updated_count = 0
        error_count = 0
        
        for business in businesses:
            try:
                result = self._process_business(
                    business, 
                    trial_plan, 
                    trial_days, 
                    skip_existing,
                    dry_run
                )
                
                if result == 'created':
                    created_count += 1
                elif result == 'skipped':
                    skipped_count += 1
                elif result == 'updated':
                    updated_count += 1
                    
            except Exception as e:
                error_count += 1
                self.stdout.write(
                    self.style.ERROR(f'  ✗ Error processing {business.name}: {str(e)}')
                )
        
        # Summary
        self.stdout.write(self.style.SUCCESS('\n' + '='*70))
        self.stdout.write(self.style.SUCCESS('  SUMMARY'))
        self.stdout.write(self.style.SUCCESS('='*70 + '\n'))
        
        if dry_run:
            self.stdout.write(self.style.WARNING('  Mode: DRY RUN (no changes made)'))
        else:
            self.stdout.write(self.style.SUCCESS('  Mode: LIVE'))
        
        self.stdout.write(f'\n  Total Businesses: {total_businesses}')
        self.stdout.write(self.style.SUCCESS(f'  ✓ Created: {created_count}'))
        self.stdout.write(self.style.WARNING(f'  ⊘ Skipped: {skipped_count}'))
        
        if updated_count > 0:
            self.stdout.write(self.style.SUCCESS(f'  ↻ Updated: {updated_count}'))
        
        if error_count > 0:
            self.stdout.write(self.style.ERROR(f'  ✗ Errors: {error_count}'))
        
        self.stdout.write('\n' + '='*70 + '\n')
        
        if not dry_run and created_count > 0:
            self.stdout.write(
                self.style.SUCCESS(
                    f'\n✓ Successfully created {created_count} trial subscription(s)!\n'
                )
            )
    
    def _get_or_create_trial_plan(self, plan_name, dry_run):
        """Get or create the trial subscription plan"""
        
        try:
            trial_plan = SubscriptionPlan.objects.get(name=plan_name)
            self.stdout.write(
                self.style.SUCCESS(f'✓ Using existing plan: {trial_plan.name}')
            )
            self.stdout.write(f'  Price: ${trial_plan.monthly_price}')
            self.stdout.write(f'  Max Locations: {trial_plan.max_locations}')
            self.stdout.write(f'  Max Users: {trial_plan.max_users}\n')
            return trial_plan
            
        except SubscriptionPlan.DoesNotExist:
            if dry_run:
                self.stdout.write(
                    self.style.WARNING(f'⊘ Would create new plan: {plan_name}')
                )
                return None
            
            self.stdout.write(f'Creating new plan: {plan_name}...')
            
            trial_plan = SubscriptionPlan.objects.create(
                name=plan_name,
                description=f'Free trial plan with full features',
                monthly_price=0.00,
                annual_price=0.00,
                max_locations=5,
                max_users=10,
                max_inventory_items=1000,
                max_monthly_transactions=500,
                features={
                    'inventory_management': True,
                    'sales_tracking': True,
                    'customer_management': True,
                    'basic_reports': True,
                    'warranty_tracking': True,
                    'multi_location': True,
                    'team_management': True,
                },
                is_active=True,
                is_popular=False,
                display_order=0
            )
            
            self.stdout.write(
                self.style.SUCCESS(f'✓ Created new trial plan: {trial_plan.name}\n')
            )
            return trial_plan
    
    def _process_business(self, business, trial_plan, trial_days, skip_existing, dry_run):
        """Process a single business"""
        
        # Check if subscription already exists
        existing_subscription = BusinessSubscription.objects.filter(
            business=business
        ).first()
        
        if existing_subscription:
            if skip_existing:
                self.stdout.write(
                    f'⊘ {business.name:<40} - Already has subscription ({existing_subscription.status})'
                )
                return 'skipped'
            else:
                # Update existing subscription
                if dry_run:
                    self.stdout.write(
                        f'↻ {business.name:<40} - Would update existing subscription'
                    )
                    return 'skipped'
                else:
                    self._update_subscription(existing_subscription, trial_plan, trial_days)
                    self.stdout.write(
                        self.style.SUCCESS(
                            f'↻ {business.name:<40} - Updated subscription'
                        )
                    )
                    return 'updated'
        
        # Create new subscription
        if dry_run:
            self.stdout.write(
                f'✓ {business.name:<40} - Would create trial subscription'
            )
            return 'skipped'
        
        with transaction.atomic():
            # Count current usage
            locations_count = business.locations.filter(is_active=True).count()
            users_count = business.memberships.filter(status='ACTIVE').count()
            
            # Create subscription
            subscription = BusinessSubscription.objects.create(
                business=business,
                plan=trial_plan,
                status='TRIAL',
                billing_cycle='MONTHLY',
                start_date=timezone.now().date(),
                end_date=timezone.now().date() + timedelta(days=trial_days),
                trial_end_date=timezone.now().date() + timedelta(days=trial_days),
                next_billing_date=timezone.now().date() + timedelta(days=trial_days),
                amount=0.00,
                auto_renew=False,
                current_locations_count=locations_count,
                current_users_count=users_count,
                current_inventory_count=0,
                monthly_transaction_count=0
            )
            
            # Update business status if needed
            if business.status != 'TRIAL':
                business.status = 'TRIAL'
                business.save(update_fields=['status'])
            
            self.stdout.write(
                self.style.SUCCESS(
                    f'✓ {business.name:<40} - Created trial ({trial_days} days)'
                )
            )
            
            return 'created'
    
    def _update_subscription(self, subscription, trial_plan, trial_days):
        """Update an existing subscription"""
        
        subscription.plan = trial_plan
        subscription.status = 'TRIAL'
        subscription.trial_end_date = timezone.now().date() + timedelta(days=trial_days)
        subscription.end_date = timezone.now().date() + timedelta(days=trial_days)
        subscription.next_billing_date = timezone.now().date() + timedelta(days=trial_days)
        subscription.amount = 0.00
        subscription.auto_renew = False
        
        # Update usage counts
        subscription.current_locations_count = subscription.business.locations.filter(
            is_active=True
        ).count()
        subscription.current_users_count = subscription.business.memberships.filter(
            status='ACTIVE'
        ).count()
        
        subscription.save()
        
        # Update business status
        if subscription.business.status != 'TRIAL':
            subscription.business.status = 'TRIAL'
            subscription.business.save(update_fields=['status'])