import { join } from "node:path";
import { homedir } from "node:os";

/**
 * Single source of truth for all filesystem locations the server reads/writes.
 * If a path needs to change, this is the only file to edit.
 */

export const PORT = Number(process.env.PORT || 5181);

/** Claude Code encodes filesystem paths as project keys by replacing `/`
 *  with `-`. The current user's home maps to a directory under
 *  `~/.claude/projects/` with this encoding. Derive it so the app works
 *  under any username, not just `pavelracu`. */
export const USER_PROJECT_KEY = homedir().replace(/\//g, "-");

/** iCloud workspace root — the file tree, markdown previews, and chat default cwd. */
export const ICLOUD_ROOT = join(
  homedir(),
  "Library/Mobile Documents/com~apple~CloudDocs/claude-output",
);

/** Personal memory directory — MEMORY.md and project_*.md. */
export const MEMORY_DIR = join(
  homedir(),
  ".claude/projects",
  `${USER_PROJECT_KEY}/memory`,
);

/** Append-only resolution log. Created on first write. */
export const RESOLUTIONS_FILE = join(MEMORY_DIR, "resolutions.md");

/** Active postpones (snoozed dashboard items). JSON array. */
export const POSTPONES_FILE = join(MEMORY_DIR, "postpones.json");

/** Archived chat session IDs. Hide from history without deleting the .jsonl. */
export const ARCHIVED_CHATS_FILE = join(MEMORY_DIR, "archived_chats.json");

/** Custom chat names — Map<sessionId, name>. Overrides the auto-derived title. */
export const CHAT_NAMES_FILE = join(MEMORY_DIR, "chat_names.json");

/** Cached /api/now/check verdicts as a HISTORY (array per thread key).
 *  Newest entry first; capped at MAX_CHECK_HISTORY_PER_THREAD. */
export const NOW_CHECK_HISTORY_FILE = join(MEMORY_DIR, "now_check_history.json");

/** Migration source — pre-history single-entry cache. Read once, then ignored. */
export const NOW_CHECK_CACHE_FILE_LEGACY = join(MEMORY_DIR, "now_check_cache.json");

/** Linked chats per thread key — set when "Work on this" creates a chat
 *  bound to a thread. Used to render the conversation list per thread. */
export const THREAD_CHATS_FILE = join(MEMORY_DIR, "thread_chats.json");

/** Manual tasks added by Pavel from the dashboard "+ Add task" composer.
 *  Live alongside auto-scanned items in /api/now and use the same
 *  item-key convention so resolve/postpone work on them. */
export const MANUAL_TASKS_FILE = join(MEMORY_DIR, "manual_tasks.json");

/** Claude Code chat session storage — read-only for the server. */
export const CLAUDE_PROJECTS_DIR = join(homedir(), ".claude/projects");

/** Plugin install index — used by the Agent SDK loader. */
export const PLUGINS_INDEX_FILE = join(homedir(), ".claude/plugins/installed_plugins.json");

/** Set of sessionIds created by the system (scan-now, per-thread checks).
 *  Used to filter these out of the chat history list — they're agent-only
 *  background work, not user conversations. */
export const SYSTEM_SESSIONS_FILE = join(MEMORY_DIR, "system_sessions.json");

/** Scan-now run state. Persisted so a page reload mid-scan can rehydrate
 *  the "Scanning…" indicator. Server keeps the in-memory copy authoritative;
 *  this file is the recovery source after a server restart. */
export const SCAN_STATE_FILE = join(MEMORY_DIR, "scan_state.json");

/** User-editable preferences exposed through the Settings modal:
 *  active check sources + scheduler hourly cap. Loaded on each access
 *  so changes apply without a server restart. */
export const SETTINGS_FILE = join(MEMORY_DIR, "settings.json");

/** Cache of every thread the discovery agent has ever surfaced. Survives
 *  failed scan-now runs — additive, never wiped silently. Keyed by
 *  itemKey() so resolve / postpone / verdict caches all match. */
export const DISCOVERED_THREADS_FILE = join(MEMORY_DIR, "discovered_threads.json");

/** Append-only log of Pavel's thumbs-up / thumbs-down ratings on surfaced
 *  threads. Used to tune the discovery algorithm over time. */
export const THREAD_FEEDBACK_FILE = join(MEMORY_DIR, "thread_feedback.json");

/** EXPERIMENT(weighting) Phase 3 — append-only log of every action Pavel
 *  takes on a surfaced thread (resolve / postpone / work-on). Each entry
 *  includes the item's weight + signals at time of action so Phase 4
 *  calibration can compute P(action | signal) lift per coefficient. */
export const ACTION_LOG_FILE = join(MEMORY_DIR, "action_log.json");
