# abstractclass/cache_tools.py
from django.core.cache import cache
from celery import shared_task


try:
    from django_redis import get_redis_connection
except Exception:
    get_redis_connection = None

def _delete_by_patterns_via_redis(patterns, log_prefix=""):
    if get_redis_connection is None:
        print(f"{log_prefix}[CACHE] django-redis not installed; cannot delete by pattern.")
        return False

    try:
        con = get_redis_connection("default")
    except Exception as e:
        print(f"{log_prefix}[CACHE] Cannot get redis connection: {e}")
        return False

    for pat in patterns or []:
        total = 0
        cursor = 0
        # używamy SCAN żeby nie blokować Redisa jak KEYS
        while True:
            cursor, keys = con.scan(cursor=cursor, match=pat, count=1000)
            if keys:
                # redis-py akceptuje rozpakowanie listy
                con.delete(*keys)
                total += len(keys)
            if cursor == 0:
                break
        print(f"{log_prefix}[CACHE] Deleted {total} keys for pattern: {pat}")
    return True


def _cache_clear(*, keys=None, patterns=None, clear_all=False, log_prefix=""):
    keys = keys or []
    patterns = patterns or []

    if clear_all:
        cache.clear()
        print(f"{log_prefix}[CACHE] Cleared ALL cache.")
        return

    # 1) Dokładne klucze
    for k in keys:
        try:
            cache.delete(k)
            print(f"{log_prefix}[CACHE] Deleted key: {k}")
        except Exception as e:
            print(f"{log_prefix}[CACHE] Del key error '{k}': {e}")

    # 2) Wzorce
    if patterns:
        delete_pattern = getattr(cache, "delete_pattern", None)
        if callable(delete_pattern):
            for p in patterns:
                try:
                    delete_pattern(p)
                    print(f"{log_prefix}[CACHE] Deleted pattern: {p}")
                except Exception as e:
                    print(f"{log_prefix}[CACHE] Del pattern error '{p}': {e}")
        else:
            # fallback po SCAN jeśli mamy django-redis
            if not _delete_by_patterns_via_redis(patterns, log_prefix=log_prefix):
                print(f"{log_prefix}[CACHE] Pattern delete unsupported by backend. Ignored: {patterns}")


@shared_task(name="cache.clear")
def clear_cache_task(previous_task_result=None, *, keys=None, patterns=None, clear_all=False, log_prefix=""):
    _cache_clear(keys=keys, patterns=patterns, clear_all=clear_all, log_prefix=log_prefix)
    return {"status": "ok", "keys": keys or [], "patterns": patterns or [], "clear_all": bool(clear_all)}
