"""Константная матрица уровней AI (`min`/`medium`/`max`) — ADR-004.

Единственный источник моделей/квантов/параметров генерации/требований
железа — `docs/architecture/adr/004-ai-tier-matrix.md`; этот модуль переводит
матрицу ADR в структуры, которыми пользуются `services/ai_levels.py` (детект
доступности уровня) и `services/instance_settings.py::load_effective_config`
(подмена `transcriber`/`summarizer` эффективной конфигурации для `medium`/`max` —
`min` продолжает использовать дефолты `plugins.yaml`/правки администратора).

Пути моделей на дисковых томах (`model_files`, `options.download_root`,
`options.tokenizer_path`) — контракт с инсталлятором
(`deploy/llm/download-model.sh` и его аналог для faster-whisper): скрипты
обязаны скачивать модели именно по этим путям, иначе детект доступности
уровня будет ошибочно считать модель нескачанной.
"""

from pydantic import BaseModel

from core.plugins.config import AiLevel, SummarizerConfig, TranscriberConfig

WHISPER_MODELS_ROOT = "/models/whisper"
"""Корень тома с моделями faster-whisper; каждый уровень хранит свою модель в
одноимённом (модели, не уровню) подкаталоге — общий volume `whisper-cache`."""

QWEN_MODELS_ROOT = "/models/qwen"
"""Корень тома с GGUF-квантами и токенизаторами Qwen — общий volume `llm-models`."""

_LLM_BASE_URL_CPU = "http://llm:8080/v1"
"""CPU-сервер llama.cpp (compose-сервис `llm`) — уровни `min`/`medium`."""

_LLM_BASE_URL_GPU = "http://llm-gpu:8080/v1"
"""GPU-сервер llama.cpp (compose-сервис `llm-gpu`, образ `...:server-cuda`)
— уровень `max` (`requires_gpu=True`, GPU обязателен)."""


class TierSpec(BaseModel):
    """Полная конфигурация одного уровня AI: плагины, требования железа, модели."""

    transcriber: TranscriberConfig
    summarizer: SummarizerConfig
    min_ram_mb: int
    requires_gpu: bool
    min_vram_mb: int | None = None
    model_files: list[str]


TIERS: dict[AiLevel, TierSpec] = {
    "min": TierSpec(
        transcriber=TranscriberConfig(
            provider="faster_whisper_cpu",
            model="small",
            options={"download_root": f"{WHISPER_MODELS_ROOT}/small"},
        ),
        summarizer=SummarizerConfig(
            provider="qwen_local",
            model="qwen3.5-4b-instruct-q4_k_m",
            chunk_minutes=20,
            options={
                "base_url": _LLM_BASE_URL_CPU,
                "tokenizer_path": f"{QWEN_MODELS_ROOT}/qwen3.5-4b-instruct.tokenizer.json",
                "temperature": 0.2,
                "max_tokens_map": 1024,
                "max_tokens_reduce": 1536,
            },
        ),
        min_ram_mb=16 * 1024,
        requires_gpu=False,
        min_vram_mb=None,
        model_files=[
            f"{WHISPER_MODELS_ROOT}/small",
            f"{QWEN_MODELS_ROOT}/qwen3.5-4b-instruct-q4_k_m.gguf",
            f"{QWEN_MODELS_ROOT}/qwen3.5-4b-instruct.tokenizer.json",
        ],
    ),
    "medium": TierSpec(
        transcriber=TranscriberConfig(
            provider="faster_whisper_cpu",
            model="medium",
            options={"download_root": f"{WHISPER_MODELS_ROOT}/medium"},
        ),
        summarizer=SummarizerConfig(
            provider="qwen_local",
            model="qwen3.5-9b-instruct-q4_k_m",
            chunk_minutes=20,
            options={
                "base_url": _LLM_BASE_URL_CPU,
                "tokenizer_path": f"{QWEN_MODELS_ROOT}/qwen3.5-9b-instruct.tokenizer.json",
                "temperature": 0.2,
                "max_tokens_map": 1024,
                "max_tokens_reduce": 2048,
            },
        ),
        min_ram_mb=32 * 1024,
        # GPU опционален на этом уровне (ADR-004: полный offload от ~8 ГБ
        # VRAM ускоряет, но не требуется) — константная матрица держит
        # безопасный CPU-вариант `faster_whisper_cpu`/CPU llama.cpp;
        # GPU-ускорение уровня `medium` — ручная настройка администратора
        # поверх этой матрицы (вне детекта доступности).
        requires_gpu=False,
        min_vram_mb=8 * 1024,
        model_files=[
            f"{WHISPER_MODELS_ROOT}/medium",
            f"{QWEN_MODELS_ROOT}/qwen3.5-9b-instruct-q4_k_m.gguf",
            f"{QWEN_MODELS_ROOT}/qwen3.5-9b-instruct.tokenizer.json",
        ],
    ),
    "max": TierSpec(
        transcriber=TranscriberConfig(
            provider="faster_whisper_gpu",
            model="large-v3",
            options={
                "download_root": f"{WHISPER_MODELS_ROOT}/large-v3",
                "compute_type": "float16",
            },
        ),
        summarizer=SummarizerConfig(
            provider="qwen_local",
            model="qwen3.5-35b-a3b-instruct-q4_k_m",
            chunk_minutes=20,
            options={
                "base_url": _LLM_BASE_URL_GPU,
                "tokenizer_path": f"{QWEN_MODELS_ROOT}/qwen3.5-35b-a3b-instruct.tokenizer.json",
                "temperature": 0.2,
                "max_tokens_map": 1536,
                "max_tokens_reduce": 2560,
            },
        ),
        min_ram_mb=64 * 1024,
        requires_gpu=True,
        min_vram_mb=16 * 1024,
        model_files=[
            f"{WHISPER_MODELS_ROOT}/large-v3",
            f"{QWEN_MODELS_ROOT}/qwen3.5-35b-a3b-instruct-q4_k_m.gguf",
            f"{QWEN_MODELS_ROOT}/qwen3.5-35b-a3b-instruct.tokenizer.json",
        ],
    ),
}
