"""
Generate the two word topic label for chat sessions that predate the field.

Only sessions with at least one visitor message and no topic yet are touched,
so running this twice is safe.

    python manage.py backfill_chat_topics             # every unlabelled session
    python manage.py backfill_chat_topics --dry-run   # report only
    python manage.py backfill_chat_topics --limit 20  # stop after 20
"""
from django.core.management.base import BaseCommand

from apps.chat.models import ChatSession, ChatMessage


class Command(BaseCommand):
    help = 'Label older chat sessions with a two word topic.'

    def add_arguments(self, parser):
        parser.add_argument('--dry-run', action='store_true',
                            help='Show what would be generated without saving.')
        parser.add_argument('--limit', type=int, default=0,
                            help='Stop after this many sessions.')
        parser.add_argument('--force', action='store_true',
                            help='Clear and regenerate labels that already exist.')

    def handle(self, *args, **options):
        dry_run = options['dry_run']
        qs = ChatSession.objects.all() if options['force'] else ChatSession.objects.filter(topic='')
        qs = qs.order_by('-created_at')
        if options['limit']:
            qs = qs[:options['limit']]

        sessions = list(qs)
        if not sessions:
            self.stdout.write('Nothing to do. Every session already has a topic.')
            return

        self.stdout.write(f'Labelling {len(sessions)} session(s).')
        done = skipped = failed = 0

        for session in sessions:
            said = list(
                session.messages.filter(role=ChatMessage.ROLE_USER)
                .order_by('created_at')
                .values_list('content', flat=True)[:4]
            )
            if not said:
                skipped += 1
                self.stdout.write(f'  #{session.pk}: no visitor messages, skipped.')
                continue

            if dry_run:
                preview = said[0][:60].replace('\n', ' ')
                self.stdout.write(f'  #{session.pk}: would label from "{preview}"')
                done += 1
                continue

            if options['force'] and session.topic:
                session.topic = ''
                session.save(update_fields=['topic'])
            label = session.generate_topic()
            if label:
                done += 1
                self.stdout.write(f'  #{session.pk}: {label}')
            else:
                failed += 1
                self.stdout.write(self.style.WARNING(
                    f'  #{session.pk}: no label returned. Check the OpenAI key for '
                    f'tenant "{session.tenant.name}".'
                ))

        verb = 'would label' if dry_run else 'labelled'
        self.stdout.write(self.style.SUCCESS(
            f'Done. {verb} {done}, skipped {skipped}, failed {failed}.'
        ))
