from __future__ import annotations

import os
from pathlib import Path

HOME = Path.home()
CLOUD = bool(os.environ.get("SCOUT_CLOUD"))            # set in fly.toml: repos are disposable mirrors


def _data_dir() -> Path:
    """Where this computer keeps its ideas, logs and scratch copies.

    New installs use ~/.feature-scout. The first machine this ever ran on used a macOS-shaped
    path, so that one is kept if it is already there — nobody should lose their ideas to a
    tidier default.
    """
    if os.environ.get("SCOUT_DATA_DIR"):
        return Path(os.environ["SCOUT_DATA_DIR"])
    legacy = HOME / "Library" / "FeatureScout"
    return legacy if legacy.exists() else HOME / ".feature-scout"


DATA_DIR = _data_dir()
DB_PATH = DATA_DIR / "scout.sqlite"
LOG_DIR = DATA_DIR / "logs"
WORKTREE_DIR = DATA_DIR / "worktrees"
LOCK_PATH = DATA_DIR / "scout.lock"
# Extra settings this computer keeps (an API key, which Claude to use). Nothing here ships with
# the package: a machine that has no such file simply has no extra settings.
ENV_FILE = Path(os.environ.get("SCOUT_ENV_FILE") or DATA_DIR / "settings.env")

IDEAS_PER_PLATFORM = int(os.environ.get("SCOUT_IDEAS_PER_PLATFORM", "4"))  # ideas per platform per scan
SCAN_TIMEOUT_S = 25 * 60
BUILD_TIMEOUT_S = 150 * 60
# A nudge resumes a session that stopped early and only has to finish up and write the report.
# Four builds on 2026-09-07 each sat for the full 2.5 h inside a nudge, waiting on a background
# browser suite that could never finish, so a nudge gets far less rope than a first attempt.
NUDGE_TIMEOUT_S = 20 * 60
TEST_TIMEOUT_S = 20 * 60


# Ideas recorded before the merge used these keys; the store maps them onto the merged platform.
LEGACY_PLATFORMS: dict[str, tuple[str, str]] = {}
VENUES = ("polymarket", "kalshi", "both")

IDEA_STATUSES = (
    "proposed", "approved", "rejected", "building", "built", "blocked", "failed", "shipped",
)


def load_env(path: Path | None = None) -> dict[str, str]:
    """Settings: the dotenv file (Mac) overlaid with real environment variables (Fly secrets)."""
    path = path or ENV_FILE
    out: dict[str, str] = {}
    for raw in (path.read_text().splitlines() if path.exists() else []):
        line = raw.strip()
        if not line or line.startswith("#"):
            continue
        if line.startswith("export "):
            line = line[len("export "):]
        if "=" not in line:
            continue
        k, v = line.split("=", 1)
        v = v.strip()
        if len(v) >= 2 and v[0] == v[-1] and v[0] in "\"'":
            v = v[1:-1]
        out[k.strip()] = v
    for k, v in os.environ.items():
        if k.startswith(("SCOUT_", "LIBRARYMODE_", "FLY_")):
            out[k] = v
    return out


def ensure_dirs() -> None:
    for d in (DATA_DIR, LOG_DIR, WORKTREE_DIR):
        d.mkdir(parents=True, exist_ok=True)


# ---- settings a person chooses at setup and keeps on this computer (settings.env) ----

DEFAULT_CATEGORIES_DOC = "feature, improvement, fix, data, report, automation"

MODEL_CHOICES = {
    # what a person says -> what the claude command is asked for ('' = its own default)
    "default": "", "best": "opus", "balanced": "sonnet", "fast": "haiku",
}


def save_setting(name: str, value: str, path: Path | None = None) -> Path:
    """Write one NAME=value line into this computer's settings file (replacing any old one).
    An empty value removes the line. Never used for anything that ships with the package."""
    path = path or ENV_FILE
    path.parent.mkdir(parents=True, exist_ok=True)
    lines = [ln for ln in (path.read_text().splitlines() if path.exists() else [])
             if not ln.startswith(f"{name}=")]
    if value:
        lines.append(f"{name}={value}")
    path.write_text("\n".join(lines) + ("\n" if lines else ""))
    os.chmod(path, 0o600)
    return path


def scan_model() -> str | None:
    """Which Claude does the research, or None for the person's own default."""
    return load_env().get("SCOUT_SCAN_MODEL") or None


def build_model() -> str | None:
    return load_env().get("SCOUT_BUILD_MODEL") or None


def scan_time() -> tuple[int, int]:
    """When the daily look for ideas happens (hour, minute), local time."""
    env = load_env()
    try:
        return int(env.get("SCOUT_SCAN_HOUR", 8)), int(env.get("SCOUT_SCAN_MINUTE", 15))
    except ValueError:
        return 8, 15
