from __future__ import annotations

import os
from pathlib import Path


def load_env_file(env_path: Path) -> bool:
    """Load simple KEY=VALUE pairs from an env file if present.

    Existing process environment variables win over values from .env.
    """

    if not env_path.exists() or not env_path.is_file():
        return False

    for raw_line in env_path.read_text(encoding="utf-8").splitlines():
        line = raw_line.strip()
        if not line or line.startswith("#") or "=" not in line:
            continue
        key, value = line.split("=", 1)
        key = key.strip()
        value = value.strip()
        if not key:
            continue
        if value and len(value) >= 2 and value[0] == value[-1] and value[0] in {"'", '"'}:
            value = value[1:-1]
        os.environ.setdefault(key, value)

    return True


def runtime_env_path() -> Path:
    from eightmem.core.paths import runtime_home

    return runtime_home() / ".env"


def load_project_env(cwd: Path | None = None) -> Path | None:
    """Load environment from local project .env and runtime .env.

    Precedence is: shell environment > current project .env > 8mem runtime .env.
    That keeps developer/project overrides authoritative while making installed
    users work from `~/.8mem/.env` without manual exports.
    """

    loaded: Path | None = None
    base = cwd or Path.cwd()
    project_env = base / ".env"
    if load_env_file(project_env):
        loaded = project_env

    runtime_env = runtime_env_path()
    if load_env_file(runtime_env) and loaded is None:
        loaded = runtime_env

    return loaded


def render_env_value(value: str) -> str:
    escaped = value.replace("\\", "\\\\").replace('"', '\\"')
    return f'"{escaped}"'


def write_runtime_env(values: dict[str, str]) -> Path:
    """Merge values into the runtime .env file without printing secrets."""

    path = runtime_env_path()
    path.parent.mkdir(parents=True, exist_ok=True)
    existing: dict[str, str] = {}
    if path.exists():
        for raw_line in path.read_text(encoding="utf-8").splitlines():
            line = raw_line.strip()
            if not line or line.startswith("#") or "=" not in line:
                continue
            key, value = line.split("=", 1)
            key = key.strip()
            value = value.strip()
            if value and len(value) >= 2 and value[0] == value[-1] and value[0] in {"'", '"'}:
                value = value[1:-1]
            if key:
                existing[key] = value

    existing.update({key: value for key, value in values.items() if value != ""})
    lines = [
        "# 8mem local runtime configuration",
        "# Generated by `8mem setup`. Shell-exported env vars still override these values.",
    ]
    for key in sorted(existing):
        lines.append(f"{key}={render_env_value(existing[key])}")
    path.write_text("\n".join(lines) + "\n", encoding="utf-8")
    return path


def remove_runtime_env_keys(keys: set[str]) -> Path:
    """Remove keys from the runtime .env file without printing secrets."""

    path = runtime_env_path()
    if not path.exists():
        path.parent.mkdir(parents=True, exist_ok=True)
        path.write_text(
            "\n".join(
                [
                    "# 8mem local runtime configuration",
                    "# Generated by `8mem setup`. Shell-exported env vars still override these values.",
                ]
            )
            + "\n",
            encoding="utf-8",
        )
        return path

    kept_lines: list[str] = []
    for raw_line in path.read_text(encoding="utf-8").splitlines():
        line = raw_line.strip()
        if not line or line.startswith("#") or "=" not in line:
            kept_lines.append(raw_line)
            continue
        key, _ = line.split("=", 1)
        if key.strip() not in keys:
            kept_lines.append(raw_line)
    path.write_text("\n".join(kept_lines).rstrip() + "\n", encoding="utf-8")
    return path
