from __future__ import annotations

from datetime import timedelta

from django.core.management.base import BaseCommand
from django.db import transaction
from django.utils import timezone

from ocyan.plugin.ai_assistant.constants import (
    MODE_ADMIN,
    MODE_CUSTOMER,
    SESSION_CLOSED,
)
from ocyan.plugin.ai_assistant.models import AiAssistantSession


class Command(BaseCommand):
    help = "Close or delete old AI assistant sessions. Dry-run by default."

    def add_arguments(self, parser):
        parser.add_argument("--days", type=int, default=30)
        parser.add_argument(
            "--mode",
            choices=["customer", "admin", "all"],
            default="customer",
        )
        parser.add_argument(
            "--delete",
            action="store_true",
            help="Delete matching sessions instead of closing them.",
        )
        parser.add_argument(
            "--apply",
            action="store_true",
            help="Apply changes. Without this flag the command is dry-run only.",
        )

    def handle(self, *args, **options):
        days = options["days"]
        cutoff = timezone.now() - timedelta(days=days)
        queryset = AiAssistantSession.objects.filter(updated_at__lt=cutoff)

        if options["mode"] == MODE_CUSTOMER:
            queryset = queryset.filter(mode=MODE_CUSTOMER)
        elif options["mode"] == MODE_ADMIN:
            queryset = queryset.filter(mode=MODE_ADMIN)

        matched_sessions = queryset.count()
        matched_messages = sum(
            queryset.values_list("messages__id", flat=True)
            .exclude(messages__id=None)
            .count()
            for _ in [0]
        )
        action = "delete" if options["delete"] else "close"

        self.stdout.write(
            self.style.WARNING(
                f"Dry run: {not options['apply']} | action={action} | mode={options['mode']} | "
                f"days={days} | sessions={matched_sessions} | messages={matched_messages}"
            )
        )

        if not options["apply"]:
            return

        if options["delete"]:
            with transaction.atomic():
                deleted_sessions, deleted_detail = queryset.delete()
            self.stdout.write(
                self.style.SUCCESS(
                    f"Deleted {deleted_sessions} rows across matching sessions and related records."
                )
            )
            self.stdout.write(str(deleted_detail))
            return

        updated = queryset.exclude(status=SESSION_CLOSED).update(
            status=SESSION_CLOSED,
            updated_at=timezone.now(),
        )
        self.stdout.write(self.style.SUCCESS(f"Closed {updated} sessions."))
