"""
Django Management Command: Check All Subscriptions
Save as: apps/business/management/commands/check_all_subscriptions.py

Usage: 
  python manage.py check_all_subscriptions
  python manage.py check_all_subscriptions --status=TRIAL
  python manage.py check_all_subscriptions --expiring-soon  # Show subscriptions expiring in 7 days
"""

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


class Command(BaseCommand):
    help = 'Check subscription status for all businesses'

    def add_arguments(self, parser):
        parser.add_argument(
            '--status',
            type=str,
            help='Filter by subscription status (TRIAL, ACTIVE, EXPIRED, etc.)'
        )
        parser.add_argument(
            '--expiring-soon',
            action='store_true',
            help='Show only subscriptions expiring within 7 days'
        )
        parser.add_argument(
            '--no-subscription',
            action='store_true',
            help='Show only businesses without subscriptions'
        )
        parser.add_argument(
            '--export',
            type=str,
            help='Export results to CSV file'
        )

    def handle(self, *args, **options):
        status_filter = options.get('status')
        expiring_soon = options.get('expiring_soon')
        no_subscription = options.get('no_subscription')
        export_file = options.get('export')
        
        self.stdout.write(self.style.SUCCESS('\n' + '='*80))
        self.stdout.write(self.style.SUCCESS('  SUBSCRIPTION STATUS REPORT'))
        self.stdout.write(self.style.SUCCESS('='*80 + '\n'))
        
        # Get all active businesses
        businesses = Business.objects.filter(is_active=True).order_by('name')
        total_businesses = businesses.count()
        
        self.stdout.write(f'Total Active Businesses: {total_businesses}\n')
        
        # Track statistics
        stats = {
            'with_subscription': 0,
            'without_subscription': 0,
            'trial': 0,
            'active': 0,
            'expired': 0,
            'past_due': 0,
            'cancelled': 0,
            'expiring_soon': 0
        }
        
        results = []
        
        for business in businesses:
            try:
                subscription = BusinessSubscription.objects.select_related('plan').get(
                    business=business
                )
                
                stats['with_subscription'] += 1
                
                # Calculate days remaining
                days_remaining = None
                if subscription.end_date:
                    days_remaining = (subscription.end_date - timezone.now().date()).days
                
                # Check if expiring soon
                is_expiring_soon = days_remaining is not None and 0 < days_remaining <= 7
                if is_expiring_soon:
                    stats['expiring_soon'] += 1
                
                # Track by status
                status_key = subscription.status.lower()
                if status_key in stats:
                    stats[status_key] += 1
                
                # Apply filters
                if status_filter and subscription.status != status_filter:
                    continue
                
                if expiring_soon and not is_expiring_soon:
                    continue
                
                # Display subscription info
                self._display_business_with_subscription(
                    business, 
                    subscription, 
                    days_remaining,
                    is_expiring_soon
                )
                
                # Store for export
                results.append({
                    'business_name': business.name,
                    'business_code': business.business_code,
                    'status': subscription.status,
                    'plan': subscription.plan.name,
                    'billing_cycle': subscription.billing_cycle,
                    'days_remaining': days_remaining,
                    'locations': f"{subscription.current_locations_count}/{subscription.plan.max_locations}",
                    'users': f"{subscription.current_users_count}/{subscription.plan.max_users}",
                    'is_expiring_soon': is_expiring_soon
                })
                
            except BusinessSubscription.DoesNotExist:
                stats['without_subscription'] += 1
                
                if no_subscription or not status_filter:
                    self._display_business_without_subscription(business)
                    
                    results.append({
                        'business_name': business.name,
                        'business_code': business.business_code,
                        'status': 'NO SUBSCRIPTION',
                        'plan': 'N/A',
                        'billing_cycle': 'N/A',
                        'days_remaining': None,
                        'locations': business.locations.filter(is_active=True).count(),
                        'users': business.memberships.filter(status='ACTIVE').count(),
                        'is_expiring_soon': False
                    })
        
        # Display summary
        self._display_summary(stats)
        
        # Export if requested
        if export_file:
            self._export_to_csv(results, export_file)
    
    def _display_business_with_subscription(self, business, subscription, days_remaining, is_expiring_soon):
        """Display business with subscription information"""
        
        # Color code based on status
        if subscription.status == 'ACTIVE':
            status_style = self.style.SUCCESS
        elif subscription.status == 'TRIAL':
            status_style = self.style.WARNING
        elif subscription.status in ['EXPIRED', 'PAST_DUE', 'CANCELLED']:
            status_style = self.style.ERROR
        else:
            status_style = self.style.NOTICE
        
        # Format output
        name_str = f'{business.name:<35}'
        status_str = f'{subscription.status:<12}'
        plan_str = f'{subscription.plan.name:<15}'
        
        if days_remaining is not None:
            if days_remaining < 0:
                days_str = f'EXPIRED {abs(days_remaining)} days ago'
                days_style = self.style.ERROR
            elif is_expiring_soon:
                days_str = f'{days_remaining} days left ⚠️'
                days_style = self.style.WARNING
            else:
                days_str = f'{days_remaining} days left'
                days_style = lambda x: x
        else:
            days_str = 'No end date'
            days_style = lambda x: x
        
        usage_str = f'[L:{subscription.current_locations_count}/{subscription.plan.max_locations} U:{subscription.current_users_count}/{subscription.plan.max_users}]'
        
        self.stdout.write(
            f'{name_str} {status_style(status_str)} {plan_str} {days_style(days_str):<25} {usage_str}'
        )
    
    def _display_business_without_subscription(self, business):
        """Display business without subscription"""
        
        name_str = f'{business.name:<35}'
        status_str = self.style.ERROR('NO SUBSCRIPTION')
        locations = business.locations.filter(is_active=True).count()
        users = business.memberships.filter(status='ACTIVE').count()
        usage_str = f'[L:{locations} U:{users}]'
        
        self.stdout.write(
            f'{name_str} {status_str:<25} {"N/A":<15} {"---":<25} {usage_str}'
        )
    
    def _display_summary(self, stats):
        """Display summary statistics"""
        
        self.stdout.write('\n' + '='*80)
        self.stdout.write(self.style.SUCCESS('  SUMMARY'))
        self.stdout.write('='*80 + '\n')
        
        self.stdout.write(f'Businesses with Subscriptions: {stats["with_subscription"]}')
        self.stdout.write(self.style.ERROR(f'Businesses without Subscriptions: {stats["without_subscription"]}'))
        
        self.stdout.write('\nBy Status:')
        self.stdout.write(self.style.WARNING(f'  TRIAL: {stats["trial"]}'))
        self.stdout.write(self.style.SUCCESS(f'  ACTIVE: {stats["active"]}'))
        self.stdout.write(self.style.ERROR(f'  EXPIRED: {stats["expired"]}'))
        self.stdout.write(self.style.ERROR(f'  PAST DUE: {stats["past_due"]}'))
        self.stdout.write(f'  CANCELLED: {stats["cancelled"]}')
        
        if stats['expiring_soon'] > 0:
            self.stdout.write(
                self.style.WARNING(f'\n⚠️  {stats["expiring_soon"]} subscription(s) expiring within 7 days')
            )
        
        if stats['without_subscription'] > 0:
            self.stdout.write(
                self.style.ERROR(f'\n⚠️  {stats["without_subscription"]} business(es) need subscriptions!')
            )
            self.stdout.write(
                '\nRun: python manage.py create_all_trial_subscriptions'
            )
        
        self.stdout.write('\n' + '='*80 + '\n')
    
    def _export_to_csv(self, results, filename):
        """Export results to CSV file"""
        
        import csv
        
        try:
            with open(filename, 'w', newline='') as csvfile:
                fieldnames = [
                    'business_name', 'business_code', 'status', 'plan',
                    'billing_cycle', 'days_remaining', 'locations', 'users',
                    'is_expiring_soon'
                ]
                
                writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
                writer.writeheader()
                
                for row in results:
                    writer.writerow(row)
            
            self.stdout.write(
                self.style.SUCCESS(f'\n✓ Exported to {filename}')
            )
        except Exception as e:
            self.stdout.write(
                self.style.ERROR(f'\n✗ Export failed: {str(e)}')
            )