import logging
import signal
import time

from django.core.management.base import BaseCommand

from django_broadcaster.publishers import publisher

logger = logging.getLogger(__name__)


class Command(BaseCommand):
    help = "Run the outbox pattern worker to process pending events"

    def __init__(self):
        super().__init__()
        self.running = True

    def add_arguments(self, parser):
        parser.add_argument(
            "--batch-size",
            type=int,
            default=100,
            help="Number of events to process in each batch (default: 100)",
        )
        parser.add_argument(
            "--interval",
            type=int,
            default=5,
            help="Interval in seconds between processing batches (default: 5)",
        )
        parser.add_argument(
            "--max-iterations",
            type=int,
            default=0,
            help="Maximum number of iterations to run (0 for infinite, default: 0)",
        )

    def handle(self, *args, **options):
        batch_size = options["batch_size"]
        interval = options["interval"]
        max_iterations = options["max_iterations"]

        # Set up signal handlers for graceful shutdown
        signal.signal(signal.SIGINT, self._signal_handler)
        signal.signal(signal.SIGTERM, self._signal_handler)

        self.stdout.write(
            self.style.SUCCESS(
                f"Starting outbox worker (batch_size={batch_size}, interval={interval}s)"
            )
        )

        iteration = 0

        while self.running:
            try:
                # Check backend health
                health_status = publisher.get_backend_health()
                unhealthy_backends = [
                    name for name, healthy in health_status.items() if not healthy
                ]

                if unhealthy_backends:
                    logger.warning(f"Unhealthy backends detected: {unhealthy_backends}")

                # Process pending events
                processed_count = publisher.process_pending_events(batch_size)

                if processed_count > 0:
                    self.stdout.write(
                        self.style.SUCCESS(f"Processed {processed_count} events")
                    )
                    logger.info(
                        f"Processed {processed_count} events in iteration {iteration + 1}"
                    )
                else:
                    logger.debug(f"No events to process in iteration {iteration + 1}")

                iteration += 1

                # Check if we've reached max iterations
                if max_iterations > 0 and iteration >= max_iterations:
                    self.stdout.write(
                        self.style.SUCCESS(
                            f"Reached maximum iterations ({max_iterations}), stopping"
                        )
                    )
                    break

                # Wait before next iteration
                if self.running:
                    time.sleep(interval)

            except KeyboardInterrupt:
                break
            except Exception as e:
                logger.error(f"Error in outbox worker: {str(e)}")
                self.stdout.write(self.style.ERROR(f"Error in worker: {str(e)}"))
                # Continue running even if there's an error
                time.sleep(interval)

        self.stdout.write(self.style.SUCCESS("Outbox worker stopped gracefully"))

    def _signal_handler(self, signum, frame):
        """Handle shutdown signals"""
        self.stdout.write(
            self.style.WARNING(f"Received signal {signum}, shutting down gracefully...")
        )
        self.running = False
