from datetime import date

from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand, CommandError

from seasons.constants import SeasonOrchestrationStatus
from seasons.orchestration import SeasonCompetitionOrchestrationService


class Command(BaseCommand):
    help = "Prepare/execute the FTG Season & Competition Orchestration workflow."

    def add_arguments(self, parser):
        parser.add_argument("--source-season-id", required=True, type=int)
        parser.add_argument("--target-season-id", required=True, type=int)
        parser.add_argument("--operator-user-id", default=None)
        parser.add_argument("--prepare-only", action="store_true")
        parser.add_argument("--recover-interrupted", action="store_true")
        parser.add_argument("--activate", action="store_true")
        parser.add_argument(
            "--effective-date",
            default=None,
            help="Optional YYYY-MM-DD date used only by --activate.",
        )

    def handle(self, *args, **options):
        operator = None
        if options["operator_user_id"]:
            User = get_user_model()
            try:
                operator = User.objects.get(pk=options["operator_user_id"])
            except User.DoesNotExist as exc:
                raise CommandError("Operator user does not exist.") from exc

        try:
            run = SeasonCompetitionOrchestrationService.prepare(
                source_season_id=options["source_season_id"],
                target_season_id=options["target_season_id"],
            )
            self.stdout.write(f"run={run.pk} status={run.status}")

            if options["prepare_only"]:
                return

            if options["recover_interrupted"] and run.status == SeasonOrchestrationStatus.RUNNING:
                run = SeasonCompetitionOrchestrationService.recover_interrupted(run_id=run.pk)
                self.stdout.write(self.style.WARNING(f"recovered run={run.pk} status={run.status}"))

            run = SeasonCompetitionOrchestrationService.execute(
                run_id=run.pk,
                performed_by=operator,
            )
            self.stdout.write(self.style.SUCCESS(f"orchestration succeeded run={run.pk}"))

            if options["activate"]:
                effective_date = None
                if options["effective_date"]:
                    try:
                        effective_date = date.fromisoformat(options["effective_date"])
                    except ValueError as exc:
                        raise CommandError("--effective-date must use YYYY-MM-DD.") from exc
                season = SeasonCompetitionOrchestrationService.activate_target(
                    run_id=run.pk,
                    today=effective_date,
                )
                self.stdout.write(self.style.SUCCESS(f"activated season={season.pk} status={season.status}"))
        except CommandError:
            raise
        except Exception as exc:
            raise CommandError(str(exc)) from exc
