"""
Management command for running cron tasks.
"""

from datetime import date
from django.core.management.base import BaseCommand, CommandError
from django_cronjob_utils.registry import TaskRegistry
from django_cronjob_utils.exceptions import TaskNotFoundError, ConcurrentExecutionError


class Command(BaseCommand):
    help = 'Run a registered cron task'
    
    def execute(self, *args, **options):
        """Override to catch SystemExit and convert to return code."""
        try:
            return super().execute(*args, **options)
        except SystemExit as e:
            # Convert SystemExit to a return code that call_command() will return
            return e.code if e.code is not None else 0
    
    def add_arguments(self, parser):
        parser.add_argument(
            'task_name',
            type=str,
            help='Task name (e.g., calc-commission)'
        )
        parser.add_argument(
            'date',
            type=str,
            help='Execution date (YYYY-MM-DD)'
        )
        parser.add_argument(
            '--force',
            action='store_true',
            help='Force execution even if already ran'
        )
        parser.add_argument(
            '--rerun',
            action='store_true',
            help='Rerun even if successful'
        )
    
    def handle(self, *args, **options):
        task_name = options['task_name']
        
        # Parse date
        try:
            execution_date = date.fromisoformat(options['date'])
        except ValueError:
            raise CommandError(f"Invalid date format: {options['date']}. Use YYYY-MM-DD format.")
        
        try:
            # Get task class from registry
            task_class = TaskRegistry.get_task(task_name)
            
            # Create task instance
            task = task_class(
                execution_date=execution_date,
                force=options['force'],
                rerun=options['rerun']
            )
            
            # Run task
            result = task.run()
            
            if result.skipped:
                self.stdout.write(
                    self.style.WARNING(
                        f"Task '{task_name}' was skipped: {result.reason}"
                    )
                )
                raise SystemExit(0)
            
            if result.success:
                self.stdout.write(
                    self.style.SUCCESS(
                        f"Task '{task_name}' completed successfully: {result.message}"
                    )
                )
                raise SystemExit(0)
            else:
                self.stdout.write(
                    self.style.ERROR(
                        f"Task '{task_name}' failed: {result.message} "
                        f"(Error code: {result.error_code})"
                    )
                )
                raise SystemExit(1)
                
        except TaskNotFoundError as e:
            self.stdout.write(
                self.style.ERROR(str(e))
            )
            raise SystemExit(1)
        except ConcurrentExecutionError as e:
            self.stdout.write(
                self.style.WARNING(str(e))
            )
            raise SystemExit(2)
        except SystemExit:
            raise  # Re-raise SystemExit to propagate code
        except Exception as e:
            self.stdout.write(
                self.style.ERROR(
                    f"Unexpected error running task '{task_name}': {str(e)}"
                )
            )
            import traceback
            traceback_str = traceback.format_exc()
            if traceback_str:
                self.stdout.write(traceback_str)
            raise SystemExit(1)
