import json
import logging
from pathlib import Path
from typing import Any, Type

from django.core.cache import cache
from django.core.exceptions import BadRequest
from django.utils.translation import gettext_lazy as _
from graphene import Context
from rest_framework.request import Request

from evibes.settings import UNSAFE_CACHE_KEYS
from vibes_auth.models import User

logger = logging.getLogger("django")


def is_safe_cache_key(key: str) -> bool:
    return key not in UNSAFE_CACHE_KEYS


def get_cached_value(user: Type[User], key: str, default: Any = None) -> Any:
    if user.is_staff or user.is_superuser:
        return cache.get(key, default)

    if is_safe_cache_key(key):
        return cache.get(key, default)

    return None


def set_cached_value(user: Type[User], key: str, value: object, timeout: int = 3600) -> None | object:
    if user.is_staff or user.is_superuser:
        cache.set(key, value, timeout)
        return value

    return None


def web_cache(request: Request | Context, key: str, data: dict[str, Any], timeout: int) -> dict[str, Any]:
    if not data and not timeout:
        return {"data": get_cached_value(request.user, key)}  # type: ignore [assignment, arg-type]
    if (data and not timeout) or (timeout and not data):
        raise BadRequest(_("both data and timeout are required"))
    if not 0 < int(timeout) < 216000:
        raise BadRequest(_("invalid timeout value, it must be between 0 and 216000 seconds"))
    return {"data": set_cached_value(request.user, key, data, timeout)}  # type: ignore [assignment, arg-type]


def set_default_cache() -> None:
    data_dir = Path(__file__).resolve().parent.parent / "data"
    for json_file in data_dir.glob("*.json"):
        with json_file.open("r", encoding="utf-8") as f:
            data = json.load(f)
        logger.info(f"Setting cache for {json_file.stem}")
        cache.set(json_file.stem, data, timeout=28800)
