import logging, importlib
from django.conf import settings
from django.db import transaction
from django.db.models.signals import post_save
from django.dispatch import receiver
from extractly.models import AdsManual
from link_agregator.check_active.context import STATUS_ONLY_MODE

logger = logging.getLogger(__name__)
AUTO_UPLOAD_ENABLED = getattr(settings, "IMAGES_AUTO_UPLOAD_ENABLED", True)

def _resolve_store_main_image():
    for mod in ("image_agregator.images", "manual_agregator.images"):
        try:
            return importlib.import_module(mod).store_main_image
        except Exception:
            continue
    return None



@receiver(post_save, sender=AdsManual)
def adsmanual_post_save_upload_image(sender, instance, created, update_fields=None, **kwargs):
    if STATUS_ONLY_MODE.get():
        return                     # ⬅️ nie kolejkuj nic obrazkowego w status-only
    if not getattr(settings, "IMAGES_AUTO_UPLOAD_ENABLED", True):
        return
    if not AUTO_UPLOAD_ENABLED:
        return

    # 1) nie uruchamiaj, gdy to był zapis właśnie pola "images"
    if update_fields and "images" in update_fields:
        return

    # 1.1) pomiń zapisy status-check (unikamy zapętleń: flagowanie -> post_save -> kolejka -> flagowanie ...)
    if update_fields:
        uf = set(update_fields)
        if uf and uf.issubset({"check_active", "check_active_from_image", "meta"}):
            return

    # 2) przy aktualizacjach – jeśli już mamy miniaturę, nie rób nic
    if not created:
        imgs = getattr(instance, "images", None)
        if (isinstance(imgs, dict) and imgs.get("main")) or (isinstance(imgs, str) and imgs):
            return

    # 2.1) brak kandydatów obrazów – nie kolejkuj (unikamy zapętleń)
    originals = getattr(instance, "original_image_urls", None)
    has_candidates = bool(originals)
    if not has_candidates:
        logger.info("Skip image upload: no original_image_urls for id=%s", getattr(instance, "id", None))
        return

    def _enqueue():
        try:
            # spróbuj Celery
            try:
                from image_agregator.tasks import task_store_main_image
                task_store_main_image.delay(instance.id, overwrite=False)
                return
            except Exception as e:
                logger.info("Celery task fallback to sync: %s", e)

            # fallback sync: ale tylko jeśli nadal brak miniatury
            imgs = getattr(instance, "images", None)
            if (isinstance(imgs, dict) and imgs.get("main")) or (isinstance(imgs, str) and imgs):
                return

            store_main_image = _resolve_store_main_image()
            if store_main_image:
                try:
                    store_main_image(instance)
                except Exception as e2:
                    logger.warning("Sync image upload failed for ad_id=%s: %s", instance.id, e2)
            else:
                logger.warning("No store_main_image implementation found.")
        except Exception as e:
            # absolutnie nic nie wypuszczamy wyżej – on_commit musi zakończyć się bez wyjątku
            logger.error("on_commit enqueue failed: %s", e)

    transaction.on_commit(_enqueue)
