"""Re-runs the extraction pipeline over already-uploaded declarations.

Mainly useful after configuring an OCR API key: every scan uploaded before the
key existed is sitting at "À confirmer" and can now be classified for real.

    python manage.py reclassify_documents --only-pending
    python manage.py reclassify_documents --dry-run
"""
from django.core.management.base import BaseCommand

from documents.extraction import analyze_document
from documents.models import CustomsDocument


class Command(BaseCommand):
    help = 'Re-extracts and re-classifies stored customs documents.'

    def add_arguments(self, parser):
        parser.add_argument(
            '--only-pending', action='store_true',
            help='Only documents currently "À confirmer" (typically scans that '
                 'were uploaded before an OCR key was configured).',
        )
        parser.add_argument(
            '--include-manual', action='store_true',
            help='Also re-classify documents an admin corrected by hand. Off by '
                 'default so a human decision is never silently overwritten.',
        )
        parser.add_argument(
            '--dry-run', action='store_true',
            help='Report what would change without writing anything.',
        )

    def handle(self, *args, **options):
        queryset = CustomsDocument.objects.all()
        if options['only_pending']:
            queryset = queryset.filter(status=CustomsDocument.Status.PENDING_REVIEW)
        if not options['include_manual']:
            queryset = queryset.filter(auto_classified=True)

        total = queryset.count()
        if not total:
            self.stdout.write('No document to re-classify.')
            return

        changed = failed = 0
        for document in queryset.iterator():
            try:
                result = analyze_document(document.file.path)
            except (OSError, ValueError) as exc:
                # A file missing from disk must not abort the whole run.
                failed += 1
                self.stderr.write(self.style.WARNING(f'{document.pk}: unreadable ({exc})'))
                continue

            was = (document.status, document.officer_name)
            now = (result['statut'], result['agent_detecte'])

            if was != now:
                changed += 1
                self.stdout.write(
                    f'{document.pk} {document.original_filename}: '
                    f'{was[0]}/{was[1]!r} -> {now[0]}/{now[1]!r} [{result["source"]}]'
                )

            if not options['dry_run']:
                document.status = result['statut']
                document.officer_name = result['agent_detecte']
                document.text_source = result['source']
                document.extracted_text = result['texte_brut']
                document.save(update_fields=[
                    'status', 'officer_name', 'text_source', 'extracted_text',
                ])

        verb = 'would change' if options['dry_run'] else 'changed'
        self.stdout.write(self.style.SUCCESS(
            f'{total} document(s) processed, {changed} {verb}, {failed} unreadable.'
        ))
