"""Server-managed enhancement prompts (company-global AI modes).

A company can define system prompts centrally on the server; clients fetch them
via GET /v1/prompts, show them alongside the user's own modes, and let the user
pick a server mode or add their own. Managed here as a JSON list in the data
dir, editable by the prompt-management CLI (VoxCastServer.exe --add-prompt ...)
on Windows AND Unix, or by editing the file directly.

Each prompt: {"id": str, "name": str, "prompt": str}. No secrets.
"""
from __future__ import annotations

import json
import re
from pathlib import Path

from loguru import logger

_SLUG = re.compile(r"[^a-z0-9]+")


def prompts_path(data_dir: str | Path) -> Path:
    return Path(data_dir) / "prompts.json"


def slugify(name: str) -> str:
    s = _SLUG.sub("-", (name or "").strip().lower()).strip("-")
    return s or "mode"


def _valid_entry(e: object) -> bool:
    return (isinstance(e, dict) and isinstance(e.get("id"), str)
            and isinstance(e.get("name"), str)
            and isinstance(e.get("prompt"), str)
            and bool(e["id"].strip()) and bool(e["prompt"].strip()))


def load_prompts(data_dir: str | Path) -> list[dict]:
    """Return the server prompt list (empty if none/invalid). Read fresh each
    call so CLI edits take effect without a restart."""
    path = prompts_path(data_dir)
    if not path.exists():
        return []
    try:
        data = json.loads(path.read_text(encoding="utf-8"))
    except (ValueError, OSError) as e:
        logger.warning("prompts.json unreadable ({}); ignoring", e)
        return []
    if not isinstance(data, list):
        return []
    out, seen = [], set()
    for e in data:
        if _valid_entry(e) and e["id"] not in seen:
            seen.add(e["id"])
            out.append({"id": e["id"], "name": e["name"], "prompt": e["prompt"]})
    return out


def save_prompts(data_dir: str | Path, prompts: list[dict]) -> None:
    path = prompts_path(data_dir)
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(prompts, indent=2, ensure_ascii=False) + "\n",
                    encoding="utf-8")


def add_prompt(data_dir: str | Path, name: str, prompt: str,
               id: str = "") -> dict:
    """Add or update a prompt (by id). Returns the stored entry."""
    name = (name or "").strip()
    prompt = (prompt or "").strip()
    if not name or not prompt:
        raise ValueError("name and prompt must both be non-empty")
    pid = (id or "").strip() or slugify(name)
    prompts = load_prompts(data_dir)
    entry = {"id": pid, "name": name, "prompt": prompt}
    for i, e in enumerate(prompts):
        if e["id"] == pid:
            prompts[i] = entry
            break
    else:
        prompts.append(entry)
    save_prompts(data_dir, prompts)
    return entry


def remove_prompt(data_dir: str | Path, pid: str) -> bool:
    prompts = load_prompts(data_dir)
    kept = [e for e in prompts if e["id"] != pid]
    if len(kept) == len(prompts):
        return False
    save_prompts(data_dir, kept)
    return True
