"""Local cover art cache for the player UI.

Caches extracted cover art as JPEG files in a local directory
so the player can display them without re-extracting from audio.
"""

from __future__ import annotations

import hashlib
import logging
import os

from xdg_base import xdg_cache_path

logger = logging.getLogger(__name__)


class CoverCache:
    """Manages a local cache of cover art images for the player UI.

    The cache stores JPEG thumbnails keyed by (artist, album) hash.
    Covers are stored in $XDG_CACHE_HOME/neo-pod-desktop/covers/
    (default ~/.cache/neo-pod-desktop/covers/).
    """

    def __init__(self, cache_dir: str | None = None):
        self.cache_dir = cache_dir or xdg_cache_path("covers")
        os.makedirs(self.cache_dir, exist_ok=True)

    def _key(self, artist: str, album: str) -> str:
        raw = f"{artist.lower()}|{album.lower()}"
        return hashlib.md5(raw.encode()).hexdigest()

    def get(self, artist: str, album: str) -> str | None:
        """Return path to cached cover, or None."""
        path = os.path.join(self.cache_dir, f"{self._key(artist, album)}.jpg")
        if os.path.exists(path):
            return path
        return None

    def put(self, artist: str, album: str, art_bytes: bytes) -> str | None:
        """Cache cover art bytes and return the file path."""
        from PIL import Image
        from io import BytesIO

        key = self._key(artist, album)
        path = os.path.join(self.cache_dir, f"{key}.jpg")
        try:
            img = Image.open(BytesIO(art_bytes))
            img = img.convert("RGB")
            img.thumbnail((300, 300), Image.Resampling.LANCZOS)
            img.save(path, "JPEG", quality=85)
            return path
        except Exception as exc:
            logger.warning("Failed to cache cover art: %s", exc)
            return None

    def clear(self) -> None:
        """Remove all cached covers."""
        for fname in os.listdir(self.cache_dir):
            if fname.endswith(".jpg"):
                try:
                    os.remove(os.path.join(self.cache_dir, fname))
                except OSError:
                    pass


cover_cache = CoverCache()
