"""Organization-Settings-Helper.

KV-Store pro Organisation. Aktuell genutzt fuer output_language ('de'|'en').
Spaeter erweiterbar (Default-Modell, Telegram-Toggle, Theme, ...).

Cache: TTL 60s in-memory pro (tenant_id, key). Wird bei set_org_setting()
invalidiert.
"""
import logging
import time
from typing import Optional

import aiosqlite

logger = logging.getLogger("osint.org_settings")

_CACHE: dict[tuple[int, str], tuple[float, Optional[str]]] = {}
_TTL_SECONDS = 60.0


def _cache_get(tenant_id: int, key: str) -> tuple[bool, Optional[str]]:
    """(hit, value). hit=True heisst Cache traf; value kann auch None sein."""
    entry = _CACHE.get((tenant_id, key))
    if entry is None:
        return (False, None)
    expires_at, value = entry
    if time.monotonic() > expires_at:
        _CACHE.pop((tenant_id, key), None)
        return (False, None)
    return (True, value)


def _cache_put(tenant_id: int, key: str, value: Optional[str]) -> None:
    _CACHE[(tenant_id, key)] = (time.monotonic() + _TTL_SECONDS, value)


def _cache_invalidate(tenant_id: int, key: str) -> None:
    _CACHE.pop((tenant_id, key), None)


async def get_org_setting(
    db: aiosqlite.Connection,
    tenant_id: int,
    key: str,
    default: Optional[str] = None,
) -> Optional[str]:
    """Liest ein Org-Setting. Fallback auf default."""
    if tenant_id is None:
        return default
    hit, cached = _cache_get(tenant_id, key)
    if hit:
        return cached if cached is not None else default
    cursor = await db.execute(
        "SELECT value FROM organization_settings WHERE organization_id = ? AND key = ?",
        (tenant_id, key),
    )
    row = await cursor.fetchone()
    value = row["value"] if row else None
    _cache_put(tenant_id, key, value)
    return value if value is not None else default


async def set_org_setting(
    db: aiosqlite.Connection,
    tenant_id: int,
    key: str,
    value: str,
) -> None:
    """Setzt ein Org-Setting (upsert)."""
    await db.execute(
        """INSERT INTO organization_settings (organization_id, key, value, updated_at)
           VALUES (?, ?, ?, CURRENT_TIMESTAMP)
           ON CONFLICT(organization_id, key) DO UPDATE SET
             value = excluded.value,
             updated_at = CURRENT_TIMESTAMP""",
        (tenant_id, key, value),
    )
    await db.commit()
    _cache_invalidate(tenant_id, key)
    logger.info("Org %s Setting %s='%s' gespeichert", tenant_id, key, value)


# Bekannte Sprachen + Anzeigenamen fuer Prompts
LANGUAGE_DISPLAY_NAMES = {
    "de": "Deutsch",
    "en": "English",
}


async def get_org_language(
    db: aiosqlite.Connection,
    tenant_id: int,
) -> str:
    """Liefert ISO-2-Sprachcode der Org (default 'de')."""
    value = await get_org_setting(db, tenant_id, "output_language", default="de")
    if value not in LANGUAGE_DISPLAY_NAMES:
        logger.warning("Unbekannte output_language '%s' fuer Org %s -- fallback 'de'", value, tenant_id)
        return "de"
    return value


def language_display(lang_iso: str) -> str:
    """ISO-Code -> Anzeigename fuer Prompts ('de' -> 'Deutsch')."""
    return LANGUAGE_DISPLAY_NAMES.get(lang_iso, lang_iso)
