from uuid import UUID
from django.core.management.base import BaseCommand, CommandError
from extractly.models import SourceNetwork
import asyncio

from link_agregator.tasks import check_flagged_ads_task
from link_agregator.check_active.run_check import run_status_only_checks, run_status_pipeline
from link_agregator.tasks import check_flagged_ads_pipeline_task  # Celery

class Command(BaseCommand):
    help = "Sprawdza aktywność ofert oflagowanych check_active (status-only lub pipeline)."

    def add_arguments(self, parser):
        grp = parser.add_mutually_exclusive_group()
        grp.add_argument("--source_id", type=str, default=None, help="UUID źródła")
        grp.add_argument("--source_name", type=str, default=None, help="Nazwa źródła (case-insensitive / partial)")

        parser.add_argument(
            "--skip-actions",
            action="store_true",
            help="Nie uruchamiaj akcji z configu (run_actions_on_page) w trakcie sprawdzania."
        )

        # NOWE: ordering
        parser.add_argument(
            "--order",
            type=str,
            default="id",
            help="Kolejność rekordów, np.: id, -id, created_at, -created_at, ? (losowo). Działa tylko w trybie inline (bez --enqueue).",
        )

        parser.add_argument("--headless", type=str, choices=["true", "false"], default="true",
                            help="Playwright w trybie headless")

        mode_grp = parser.add_mutually_exclusive_group()
        mode_grp.add_argument("--once", action="store_true", help="Jedna partia (domyślne zachowanie poprzednie).")
        mode_grp.add_argument("--pipeline", action="store_true", help="Tryb pipeline (partie po --batch_size).")

        parser.add_argument("--limit", type=int, default=300, help="[--once] Maksymalna liczba rekordów")
        parser.add_argument("--batch_size", type=int, default=150, help="[--pipeline] Rozmiar partii")
        parser.add_argument("--max_batches", type=int, default=None, help="[--pipeline] Limit liczby partii")
        parser.add_argument("--enqueue", action="store_true", help="Uruchom w Celery (kolejka 'check')")

    def handle(self, *args, **opts):
        headless = (opts["headless"].lower() == "true")
        src_id_opt = opts.get("source_id")
        src_name = opts.get("source_name")
        run_actions = not opts.get("skip_actions", False)
        order_by = opts.get("order") or "id"     # <--- NOWE

        # Rozwiąż source_id/source_name do ID (standaryzacja)
        source_id = None
        if src_id_opt:
            try:
                source_id = UUID(src_id_opt)
            except ValueError:
                raise CommandError("Parametr --source_id nie jest poprawnym UUID.")
            if not SourceNetwork.objects.filter(id=source_id).exists():
                raise CommandError(f"Nie znaleziono źródła o ID {source_id}")
        elif src_name:
            qs = SourceNetwork.objects.filter(title__iexact=src_name)
            if not qs.exists():
                qs = SourceNetwork.objects.filter(title__icontains=src_name)
            if not qs.exists():
                raise CommandError(f"Nie znaleziono źródła o nazwie '{src_name}'")
            if qs.count() > 1:
                self.stdout.write(self.style.WARNING(
                    f"Znaleziono wiele źródeł dla '{src_name}'. Używam pierwszego: {qs[0].title} (ID: {qs[0].id})"
                ))
            source_id = qs.first().id

        # Domyślny tryb: pipeline gdy podano --pipeline, inaczej once
        if opts.get("pipeline"):
            batch_size = int(opts["batch_size"])
            max_batches = opts.get("max_batches")

            if opts["enqueue"]:
                # Uwaga: order_by NIE jest przekazywane do Celery (na Twoją prośbę tylko CLI-inline).
                res = check_flagged_ads_pipeline_task.apply_async(
                    kwargs={
                        "batch_size": batch_size, "headless": headless,
                        "source_id": str(source_id) if source_id else None,
                        "source_name": None,
                        "max_batches": max_batches,
                        "run_actions": run_actions,
                    },
                    queue="check",
                )
                self.stdout.write(self.style.SUCCESS(
                    f"[PIPELINE] Zadanie w kolejce 'check' (task_id={res.id}, source_id={source_id}, batch_size={batch_size})"
                ))
            else:
                out = asyncio.run(run_status_pipeline(
                    batch_size=batch_size, headless=headless,
                    source_id=str(source_id) if source_id else None,
                    source_name=None,
                    max_batches=max_batches,
                    run_actions=run_actions,
                    order_by=order_by,  # <--- NOWE
                ))
                self.stdout.write(self.style.SUCCESS(
                    f"[PIPELINE] Batches={out.get('batches')} checked={out.get('checked')} errors={out.get('errors')}"
                ))
        else:
            # once
            limit = int(opts["limit"])
            if opts["enqueue"]:
                # Uwaga: order_by NIE jest przekazywane do Celery (na Twoją prośbę tylko CLI-inline).
                res = check_flagged_ads_task.apply_async(
                    kwargs={
                        "limit": limit, "headless": headless,
                        "source_id": str(source_id) if source_id else None,
                        "source_name": None,
                        "run_actions": run_actions,
                    },
                    queue="check",
                )
                self.stdout.write(self.style.SUCCESS(
                    f"[ONCE] Zadanie w kolejce 'check' (task_id={res.id}, source_id={source_id}, limit={limit})"
                ))
            else:
                out = asyncio.run(run_status_only_checks(
                    limit=limit, headless=headless,
                    source_id=str(source_id) if source_id else None,
                    source_name=None,
                    run_actions=run_actions,
                    order_by=order_by,  # <--- NOWE
                ))
                self.stdout.write(self.style.SUCCESS(
                    f"[ONCE] Sprawdzono: {out.get('checked', 0)} (errors={out.get('errors', 0)})"
                ))
