"""Shared editor plumbing: slugs, media-URL resolution, the library sidecar."""
import json
import os
import re
import threading
from pathlib import Path

from clipshelf import config
from clipshelf.config import ASSETS, DATA, EXPORTS, HIGHLIGHTS_DIR, SOUNDS
HIGHLIGHTS = Path(HIGHLIGHTS_DIR)

SLUG = re.compile(r"[^a-zA-Z0-9_-]+")


def slugify(name: str) -> str:
    return SLUG.sub("-", name).strip("-")[:60] or "untitled"


def resolve_media(src: str) -> str:
    """Map a frontend media URL to a file on disk."""
    from urllib.parse import unquote
    src = unquote(src)
    if src.startswith("/clips/"):
        p = EXPORTS / src[len("/clips/"):]
    elif src.startswith("/vod_media/"):
        p = Path(config.VOD_DIR) / src[len("/vod_media/"):]
    elif src.startswith("/api/editor/assets/"):
        p = ASSETS / src.rsplit("/", 1)[1]
    elif src.startswith("/api/editor/sounds/"):
        p = SOUNDS / src.rsplit("/", 1)[1]
    elif src.startswith("/api/editor/highlights/file/"):
        p = HIGHLIGHTS / src[len("/api/editor/highlights/file/"):]
    else:
        raise ValueError(f"unresolvable src {src}")
    p = p.resolve()
    roots = [EXPORTS.resolve(), ASSETS.resolve(), SOUNDS.resolve(), HIGHLIGHTS.resolve()]
    if config.VOD_DIR:
        roots.append(Path(config.VOD_DIR).resolve())
    for root in roots:
        if str(p).startswith(str(root)):
            if not p.exists():
                raise ValueError(f"missing media {p}")
            return str(p)
    raise ValueError(f"src escapes media roots: {src}")


# ---------------------------------------------------------------- library
# Folder/tag organization for assets + sounds; one JSON sidecar. Files with
# no recorded name (freeze grabs, voiceovers…) surface in "unsorted".
LIBRARY = DATA / "library.json"
lib_lock = threading.Lock()

ASSET_KINDS = {".png": "image", ".jpg": "image", ".jpeg": "image", ".webp": "image",
               ".gif": "image", ".webm": "video", ".mp4": "video", ".mov": "video",
               ".wav": "audio", ".mp3": "audio", ".ogg": "audio", ".m4a": "audio"}
SOUND_EXTS = (".wav", ".mp3", ".ogg", ".m4a", ".webm")


def lib_load() -> dict:
    try:
        lib = json.loads(LIBRARY.read_text(encoding="utf-8"))
    except Exception:
        lib = {}
    lib.setdefault("assets", {})
    lib.setdefault("sounds", {})
    lib.setdefault("folders", {})
    lib["folders"].setdefault("assets", [])
    lib["folders"].setdefault("sounds", [])
    return lib


def lib_save(lib: dict):
    tmp = LIBRARY.with_suffix(".tmp")
    tmp.write_text(json.dumps(lib), encoding="utf-8")
    tmp.replace(LIBRARY)


def lib_note(kind: str, fname: str, **patch):
    """Record/patch a library entry (display name / folder / tags)."""
    patch = {k: v for k, v in patch.items() if v is not None}
    if not patch:
        return
    with lib_lock:
        lib = lib_load()
        lib[kind].setdefault(fname, {}).update(patch)
        lib_save(lib)


def clean_folder(s) -> str:
    return re.sub(r"[^\w \-]", "", str(s or "")).strip()[:40]
