"""Управление API-ключом локального прокси и параметрами подключения.

Ключ хранится в connection.json рядом с accounts.json. При первом старте
(если файла нет и PROXY_API_KEY в env пуст) — генерируется автоматически.
TUI может перегенерировать через POST /api/connection/regenerate-key.
"""
from __future__ import annotations

import json
import os
import secrets
import threading
from pathlib import Path
from typing import Optional


_LOCK = threading.Lock()
_CACHED_PATH: Optional[Path] = None
_CACHED_KEY: Optional[str] = None


def _file_path() -> Path:
    """connection.json лежит рядом с accounts.json (cwd прокси)."""
    global _CACHED_PATH
    if _CACHED_PATH is None:
        _CACHED_PATH = Path(os.environ.get("CONNECTION_FILE", "connection.json")).resolve()
    return _CACHED_PATH


def _generate_key() -> str:
    """sk-vk- + 40 hex символов. Похоже на OpenAI-ключ, чтобы IDE их пропускали валидацию."""
    return "sk-vk-" + secrets.token_hex(20)


def _load_from_disk() -> Optional[str]:
    p = _file_path()
    if not p.exists():
        return None
    try:
        data = json.loads(p.read_text(encoding="utf-8"))
        key = (data.get("api_key") or "").strip()
        return key or None
    except Exception:
        return None


def _save_to_disk(key: str) -> None:
    p = _file_path()
    p.parent.mkdir(parents=True, exist_ok=True)
    payload = {"api_key": key, "version": 1}
    p.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
    # Минимальная защита: 0600 на posix
    try:
        if os.name != "nt":
            os.chmod(p, 0o600)
    except Exception:
        pass


def get_or_create_key(env_key: str = "") -> str:
    """Возвращает текущий API-ключ.

    Приоритет:
      1. env (PROXY_API_KEY) — если задан, не трогаем файл, используем его
      2. connection.json — если есть и валидно
      3. иначе — генерим, сохраняем, возвращаем
    """
    global _CACHED_KEY
    with _LOCK:
        if env_key:
            _CACHED_KEY = env_key
            return env_key
        if _CACHED_KEY:
            return _CACHED_KEY
        from_disk = _load_from_disk()
        if from_disk:
            _CACHED_KEY = from_disk
            return from_disk
        new_key = _generate_key()
        _save_to_disk(new_key)
        _CACHED_KEY = new_key
        return new_key


def regenerate_key() -> str:
    """Создаёт и сохраняет новый ключ. Возвращает его.

    ВАЖНО: если PROXY_API_KEY задан в env — операция запрещена,
    нужно убрать переменную и перезапустить, иначе env перебьёт файл.
    """
    global _CACHED_KEY
    with _LOCK:
        if os.environ.get("PROXY_API_KEY", "").strip():
            raise RuntimeError(
                "API-ключ задан через переменную окружения PROXY_API_KEY. "
                "Удали её и перезапусти прокси, чтобы управлять ключом из TUI."
            )
        new_key = _generate_key()
        _save_to_disk(new_key)
        _CACHED_KEY = new_key
        return new_key


def current_key() -> str:
    """Только чтение — для отображения в TUI."""
    return _CACHED_KEY or _load_from_disk() or ""


def is_env_locked() -> bool:
    """True если ключ задан через env — тогда регенерация заблокирована."""
    return bool(os.environ.get("PROXY_API_KEY", "").strip())
