"""Shared runtime paths for the installed Superpitch app."""

from __future__ import annotations

import os
import shutil
from datetime import datetime
from pathlib import Path

APP_NAME = "Superpitch"
APP_SLUG = "superpitch"
APP_HOME_ENV = "SUPERPITCH_HOME"

PACKAGE_ROOT = Path(__file__).resolve().parent
ASSET_ROOT = PACKAGE_ROOT / "assets"


def app_home() -> Path:
    override = os.environ.get(APP_HOME_ENV, "").strip()
    if override:
        return Path(override).expanduser()
    return Path.home() / f".{APP_SLUG}"


APP_HOME = app_home()
DATA_DIR = APP_HOME / "data"
MODELS_DIR = APP_HOME / "models"
CACHE_DIR = APP_HOME / "cache"

TRAIN_FILE = DATA_DIR / "train.jsonl"
VAL_FILE = DATA_DIR / "val.jsonl"
FEEDBACK_FILE = DATA_DIR / "feedback.jsonl"
HISTORY_FILE = DATA_DIR / "history.jsonl"
CONFIG_FILE = APP_HOME / "config.json"

LATEST_MODEL_FILE = MODELS_DIR / "latest.pkl"
LEARNED_MODEL_FILE = MODELS_DIR / "learned.pkl"
SYNC_LOG_FILE = APP_HOME / "sync.log"

BUNDLED_TRAIN_FILE = ASSET_ROOT / "data" / "train.jsonl"
BUNDLED_VAL_FILE = ASSET_ROOT / "data" / "val.jsonl"
BUNDLED_CONTRIB_FILE = ASSET_ROOT / "data" / "contrib.jsonl"
BUNDLED_MODEL_FILE = ASSET_ROOT / "models" / "latest.pkl"

CONTRIB_FILE = DATA_DIR / "contrib.jsonl"


def ensure_app_dirs() -> None:
    for path in (APP_HOME, DATA_DIR, MODELS_DIR, CACHE_DIR):
        path.mkdir(parents=True, exist_ok=True)


def log_sync_error(context: str, exc: Exception) -> None:
    """Append a timestamped error to sync.log. Never raises."""
    try:
        ensure_app_dirs()
        with open(SYNC_LOG_FILE, "a") as f:
            f.write(f"{datetime.now().isoformat()} [{context}] {type(exc).__name__}: {exc}\n")
    except Exception:
        pass


def bootstrap_user_files() -> list[Path]:
    import json
    from superpitch import __version__

    ensure_app_dirs()

    bootstrapped_version = ""
    user_retrained = False
    try:
        if CONFIG_FILE.exists():
            cfg = json.loads(CONFIG_FILE.read_text())
            bootstrapped_version = cfg.get("bootstrapped_version", "")
            user_retrained = FEEDBACK_FILE.exists() and FEEDBACK_FILE.stat().st_size > 0
    except Exception:
        pass

    is_upgrade = bootstrapped_version != __version__

    copied: list[Path] = []
    for src, dst in (
        (BUNDLED_TRAIN_FILE, TRAIN_FILE),
        (BUNDLED_VAL_FILE, VAL_FILE),
        (BUNDLED_CONTRIB_FILE, CONTRIB_FILE),
        (BUNDLED_MODEL_FILE, LATEST_MODEL_FILE),
    ):
        if not src.exists():
            continue
        if dst.exists() and not is_upgrade:
            continue  # first-run already done, nothing new
        shutil.copy2(src, dst)
        copied.append(dst)

    try:
        if CONFIG_FILE.exists():
            cfg = json.loads(CONFIG_FILE.read_text())
        else:
            cfg = {}
        if cfg.get("bootstrapped_version") != __version__:
            cfg["bootstrapped_version"] = __version__
            if is_upgrade and user_retrained:
                cfg["retrain_after_upgrade"] = True
            CONFIG_FILE.write_text(json.dumps(cfg, indent=2))
    except Exception:
        pass

    return copied
