"""PyCharter config: env or pycharter.cfg; keys = env names (e.g. PYCHARTER_DATABASE_URL, PYCHARTER_AUTH_JWT_SECRET)."""

from __future__ import annotations

import os
from configparser import ConfigParser
from pathlib import Path

_DB_ENV = "PYCHARTER_DATABASE_URL"


def _find_config_file(filename: str) -> Path | None:
    for p in [Path.cwd() / filename, Path.home() / ".pycharter" / filename]:
        if p.exists():
            return p
    # Package/project directory (so config is found when run from monorepo root or any CWD)
    try:
        import pycharter

        start = Path(pycharter.__file__).resolve().parent
        for _ in range(10):
            cand = start / filename
            if cand.exists():
                return cand
            parent = start.parent
            if parent == start:
                break
            start = parent
    except (ImportError, AttributeError):
        pass
    current = Path.cwd()
    for _ in range(5):
        if (current / "alembic.ini").exists():
            cand = current / filename
            if cand.exists():
                return cand
        current = current.parent
    return None


def _cfg(section: str, key: str) -> str | None:
    path = _find_config_file("pycharter.cfg")
    if not path:
        return None
    try:
        cfg = ConfigParser()
        cfg.read(path)
        if cfg.has_section(section):
            return cfg.get(section, key, fallback=None)
    except Exception:
        pass
    return None


def get_database_url() -> str | None:
    url = os.getenv(_DB_ENV)
    if url:
        return url
    url = _cfg("database", _DB_ENV)
    if url:
        return url
    path = _find_config_file("alembic.ini")
    if path:
        cfg = ConfigParser()
        cfg.read(path)
        url = cfg.get("alembic", "sqlalchemy.url", fallback=None)
        if url and url != "driver://user:pass@localhost/dbname":
            return url
    return None


def set_database_url(database_url: str) -> None:
    os.environ[_DB_ENV] = database_url


def get_config_variable(var_name: str, section: str = "variables") -> str | None:
    """Read from pycharter.cfg [section] by key (used for [variables], [etl])."""
    return _cfg(section, var_name)


def get_auth_initial_credentials() -> tuple[str, str] | None:
    u = os.getenv("PYCHARTER_AUTH_INITIAL_USERNAME") or _cfg(
        "auth", "PYCHARTER_AUTH_INITIAL_USERNAME"
    )
    p = os.getenv("PYCHARTER_AUTH_INITIAL_PASSWORD") or _cfg(
        "auth", "PYCHARTER_AUTH_INITIAL_PASSWORD"
    )
    if u and p:
        return (u.strip(), p.strip())
    return None


def get_auth_jwt_secret() -> str | None:
    return os.getenv("PYCHARTER_AUTH_JWT_SECRET") or _cfg(
        "auth", "PYCHARTER_AUTH_JWT_SECRET"
    )


def get_auth_service_url() -> str | None:
    url = os.getenv("PYCHARTER_AUTH_SERVICE_URL") or _cfg(
        "auth", "PYCHARTER_AUTH_SERVICE_URL"
    )
    return url.rstrip("/") if url else None


def get_auth_service_introspect_path() -> str | None:
    return os.getenv("PYCHARTER_AUTH_SERVICE_INTROSPECT_PATH") or _cfg(
        "auth", "PYCHARTER_AUTH_SERVICE_INTROSPECT_PATH"
    )


def is_auth_disabled() -> bool:
    raw = (
        os.getenv("PYCHARTER_AUTH_DISABLED")
        or _cfg("auth", "PYCHARTER_AUTH_DISABLED")
        or ""
    )
    if raw.strip().lower() in ("1", "true", "yes"):
        return True
    if get_auth_service_url():
        return False
    if get_auth_initial_credentials() and get_auth_jwt_secret():
        return False
    return True


# Named palettes use data-theme="<id>"; light/dark/system use :root + .dark only.
_VALID_UI_THEMES = (
    "light",
    "dark",
    "system",
    "ocean",
    "forest",
    "sunset",
    "high-contrast",
    "sepia",
    "violet",
    "cathay",
)
_DEFAULT_UI_APP_NAME = "PyCharter"


def get_ui_theme() -> str:
    """Return UI theme: light, dark, or system. Env overrides .cfg. Default light."""
    raw = os.getenv("PYCHARTER_UI_THEME") or _cfg("ui", "PYCHARTER_UI_THEME") or ""
    value = raw.strip().lower()
    return value if value in _VALID_UI_THEMES else "light"


def get_ui_app_name() -> str:
    """Return UI app/website name. Env overrides .cfg. Default PyCharter."""
    raw = (
        os.getenv("PYCHARTER_UI_APP_NAME") or _cfg("ui", "PYCHARTER_UI_APP_NAME") or ""
    )
    return raw.strip() or _DEFAULT_UI_APP_NAME
