from __future__ import annotations

import os
from pathlib import Path
from typing import Iterable

ROOT = Path(__file__).resolve().parent.parent
PROJECT_ENV_PATH = ROOT / ".env"
HOME_ENV_PATH = Path.home() / ".env"

LLM_ENV_KEYS = [
    "OPENAI_API_KEY",
    "ANTHROPIC_API_KEY",
    "GOOGLE_API_KEY",
    "GEMINI_API_KEY",
    "OPENROUTER_API_KEY",
]
OPTIONAL_ENV_KEYS = ["OPENROUTER_BASE_URL"]

_ENV_BOOTSTRAPPED = False


def _strip_quotes(value: str) -> str:
    raw = value.strip()
    if len(raw) >= 2 and raw[0] == raw[-1] and raw[0] in {"'", '"'}:
        return raw[1:-1]
    return raw


def _parse_env_text(text: str) -> dict[str, str]:
    parsed: dict[str, str] = {}
    for raw_line in text.splitlines():
        line = raw_line.strip()
        if not line or line.startswith("#"):
            continue
        if line.startswith("export "):
            line = line[7:].strip()
        if "=" not in line:
            continue
        key, value = line.split("=", 1)
        key = key.strip()
        if not key:
            continue
        parsed[key] = _strip_quotes(value)
    return parsed


def _load_env_file(path: Path, *, override: bool) -> None:
    if not path.exists():
        return
    try:
        payload = _parse_env_text(path.read_text(encoding="utf-8"))
    except Exception:
        return
    for key, value in payload.items():
        if override or not os.getenv(key):
            os.environ[key] = value


def load_env_candidates() -> list[Path]:
    global _ENV_BOOTSTRAPPED
    if _ENV_BOOTSTRAPPED:
        return [path for path in (PROJECT_ENV_PATH, HOME_ENV_PATH) if path.exists()]

    # precedence: home < project
    _load_env_file(HOME_ENV_PATH, override=False)
    _load_env_file(PROJECT_ENV_PATH, override=True)
    _ENV_BOOTSTRAPPED = True
    return [path for path in (PROJECT_ENV_PATH, HOME_ENV_PATH) if path.exists()]


def _read_env_map(path: Path) -> dict[str, str]:
    if not path.exists():
        return {}
    try:
        return _parse_env_text(path.read_text(encoding="utf-8"))
    except Exception:
        return {}


def _write_env_map(path: Path, env_map: dict[str, str]) -> None:
    lines = [f"{key}={value}" for key, value in env_map.items()]
    content = "\n".join(lines).strip()
    if content:
        content += "\n"
    path.write_text(content, encoding="utf-8")


def _target_env_path(target: str) -> Path:
    normalized = str(target or "project").strip().lower()
    if normalized == "home":
        return HOME_ENV_PATH
    return PROJECT_ENV_PATH


def save_env_values(values: dict[str, str], *, target: str = "project") -> dict[str, object]:
    env_path = _target_env_path(target)
    env_path.parent.mkdir(parents=True, exist_ok=True)

    current = _read_env_map(env_path)
    updated_keys: list[str] = []
    for key, value in values.items():
        if value is None:
            continue
        cleaned = str(value).strip()
        if not cleaned:
            continue
        current[key] = cleaned
        os.environ[key] = cleaned
        updated_keys.append(key)
    _write_env_map(env_path, current)

    return {
        "target": "home" if env_path == HOME_ENV_PATH else "project",
        "path": str(env_path),
        "updated_keys": updated_keys,
    }


def llm_key_status() -> dict[str, bool]:
    load_env_candidates()
    openai = bool(os.getenv("OPENAI_API_KEY", "").strip())
    anthropic = bool(os.getenv("ANTHROPIC_API_KEY", "").strip())
    google = bool(os.getenv("GOOGLE_API_KEY", "").strip() or os.getenv("GEMINI_API_KEY", "").strip())
    openrouter = bool(os.getenv("OPENROUTER_API_KEY", "").strip())
    return {
        "openai": openai,
        "anthropic": anthropic,
        "google": google,
        "openrouter": openrouter,
        "any": any([openai, anthropic, google, openrouter]),
    }


def missing_llm_env_keys() -> list[str]:
    load_env_candidates()
    missing: list[str] = []
    if not os.getenv("OPENAI_API_KEY", "").strip():
        missing.append("OPENAI_API_KEY")
    if not os.getenv("ANTHROPIC_API_KEY", "").strip():
        missing.append("ANTHROPIC_API_KEY")
    if not (os.getenv("GOOGLE_API_KEY", "").strip() or os.getenv("GEMINI_API_KEY", "").strip()):
        missing.append("GOOGLE_API_KEY(or GEMINI_API_KEY)")
    if not os.getenv("OPENROUTER_API_KEY", "").strip():
        missing.append("OPENROUTER_API_KEY")
    return missing


def supported_env_locations() -> dict[str, str]:
    return {
        "project": str(PROJECT_ENV_PATH),
        "home": str(HOME_ENV_PATH),
    }


def as_masked_key(value: str) -> str:
    raw = str(value or "").strip()
    if len(raw) <= 8:
        return "*" * len(raw)
    return f"{raw[:4]}...{raw[-4:]}"


def read_current_key_values(keys: Iterable[str]) -> dict[str, str]:
    load_env_candidates()
    out: dict[str, str] = {}
    for key in keys:
        out[key] = os.getenv(key, "")
    return out
