"""
Cache Management API
GET  /api/cache/stats     — Get cache statistics + key breakdown
GET  /api/cache/keys      — List all cached keys with TTL
POST /api/cache/clear     — Clear cache by pattern
POST /api/cache/clear-all — Flush all cache
"""

import logging
from fastapi import APIRouter
from fastapi.responses import JSONResponse

from common.cache import redis_cache

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/cache", tags=["Cache"])


@router.get("/stats")
async def cache_stats():
    """Get cache statistics and key breakdown."""
    client = redis_cache.get_client()
    if not client:
        return JSONResponse({"error": "Redis not available"}, status_code=503)

    try:
        info = await client.info("memory")
        db_size = await client.dbsize()

        # Scan all keys and categorize
        categories = {}
        async for key in client.scan_iter("*", count=500):
            prefix = key.split(":")[0] if ":" in key else "(no prefix)"
            if prefix not in categories:
                categories[prefix] = {"count": 0, "keys": []}
            categories[prefix]["count"] += 1
            if len(categories[prefix]["keys"]) < 5:
                ttl = await client.ttl(key)
                categories[prefix]["keys"].append({"key": key, "ttl": ttl})

        return {
            "status": "connected",
            "memory_used": info.get("used_memory_human", "?"),
            "memory_peak": info.get("used_memory_peak_human", "?"),
            "total_keys": db_size,
            "in_memory_stats": redis_cache._stats,
            "categories": categories,
        }
    except Exception as e:
        logger.error(f"Cache stats error: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@router.get("/keys")
async def list_keys(pattern: str = "*", limit: int = 100):
    """List cached keys matching pattern with TTL info."""
    client = redis_cache.get_client()
    if not client:
        return JSONResponse({"error": "Redis not available"}, status_code=503)

    try:
        keys = []
        count = 0
        async for key in client.scan_iter(pattern, count=500):
            if count >= limit:
                break
            ttl = await client.ttl(key)
            key_type = await client.type(key)
            size = await client.strlen(key) if key_type == "string" else -1
            keys.append({
                "key": key,
                "type": key_type,
                "ttl": ttl,
                "size": size,
            })
            count += 1

        return {"pattern": pattern, "count": len(keys), "keys": keys}
    except Exception as e:
        logger.error(f"List keys error: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@router.post("/clear")
async def clear_pattern(pattern: str = "resp_cache:*"):
    """Clear cache keys matching pattern."""
    client = redis_cache.get_client()
    if not client:
        return JSONResponse({"error": "Redis not available"}, status_code=503)

    try:
        deleted = 0
        async for key in client.scan_iter(pattern, count=500):
            await client.delete(key)
            deleted += 1

        logger.info(f"🗑️ Cleared {deleted} keys matching '{pattern}'")
        return {"deleted": deleted, "pattern": pattern}
    except Exception as e:
        logger.error(f"Clear cache error: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@router.post("/clear-all")
async def clear_all():
    """Flush entire cache database."""
    client = redis_cache.get_client()
    if not client:
        return JSONResponse({"error": "Redis not available"}, status_code=503)

    try:
        await client.flushdb()
        redis_cache._stats = {"resp_hits": 0, "emb_hits": 0, "misses": 0}
        logger.info("🗑️ FLUSHED all cache")
        return {"status": "flushed", "message": "All cache cleared"}
    except Exception as e:
        logger.error(f"Flush cache error: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)


@router.get("/get")
async def get_key(key: str):
    """Get the value stored in a specific cache key."""
    client = redis_cache.get_client()
    if not client:
        return JSONResponse({"error": "Redis not available"}, status_code=503)

    try:
        key_type = await client.type(key)
        ttl = await client.ttl(key)
        value = None

        if key_type == "string":
            raw = await client.get(key)
            # Try to parse as JSON
            try:
                import json
                value = json.loads(raw)
            except Exception:
                value = raw
        elif key_type == "hash":
            value = await client.hgetall(key)
        elif key_type == "list":
            value = await client.lrange(key, 0, 50)
        elif key_type == "set":
            value = list(await client.smembers(key))
        elif key_type == "zset":
            value = await client.zrange(key, 0, 50, withscores=True)
        else:
            value = f"(unsupported type: {key_type})"

        return {
            "key": key,
            "type": key_type,
            "ttl": ttl,
            "value": value,
        }
    except Exception as e:
        logger.error(f"Get key error: {e}")
        return JSONResponse({"error": str(e)}, status_code=500)

