from __future__ import annotations

from pathlib import Path


def get_config_dir() -> Path:
    """Return the base HUD config directory in the user's home.

    Uses ~/.hud across platforms for consistency with existing registry data.
    """
    return Path.home() / ".hud"


def get_user_env_path() -> Path:
    """Return the path to the persistent user-level env file (~/.hud/.env)."""
    return get_config_dir() / ".env"


def ensure_config_dir() -> Path:
    """Ensure the HUD config directory exists and return it."""
    config_dir = get_config_dir()
    config_dir.mkdir(parents=True, exist_ok=True)
    return config_dir


def parse_key_value(item: str) -> tuple[str, str] | None:
    """Split one ``KEY=VALUE`` string into ``(key, value)``.

    Returns ``None`` for malformed input (no ``=`` or empty key); each caller
    decides whether that's a warning, an error, or a skip.
    """
    key, sep, value = item.partition("=")
    key = key.strip()
    if not sep or not key:
        return None
    return key, value.strip()


def parse_env_file(contents: str) -> dict[str, str]:
    """Parse simple KEY=VALUE lines into a dict.

    - Ignores blank lines and lines starting with '#'.
    - Strips inline comments (# and everything after) from unquoted values.
    - Respects single and double quoted values (comments inside quotes are preserved).
    - Does not perform variable substitution.
    """
    data: dict[str, str] = {}
    for raw_line in contents.splitlines():
        line = raw_line.strip()
        if not line or line.startswith("#"):
            continue
        if "=" not in line:
            continue
        key, value = line.split("=", 1)
        key = key.strip()
        value = value.strip()

        # Handle quoted values - preserve everything inside quotes
        if value and value[0] in ('"', "'"):
            quote_char = value[0]
            # Find the closing quote
            end_quote = value.find(quote_char, 1)
            # Extract value without quotes (or strip opening quote if no closing quote)
            value = value[1:end_quote] if end_quote != -1 else value[1:]
        else:
            # Unquoted value - strip inline comments
            # Find # that's not escaped and treat as comment start
            comment_idx = value.find("#")
            if comment_idx != -1:
                value = value[:comment_idx].rstrip()

        if key:
            data[key] = value
    return data


def render_env_file(env: dict[str, str]) -> str:
    """Render a dict of env values to KEY=VALUE lines with a header."""
    header = [
        "# HUD CLI persistent environment file",
        "# Keys set via `hud set KEY=VALUE`",
        "# This file is read after process env and project .env",
        "# so project overrides take precedence over these defaults.",
        "",
    ]
    body = [f"{key}={env[key]}" for key in sorted(env.keys())]
    return "\n".join([*header, *body, ""])


def load_env_file(path: Path | None = None) -> dict[str, str]:
    """Load env assignments from the given path (defaults to ~/.hud/.env)."""
    env_path = path or get_user_env_path()
    if not env_path.exists():
        return {}
    try:
        contents = env_path.read_text(encoding="utf-8")
    except Exception:
        return {}
    return parse_env_file(contents)


def save_env_file(env: dict[str, str], path: Path | None = None) -> Path:
    """Write env assignments to the given path and return the path."""
    ensure_config_dir()
    env_path = path or get_user_env_path()
    rendered = render_env_file(env)
    env_path.write_text(rendered, encoding="utf-8")
    return env_path


def set_env_values(values: dict[str, str]) -> Path:
    """Persist provided KEY=VALUE pairs into ~/.hud/.env and return the path."""
    current = load_env_file()
    current.update(values)
    return save_env_file(current)
