"""
Management command to mark surveys as abandoned.

Marks surveys that have been opened or started but not completed
within a configurable time period as abandoned.

Usage:
    python manage.py mark_abandoned_surveys
    python manage.py mark_abandoned_surveys --hours 24
    python manage.py mark_abandoned_surveys --dry-run
"""

from django.core.management.base import BaseCommand
from django.utils import timezone
from django.conf import settings
from datetime import timedelta

from apps.surveys.models import SurveyInstance, SurveyTracking


class Command(BaseCommand):
    help = "Mark surveys as abandoned if not completed within specified time"

    def add_arguments(self, parser):
        parser.add_argument(
            "--hours",
            type=int,
            default=getattr(settings, "SURVEY_ABANDONMENT_HOURS", 24),
            help="Hours after which to mark survey as abandoned (default: 24)",
        )
        parser.add_argument("--dry-run", action="store_true", help="Show what would be done without making changes")

    def handle(self, *args, **options):
        hours = options["hours"]
        dry_run = options["dry_run"]

        self.stdout.write(
            self.style.SUCCESS(f"{'[DRY RUN] ' if dry_run else ''}Marking surveys as abandoned (after {hours} hours)")
        )

        cutoff_time = timezone.now() - timedelta(hours=hours)

        surveys_to_abandon = SurveyInstance.objects.filter(
            status__in=["viewed", "in_progress"], token_expires_at__gt=timezone.now(), last_opened_at__lt=cutoff_time
        ).select_related("survey_template", "patient")

        count = surveys_to_abandon.count()

        if count == 0:
            self.stdout.write(self.style.WARNING("No surveys to mark as abandoned"))
            return

        self.stdout.write(f"Found {count} surveys to mark as abandoned:")

        for survey in surveys_to_abandon:
            time_since_open = timezone.now() - survey.last_opened_at
            hours_since_open = time_since_open.total_seconds() / 3600

            tracking_events = survey.tracking_events.filter(event_type="question_answered").count()

            self.stdout.write(
                f"  - {survey.survey_template.name} | "
                f"Patient: {survey.patient.get_full_name()} | "
                f"Status: {survey.status} | "
                f"Opened: {survey.last_opened_at.strftime('%Y-%m-%d %H:%M')} | "
                f"{hours_since_open:.1f} hours ago | "
                f"Questions answered: {tracking_events}"
            )

        if dry_run:
            self.stdout.write(self.style.WARNING(f"\n[DRY RUN] Would mark {count} surveys as abandoned"))
            return

        updated = 0
        for survey in surveys_to_abandon:
            original_status = survey.status
            time_since_open = timezone.now() - survey.last_opened_at

            survey.status = "abandoned"
            survey.save(update_fields=["status"])

            tracking_events = survey.tracking_events.filter(event_type="question_answered")

            SurveyTracking.objects.create(
                survey_instance=survey,
                event_type="survey_abandoned",
                current_question=tracking_events.count(),
                total_time_spent=survey.time_spent_seconds or 0,
                metadata={
                    "time_since_open_hours": round(time_since_open.total_seconds() / 3600, 2),
                    "questions_answered": tracking_events.count(),
                    "original_status": original_status,
                },
            )
            updated += 1

        self.stdout.write(self.style.SUCCESS(f"\nSuccessfully marked {updated} surveys as abandoned"))
